X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=Control%2FConcurrent.hs;h=6122a102b7b09cee55d9b5cfbfd11d0d9b26f6bc;hb=0bf2fdab482da7a287ef09f18e7656abe62256d0;hp=2d9cf5786bb29fb9630a4b9b8c8e0692e868badc;hpb=d2063b5b0be014545b21819172c87756efcb0b0c;p=ghc-base.git diff --git a/Control/Concurrent.hs b/Control/Concurrent.hs index 2d9cf57..6122a10 100644 --- a/Control/Concurrent.hs +++ b/Control/Concurrent.hs @@ -28,6 +28,7 @@ module Control.Concurrent ( forkIO, #ifdef __GLASGOW_HASKELL__ + forkIOUnmasked, killThread, throwTo, #endif @@ -98,9 +99,9 @@ import Control.Exception.Base as Exception #ifdef __GLASGOW_HASKELL__ import GHC.Exception import GHC.Conc ( ThreadId(..), myThreadId, killThread, yield, - threadDelay, forkIO, childHandler ) + threadDelay, forkIO, forkIOUnmasked, childHandler ) import qualified GHC.Conc -import GHC.IO ( IO(..), unsafeInterleaveIO ) +import GHC.IO ( IO(..), unsafeInterleaveIO, unsafeUnmask ) import GHC.IORef ( newIORef, readIORef, writeIORef ) import GHC.Base @@ -357,13 +358,15 @@ failNonThreaded = fail $ "RTS doesn't support multiple OS threads " forkOS action0 | rtsSupportsBoundThreads = do mv <- newEmptyMVar - b <- Exception.blocked + b <- Exception.getMaskingState let - -- async exceptions are blocked in the child if they are blocked + -- async exceptions are masked in the child if they are masked -- in the parent, as for forkIO (see #1048). forkOS_createThread - -- creates a thread with exceptions blocked by default. - action1 | b = action0 - | otherwise = unblock action0 + -- creates a thread with exceptions masked by default. + action1 = case b of + Unmasked -> unsafeUnmask action0 + MaskedInterruptible -> action0 + MaskedUninterruptible -> uninterruptibleMask_ action0 action_plus = Exception.catch action1 childHandler @@ -430,7 +433,10 @@ runInUnboundThread action = do if bound then do mv <- newEmptyMVar - forkIO (Exception.try action >>= putMVar mv) + b <- blocked + _ <- mask $ \restore -> forkIO $ + Exception.try (if b then action else restore action) >>= + putMVar mv takeMVar mv >>= \ei -> case ei of Left exception -> Exception.throw (exception :: SomeException) Right result -> return result @@ -453,7 +459,8 @@ threadWaitRead fd -- and this only works with -threaded. | threaded = withThread (waitFd fd 0) | otherwise = case fd of - 0 -> do hWaitForInput stdin (-1); return () + 0 -> do _ <- hWaitForInput stdin (-1) + return () -- hWaitForInput does work properly, but we can only -- do this for stdin since we know its FD. _ -> error "threadWaitRead requires -threaded on Windows, or use System.IO.hWaitForInput" @@ -478,7 +485,7 @@ foreign import ccall unsafe "rtsSupportsBoundThreads" threaded :: Bool withThread :: IO a -> IO a withThread io = do m <- newEmptyMVar - forkIO $ try io >>= putMVar m + _ <- mask_ $ forkIO $ try io >>= putMVar m x <- takeMVar m case x of Right a -> return a @@ -486,9 +493,8 @@ withThread io = do waitFd :: Fd -> CInt -> IO () waitFd fd write = do - throwErrnoIfMinus1 "fdReady" $ + throwErrnoIfMinus1_ "fdReady" $ fdReady (fromIntegral fd) write (fromIntegral iNFINITE) 0 - return () iNFINITE :: CInt iNFINITE = 0xFFFFFFFF -- urgh