Expand compatibility note for readMVar
Currently, the note reads
Compatibility note: Prior to base 4.7, readMVar was a combination of takeMVar and putMVar. This mean that in the presence of other threads attempting to putMVar, readMVar could block. Furthermore, readMVar would not receive the next putMVar if there was already a pending thread blocked on takeMVar. The old behavior can be recovered by [...]
I don't think this goes quite far enough. Consider the following scenario:
main = do
mv <- newEmptyMVar
forkIO $ putMVar mv "a" >> ... >> takeMVar mv >>= ...
forkIO $ putMVar mv "b" >> ... >> takeMVar mv >>= ...
...
readMVar mv
(assume none of the ...s touch mv
)
With the current implementation of readMVar
, each child thread will put its value in the MVar
and then take that same value out. They may do so in either order, and the order will determine what value the main thread reads.
With the old implementation of readMVar
, there are two additional (symmetrical) possibilities. In one, the first child puts "a"
, the main thread takes "a"
, the second child puts "b"
, the first child takes "b"
, the main thread puts "a"
, and the second child takes "a"
.
So the old version of readMVar
could make an interaction between other threads substantially less deterministic. I believe the note should probably reflect that. Its language also could really use some clarification in general.
Trac metadata
Trac field | Value |
---|---|
Version | 8.2.2 |
Type | Bug |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | Core Libraries |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | |
Operating system | |
Architecture |