[Haskell-cafe] How to ensure code executes in the context of a specific OS thread?
David Pollak
feeder.of.the.bears at gmail.com
Mon Jul 4 16:09:09 CEST 2011
On Sun, Jul 3, 2011 at 10:02 PM, Jason Dagit <dagitj at 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 at 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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/haskell-cafe/attachments/20110704/f341dc3b/attachment.htm>
More information about the Haskell-Cafe
mailing list