summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Marlow <marlowsd@gmail.com>2014-05-30 08:47:26 +0100
committerSimon Marlow <marlowsd@gmail.com>2014-05-30 09:49:44 +0100
commit96a95f0513de785a185fd8a46c7ed2643f698295 (patch)
treecce1c8874d50cecace4d6d25951c067aee40edf9
parent660c3f9d8534e3b249b27ab4024939d204366cc7 (diff)
downloadhaskell-96a95f0513de785a185fd8a46c7ed2643f698295.tar.gz
Fix missing unlockClosure() call in tryReadMVar (#9148)
-rw-r--r--rts/PrimOps.cmm1
-rw-r--r--testsuite/tests/concurrent/should_run/all.T1
-rw-r--r--testsuite/tests/concurrent/should_run/tryReadMVar2.hs15
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
+