[Haskell-cafe] FFI and callbacks

Duncan Coutts duncan.coutts at worcester.oxford.ac.uk
Mon Aug 22 14:05:35 EDT 2005


On Mon, 2005-08-22 at 18:13 +0200, Sebastian Sylvan wrote:
> On 8/22/05, Duncan Coutts <duncan.coutts at worcester.oxford.ac.uk> wrote:
> > On Mon, 2005-08-22 at 15:45 +0200, Sebastian Sylvan wrote:
> > 
> > > I haven't found any issues with wxHaskell misbehaving when it's called
> > > from different threads, but I'd like to know for sure that it's
> > > actually honest-to-goodness thread safe. So does anyone know?
> > 
> > Actually here's an even more direct statement. From:
> > 
> > http://www.wxwidgets.org/whychoos.htm
> > 
> >         Multithreading
> > 
> >         Like many frameworks, wxWidgets isn't 'thread-safe' in the sense
> >         that the programmer can use GUI code indiscriminately from
> >         threads, but it does have a range of thread and mutex classes
> >         for the careful and more ambitious programmer. These classes are
> >         under development.
> > 
> > Unfortunately, when using wxHaskell (or indeed Gtk2Hs) with -threaded,
> > this is exactly what's happening "using GUI code indiscriminately from
> > OS threads".
> > 
> > Which is why we need some better solution.
> 
> 
> Hmm... Perhaps some operations are thread safe? It would seem that
> there's no real reason for why "appendText" couldn't be thread-safe
> (maybe it just triggers an event for the control which is then handled
> by the event-system on the C-side).
> It certainly does seem that in this particular case it does work. It
> would be nice to know exactly when it works, and exactly when it
> won't.

I don't think this is a very profitable approach. Many operations may
seem to work on most platforms however that doesn't really help us in
general.

For example consider your appendText exmaple. Suppose I'm using Windows.
I create a text widget in OS thread A. Now I use appendText in thread B.
If it does relayed repainging then you might be ok, if it does immediate
repointing then it'll try to use GDI objects in thread B that were
created in thread A.

Even if it does use delayed rendering (in which case it'll be
re-rendered in thread A) you have the clasic problem of concurrently
modifying some object. Suppose you're using appendText in two Haskell
threads, then potentially they may be in two OS threads and you could
end up concurrently modifying the text widget's text buffer object. This
may work or it may corrupt the heap and segfault.

The point is, GUIs are complex libs that need to use propper locking (in
the case of wx on gtk) against concurrent modification or simply canot
be used cocurrently at all (in the case of drawing operations with wx on
win32).

> I want my forkIO's dammit!

Me too!

> Using a timer to yield every 20 ms may work
> fine for an app with just one or two threads, but for each thread you
> spawn you potentially add 20 ms latency to other threads which quickly
> becomes unacceptable.
> It's especially troublesome when the number of threads varies, cause
> then you'll have to prioritize between excessive polling or too high
> latency...

A propper solution is to do something at the the wxHaskell/Gtk2Hs
library level to allow Haskell threads to be used freely. Personally I
think this will require more help from the Haskell runtime system.
However there are other techniques that have to be tried first.

Duncan



More information about the Haskell-Cafe mailing list