My code seems to be hanging on a readMVar after another thread calls putMVar. I wouldn't expect this to happen, but that's what I'm observing. My main thread creates two new threads, each with access to a shared MVar m.
Thread 1:
do
putStrLn "tick"
x <- readMVar m
putStrLn "tock"
Thread 2:
do
putMVar m 0
putStrLn "put m0"
void $ tryTakeMVar m
putStrLn "take m"
putMVar m 1
putStrLn "put m1"
Main:
do
m <- newEmptyMVar
<start thread 1>
<start thread 2>
In the following scenario, my program hangs:
Two threads have access to a shared MVar m, which is initially empty. Thread 1 blocks on readMVar m. Meanwhile, thread 2 calls putMVar m .... At this point, thread 1 could proceed, but let's suppose it does not. Thread 2 then calls tryTakeMVar m, which presumably empties a full MVar. Then thread 2 again calls putMVar m .... This scenario corresponds to the following output:
tick
put m0
take m
put m1
<hang>
What's going on here? I expect that "tock" should print, since thread 2 filled the MVar, but my program just hangs.
readMVaris atakeMVarfollowed by aputMVar(not performed atomically). If thetryTakeMVarand secondputMVarhappened between those, it would explain the behavior you're seeing. - Daniel WagnertryReadMVar. As a result, I implemented it myself usingtryTakeMVarandputMVar(non-atomically). Thus what Daniel says is spot on. - crockeea