
On Sat, Oct 24, 2009 at 03:42:14PM +0200, Nils wrote:
Hi there,
I'm trying to write a little status bar extension, which allows X.U.Loggers (and other) to be piped into dzen2 which then gets updated every X seconds (the dynamicLogHooks update only after an xmonad event). So I thought, forkIO with a threadDelay should do the job, but something weird happened.
The code is: http://paste.n-sch.de/0y/hs
Then run it with:
main = do runStatusbar $ defaultStatusBar "dzen" xmonad $ ...
If I start xmonad like this, the forked process stops after a short amount of time and continues only when I hit some xmonad-keybindings (even that happens pretty random). For example, if I remove the threadDelay from the previous code, you would expect to have a never ending counter in your dzen bar. But it starts counting up to about 10000, stops and waits for some input and (maybe) continues counting for another 1000 or 2000.
Can anyone see why xmonad acts like this with forkIO?
The problem is that xmonad is not compiled with -threaded, which is needed to make forkIO work properly with blocking FFI calls. In this case the problem is that getEvent also blocks all threads created with forkIO which is the reason for the behavior you are experiencing. The next problem is that compiling xmonad with -threaded is potentially dangerous, since xlib is not reentrant, so making X calls in multiple threads can lead to lockups which also happened in practice, when dons tried that. So one could either add -threaded to the compilation flags and instruct everyone not to use any X-related functionality in the new thread, with the downside that bad code can cause lockups, or port xmonad to xhb which is fully reentrant, if I recall correctly. A third option would be to add bindings for Xlib's locking mechanisms[1] in haskell-x11 and use those in the new thread. [1] http://tronche.com/gui/x/xlib/display/threads.html