diff options
author | David Feuer <david.feuer@gmail.com> | 2018-05-29 16:51:16 -0400 |
---|---|---|
committer | Tobias Dammers <tdammers@gmail.com> | 2018-05-30 12:45:51 +0200 |
commit | 35e510699dd02bd157a1ceabb0c9495f70665eb7 (patch) | |
tree | 2b574fa1303bd603df695755f7e8c09d45582696 | |
parent | 258b3835e03cdc5893bdf79d3565a0658b7f5f8f (diff) | |
download | haskell-35e510699dd02bd157a1ceabb0c9495f70665eb7.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
-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 |