
Simon Marlow wrote:
import Control.Concurrent import Control.Exception import Control.Monad import System.IO.Unsafe
main :: IO () main = do -- evaluate lock -- adding this line fixes the problem
fin1<- newEmptyMVar fin2<- newEmptyMVar
forkIO $ ping>>= putMVar fin1 forkIO $ ping>>= putMVar fin2
takeMVar fin1 takeMVar fin2
{-# NOINLINE lock #-} lock :: MVar () lock = unsafePerformIO $ newMVar ()
ping = do ()<- takeMVar lock putMVar lock ()
Since I don't yet understand why this blocks, I cannot say whether it should work or not.
I think it should work. Could you make a ticket for it please?
http://hackage.haskell.org/trac/ghc/ticket/5558 It occurred to me that normally, MVars will always be fully evaluated, since they are supposedly created by a previous IO action. This property is violated in this program. Perhaps that's the reason? Bertram