summaryrefslogtreecommitdiff
path: root/libraries/base
diff options
context:
space:
mode:
authorDavid Feuer <david.feuer@gmail.com>2018-05-29 16:51:16 -0400
committerDavid Feuer <David.Feuer@gmail.com>2018-05-29 16:56:40 -0400
commit5e91cdecc39d326e7fc42b3ea41de66c2302484f (patch)
tree2b574fa1303bd603df695755f7e8c09d45582696 /libraries/base
parent576078a8a126f24c3dfdd16e2b6d1db50dd9050f (diff)
downloadhaskell-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/base')
-rw-r--r--libraries/base/Control/Concurrent/Chan.hs11
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