Fix risk of dead-lock in documentation of Control.Concurrent

The current documentation of Control.Concurrent proposes a function to wait for a child thread to complete: myForkIO :: IO () -> IO (MVar ()) myForkIO io = do mvar <- newEmptyMVar forkIO (io `finally` putMVar mvar ()) return mvar This function has the risk of causing a dead-lock. If an asynchronous exception if thrown before the putMVar exception handler is installed the mvar will remain empty. This causes a dead-lock when the mvar is taken. The patch attached to the ticket [6126] fixes this problem by correctly masking asynchronous exceptions before forking. Also, instead of returning the mvar it returns a computation that waits for the child thread to complete. This is safer than returning the mvar itself since a user can't accidentally put the mvar (which will dead-lock) or take the mvar (which when executed twice will dead-lock). The attached patch additionally rewrites the function to wait for a group of threads to complete. Instead of keeping a list of MVars, I use a counter (stored in a TVar) that counts the number of running threads. The counter is incremented when a thread if forked and decremented when it completes. Waiting for the group of threads to complete is accomplished by checking if the counter has reached 0 and if not retry the transaction. Regards, Bas [6126] http://hackage.haskell.org/trac/ghc/ticket/6126
participants (1)
-
Bas van Dijk