diff options
author | Simon Marlow <marlowsd@gmail.com> | 2014-05-30 08:47:26 +0100 |
---|---|---|
committer | Simon Marlow <marlowsd@gmail.com> | 2014-05-30 09:49:44 +0100 |
commit | 96a95f0513de785a185fd8a46c7ed2643f698295 (patch) | |
tree | cce1c8874d50cecace4d6d25951c067aee40edf9 | |
parent | 660c3f9d8534e3b249b27ab4024939d204366cc7 (diff) | |
download | haskell-96a95f0513de785a185fd8a46c7ed2643f698295.tar.gz |
Fix missing unlockClosure() call in tryReadMVar (#9148)
-rw-r--r-- | rts/PrimOps.cmm | 1 | ||||
-rw-r--r-- | testsuite/tests/concurrent/should_run/all.T | 1 | ||||
-rw-r--r-- | testsuite/tests/concurrent/should_run/tryReadMVar2.hs | 15 |
3 files changed, 17 insertions, 0 deletions
diff --git a/rts/PrimOps.cmm b/rts/PrimOps.cmm index 84bcea5bff..4d7baca824 100644 --- a/rts/PrimOps.cmm +++ b/rts/PrimOps.cmm @@ -1786,6 +1786,7 @@ stg_tryReadMVarzh ( P_ mvar, /* :: MVar a */ ) LOCK_CLOSURE(mvar, info); if (StgMVar_value(mvar) == stg_END_TSO_QUEUE_closure) { + unlockClosure(mvar, info); return (0, stg_NO_FINALIZER_closure); } diff --git a/testsuite/tests/concurrent/should_run/all.T b/testsuite/tests/concurrent/should_run/all.T index d4e76c6b1e..0b502c3bc7 100644 --- a/testsuite/tests/concurrent/should_run/all.T +++ b/testsuite/tests/concurrent/should_run/all.T @@ -78,6 +78,7 @@ test('readMVar1', normal, compile_and_run, ['']) test('readMVar2', normal, compile_and_run, ['']) test('readMVar3', normal, compile_and_run, ['']) test('tryReadMVar1', normal, compile_and_run, ['']) +test('tryReadMVar2', normal, compile_and_run, ['']) test('T7970', normal, compile_and_run, ['']) diff --git a/testsuite/tests/concurrent/should_run/tryReadMVar2.hs b/testsuite/tests/concurrent/should_run/tryReadMVar2.hs new file mode 100644 index 0000000000..13b8a45c32 --- /dev/null +++ b/testsuite/tests/concurrent/should_run/tryReadMVar2.hs @@ -0,0 +1,15 @@ +module Main where + +import Control.Concurrent +import Control.Monad + +main = do + m <- newEmptyMVar + done <- newEmptyMVar + let q = 200000 + forkIO (do mapM (\n -> putMVar m n) [1..q]; putMVar done ()) + forkIO (do replicateM_ q $ readMVar m; putMVar done ()) + forkIO (do replicateM_ q $ tryReadMVar m; putMVar done ()) + forkIO (do replicateM_ q $ takeMVar m; putMVar done ()) + replicateM_ 4 $ takeMVar done + |