
On 20 July 2005 16:23, John Goerzen wrote:
On Wed, Jul 20, 2005 at 04:10:38PM +0100, Simon Marlow wrote:
On 20 July 2005 14:35, John Goerzen wrote:
These systems generally have some sort of an opaque main loop, implemented in C. This loop would usually never return, or perhaps only return once the UI is destroyed.
Is the library thread-safe or not? I mean OS-thread safe. If it is, then you're home and dry: just compile your program with GHC's -threaded option, and any foreign calls that need to run concurrently with Haskell threads must be declared "safe" (which is the default in fact, so instead I should really advise you to mark all calls that don't need to run concurrently as "unsafe", because that's good for performance).
That's half of the question. The other half is: what is the canonical way of handling this mainloop that doesn't return from Haskell? Do we just treat it that way in Haskell as well, or would some people forkIO it?
You could forkIO the main loop if you want; it shouldn't make any difference, except that GHC terminates the program when the main thread completes, so it's more convenient to have the main loop run in the main thread, so that the program terminates when the main loop returns.
Does any part of your answer vary depending on whether the Haskell threads in question are forkIO threads or forkOS threads? I imagine that it might.
No, and I don't think you need forkOS here. This paper might help shed some light: http://www.haskell.org/~simonmar/papers/conc-ffi.pdf
If the library isn't thread-safe, then you're in the same boat as Gtk and wxHaskell (I believe) where there are known problems with having a multithreaded Haskell GUI app. You can only have one OS thread (and hence only one Haskell thread) doing GUI operations, and that is the
What about multiple forkIO threads?
You should think of Haskell as having a one-to-one mapping between OS threads and Haskell threads. The only difference between forkIO and forkOS is that a forkIO thread can migrate from one OS thread to another, whereas a forkOS thread always runs on the same OS thread. This difference is therefore only visible when you make FFI calls, because there's no way in Haskell to tell what OS thread you're running on. In practice, GHC uses an optimised implementation to take advantage of the fact that forkIO threads are allowed to migrate from one OS thread to another, and it runs all the forkIO threads using a small pool of worker OS threads. The design of forkIO/forkOS and the FFI is carefully crafted to accommodate both GHC's optimised implementation and simpler implementations such as one-to-one or a giant lock.
thread in the main loop. You have to somehow set up a communication between your other Haskell threads and the thread running the main loop - perhaps you can send requests of type (IO ()) down a channel to the main loop thread which wakes up occasionally to run them, for example.
I imagine there could be exceptions to this.. For instance, perhaps a given operation needs to do 5 things, perhaps simultaneously, before displaying a result. It could, perhaps, fire off five threads and just not display a result until all five have terminated, yes?
Sure, but it's just a matter of converting direct GUI calls into RPCs to the GUI thread, using some appropriate RPC mechanism. Cheers, Simon