[Haskell-cafe] gtk2hs and runghc

Duncan Coutts duncan.coutts at worc.ox.ac.uk
Wed Sep 23 16:12:25 EDT 2009


On Wed, 2009-09-23 at 20:24 +0200, Günther Schmidt wrote:

> >> No, but you can unsafeInitGUIForThreadedRTS.
> >
> > If you observe the foot-shooting restrictions (of which the easiest is
> > to not use forkIO).
> >

> And exactly herein lies the problem :)
>
> I've seen your response to the recent post about gui state, in which you  
> mention your own prefered solution to the problem, ie. that you "post"  
> your state to a channel which is read in a thread.
> 
> I'm doing the same thing, but I'm also "calling" gui code from within that  
> thread.

> I figured since the thread itself isn't a separate OS thread it  
> shouldn't be a problem.

Stop! You are confused about the relationship between Haskell threads
and OS threads.

By default you have _no_ control over which OS thread your Haskell
threads run on. Using forkIO provides no promises at all about that.
Using forkOS provides the opposite guarantee to the one you want. There
is no API to launch a Haskell thread and guarantee that runs on the same
OS thread as some existing Haskell thread.

(One way is to use the single-threaded rts)


The documentation for unsafeInitGUIForThreadedRTS states:

        If you want to use Gtk2Hs and the threaded RTS then it is your
        obligation to ensure that all calls to Gtk+ happen on a single
        OS thread. If you want to make calls to Gtk2Hs functions from a
        Haskell thread other than the one that calls this functions and
        mainGUI then you will have to 'post' your GUI actions to the
        main GUI thread. You can do this using postGUISync or
        postGUIAsync.

The postGUI actions do some magic so that your IO actions are run on the
same OS thread as the GUI is running on.

> It seems to work once the app is compiled, but running the code in either  
> ghci or with runghc it crashes.

Right, because when you compile it you are using the single threaded rts
but if you linked using -threaded or if you use ghci or runghc then you
are using the threaded rts.

There are two solutions:

     1. use the single threaded rts
     2. annotate all sequences of GUI calls with postGUISync or
        postGUIAsync so that they get run in the GUI thread and not some
        random thread.

The first is obviously much easier. Only go with the second if for some
reason you actually need the -threaded rts.

There is no claim that the second option is a good GUI programming
model. The Gtk2Hs developers added the possibility of running on the
threaded rts due to popular demand but the intention of the
reallyLongNamedFunction unsafeInitGUIForThreadedRTS is to make you stop
and think about what you are doing :-).

Perhaps we should make it even more so, like
unsafeInitGUIIHaveReadTheDocsAndIAmSureIAmNotGoingToShootMyselfInTheFoot

Duncan



More information about the Haskell-Cafe mailing list