On Sun, Jul 3, 2011 at 10:02 PM, Jason Dagit <dagitj@gmail.com> wrote:
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