
On Sun, Jul 3, 2011 at 10:02 PM, Jason Dagit
Hello,
I'm trying to get some GUI code working on OSX and numerous forums around the internet keep reiterating that on OSX to correctly handle GUI events you need to use the original thread allocated to your process to check for events and to call the Cocoa framework functionality. Specifically, using a secondary thread (even a bound thread) is not sufficient with the Cocoa framework.
I looked at the threading documentation in Control.Concurrent for GHC and it's not clear to me if this is even possible with GHC without restricting to the non-threaded RTS. This means that using the GUI library from GHCI is not an option and using multiple OS threads in the final application is also not possible. This means that some FFI libraries will be unusable.
My main question is, is there a way around this so that I could, for example, use the library from GHCI?
My second question is, if there is no current workaround then how can we remedy this situation? It seems like there could be an api function like: runOnOriginalThread :: IO a -> IO a
I've got some code in https://github.com/dpp/LispHaskellIPad that uses an FFI call into ObjC code that invokes a function on the UI thread. In Haskell: runOnMain :: IO () -> IO () runOnMain todo = do func <- funky dispatchFunc func where funky = mkStrCB $ \v -> do todo And in ObjC: void dispatchFunc(void (*fp)(void*)) { // dispatch_async_f(dispatch_get_main_queue(), NULL, fp); id runner = [[PerformOMatic alloc] init]; [runner setFunc:fp]; [runner run]; } And: #import "PerformOMatic.h" @implementation PerformOMatic - (void)run { [self performSelectorOnMainThread:@selector(reallyDoIt:) withObject:self waitUntilDone:TRUE]; } - (void)reallyDoIt:(id)ignore { whatToDo(NULL); releaseMe(whatToDo); [self dealloc]; } - (void)setFunc:(void *)func { whatToDo = func; } @end Pardon the extremely ugly code, I'm a Haskell newbie and my ObjC skills are 20 years old.
This function would be similar to runInBoundThread except it would be guaranteed to run on the original thread allocated to the ghc/ghci process. I believe the above primitive would be sufficient.
I'll worry about filing a bug or making a libraries proposal after I have a better understanding of what must be done.
Thanks, Jason
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- Lift, the simply functional web framework http://liftweb.net Simply Lift http://simply.liftweb.net Follow me: http://twitter.com/dpp Blog: http://goodstuff.im