After more testing I found an ugly problem that a child could be killed before the finally installed the handler that calls (putMVar doneMVar ())
Thus I have added slightly more paranoid code to ensure that the child is running before exposing the (T)MVar/ThreadId to the rest of the application. That this was needed is is really really annoying, and does not *really* fix the problem but just minimize it. Change fork to: > fork todo = block $ do > doneVar <- atomically (newEmptyTMVar) > let putStarted = atomically (putTMVar doneVar False) > putStopped = atomically (tryTakeTMVar doneVar >> putTMVar doneVar True) > tid <- forkIO $ block $ (finally (putStarted >> unblock todo) putStopped) > yield > atomically $ do > value <- takeTMVar doneVar > when value (putTMVar doneVar True) > return (doneVar,tid) and in the rest of the code change a few readMVar to readTMVar and add atomically. The doneVar is in 3 states: empty meaning child has not started yet False meaning child has definitely started empty meaning meaning child is still running True meaning child has definitely stopped The first two of those states should only be seen inside the fork function. When the fork function is finished only the second two states should be seen. -- Chris _______________________________________________ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell