MVar deadlock exceptions cause exceptions in later MVar ops
Take the following code:
import Control.Concurrent
import Control.Concurrent.MVar
import Control.Exception
main :: IO ()
main = do
var <- newEmptyMVar
_ <- forkIO $ do
res <- try $ newEmptyMVar >>= takeMVar
putMVar var res
putStrLn "Successfully filled var"
res <- readMVar var `onException` do
putStrLn "Received exception, delaying..."
threadDelay 1000000
res <- readMVar var
putStrLn $ "After delay, res is: " ++ show res
print (res :: Either SomeException Int)
putStrLn "Exiting..."
On line 9, an MVar deadlock exception is thrown, which is caught by try
. That result is then put into the var MVar. On line 13, I readMVar
to get this value. I would expect it to return the exception previously thrown, as a Left
value. Instead, a new exception is thrown. I say new, because if I switch over to using STM instead of an MVar, I get a different exception (STM transaction instead of MVar deadlock).
With the program as above, my output is:
Successfully filled var
Received exception, delaying...
After delay, res is: Left thread blocked indefinitely in an MVar operation
async14.hs: thread blocked indefinitely in an MVar operation
I originally filed this as an issue against the async package: https://github.com/simonmar/async/issues/14
Trac metadata
Trac field | Value |
---|---|
Version | 7.8.2 |
Type | Bug |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | Runtime System |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | simonmar |
Operating system | |
Architecture |