[Haskell] Help needed interrupting accepting a network connection

Chris Kuklewicz haskell at list.mightyreason.com
Sun Dec 3 13:03:16 EST 2006

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.


More information about the Haskell mailing list