Repository : ssh://darcs.haskell.org//srv/darcs/packages/base On branch : master
http://hackage.haskell.org/trac/ghc/changeset/900b5a0d58bcbae58aeffcd360fbaddde045b96e >--------------------------------------------------------------- commit 900b5a0d58bcbae58aeffcd360fbaddde045b96e Author: Simon Marlow <[email protected]> Date: Mon Jun 11 09:54:06 2012 +0100 fix another theoretical deadlock bug in the Chan implementation (c.f. #6153) >--------------------------------------------------------------- Control/Concurrent/Chan.hs | 11 ++++++++++- 1 files changed, 10 insertions(+), 1 deletions(-) diff --git a/Control/Concurrent/Chan.hs b/Control/Concurrent/Chan.hs index 2b84503..4bc72e3 100644 --- a/Control/Concurrent/Chan.hs +++ b/Control/Concurrent/Chan.hs @@ -102,12 +102,21 @@ writeChan (Chan _ writeVar) val = do -- |Read the next value from the 'Chan'. readChan :: Chan a -> IO a readChan (Chan readVar _) = do - modifyMVar readVar $ \read_end -> do + modifyMVarMasked readVar $ \read_end -> do -- Note [modifyMVarMasked] (ChItem val new_read_end) <- readMVar read_end -- Use readMVar here, not takeMVar, -- else dupChan doesn't work return (new_read_end, val) +-- Note [modifyMVarMasked] +-- This prevents a theoretical deadlock if an asynchronous exception +-- happens during the readMVar while the MVar is empty. In that case +-- the read_end MVar will be left empty, and subsequent readers will +-- deadlock. Using modifyMVarMasked prevents this. The deadlock can +-- be reproduced, but only by expanding readMVar and inserting an +-- artificial yield between its takeMVar and putMVar operations. + + -- |Duplicate a 'Chan': the duplicate channel begins empty, but data written to -- either channel from then on will be available from both. Hence this creates -- a kind of broadcast channel, where data written by anyone is seen by _______________________________________________ Cvs-libraries mailing list [email protected] http://www.haskell.org/mailman/listinfo/cvs-libraries
