diff options
author | David Feuer <david.feuer@gmail.com> | 2018-05-29 16:51:16 -0400 |
---|---|---|
committer | David Feuer <David.Feuer@gmail.com> | 2018-05-29 16:56:40 -0400 |
commit | 5e91cdecc39d326e7fc42b3ea41de66c2302484f (patch) | |
tree | 2b574fa1303bd603df695755f7e8c09d45582696 /libraries | |
parent | 576078a8a126f24c3dfdd16e2b6d1db50dd9050f (diff) | |
download | haskell-5e91cdecc39d326e7fc42b3ea41de66c2302484f.tar.gz |
Unmask readMVar in readChan
When `readMVar` was implemented using `takeMVar` and `putMVar`,
we needed to use `modifyMVarMasked` in `readChan` just in case
the `readMVar` was interrupted between taking and putting. Now
that `readMVar` uses an atomic primop, this is impossible, so we can
safely unmask `readMVar`.
Reviewers: hvr, bgamari, simonmar
Reviewed By: simonmar
Subscribers: rwbarton, thomie, carter
Differential Revision: https://phabricator.haskell.org/D4738
Diffstat (limited to 'libraries')
-rw-r--r-- | libraries/base/Control/Concurrent/Chan.hs | 11 |
1 files changed, 1 insertions, 10 deletions
diff --git a/libraries/base/Control/Concurrent/Chan.hs b/libraries/base/Control/Concurrent/Chan.hs index d752a898f0..d0fed4a405 100644 --- a/libraries/base/Control/Concurrent/Chan.hs +++ b/libraries/base/Control/Concurrent/Chan.hs @@ -106,21 +106,12 @@ writeChan (Chan _ writeVar) val = do -- thread holds a reference to the channel. readChan :: Chan a -> IO a readChan (Chan readVar _) = do - modifyMVarMasked readVar $ \read_end -> do -- Note [modifyMVarMasked] + modifyMVar readVar $ \read_end -> do (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 |