Skip to content

BlockedIndefinitelyOnMVar thrown with live reference in unrelated finalizer

I am not sure whether this is a bug, but it is certainly unexpected behaviour. The following code throws a BlockedIndefinitelyOnMVar in the forked thread even though the MVar would be eventually written to by an unrelated finalizer:

import           Control.Concurrent
import           Data.IORef

main :: IO ()
main = do
  mvar <- newEmptyMVar
  -- _ <- forkIO $ threadDelay 9999999999999 >> isEmptyMVar mvar >> return ()
  ref <- newIORef () -- unrelated IORef
  _ <- mkWeakIORef ref (putMVar mvar ()) -- register finalizer
  _ <- forkFinally (takeMVar mvar :: IO ()) print
  threadDelay 1000000

And indeed, if the forkIO line is uncommented no exception is thrown, as the new thread keeps another live reference to the MVar. Is this intended behaviour? Why does the MVar reference in the finalizer not count for BlockedIndefinitelyOnMVar?

(A similar thing happens with STM primitives.)

Trac metadata
Trac field Value
Version 7.10.2
Type Bug
TypeOfFailure OtherFailure
Priority normal
Resolution Unresolved
Component Runtime System
Test case
Differential revisions
BlockedBy
Related
Blocking
CC simonmar
Operating system
Architecture
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information