@@ -5,6 +5,7 @@
5{-# LANGUAGE BangPatterns #-}
5{-# LANGUAGE BangPatterns #-}
6{-# LANGUAGE GeneralizedNewtypeDeriving #-}
6{-# LANGUAGE GeneralizedNewtypeDeriving #-}
7{-# LANGUAGE RecordWildCards #-}
7{-# LANGUAGE RecordWildCards #-}
8+{-# LANGUAGE MagicHash #-}
9-- | Local nodes
10-- | Local nodes
@@ -60,6 +61,8 @@ import Control.Exception
60 , Exception
61 , Exception
62 , uninterruptibleMask_
63 , uninterruptibleMask_
64import qualified Control.Exception as Exception
67import qualified Control.Exception as Exception
65 ( Handler(..)
68 ( Handler(..)
@@ -210,9 +213,20 @@ import qualified Control.Distributed.Process.Internal.StrictContainerAccessors a
210 , mapDefault
213 , mapDefault
212import Control.Monad.Catch (try)
215import Control.Monad.Catch (try)
216+import GHC.IO (IO(..), unsafeUnmask)
217+import GHC.Base ( maskAsyncExceptions# )
213import Unsafe.Coerce
219import Unsafe.Coerce
214import Prelude
220import Prelude
222+-- Remove these definitions when the fix for
223+-- https://ghc.haskell.org/trac/ghc/ticket/10149
224+-- is included in all supported compilers:
225+block :: IO a -> IO a
226+block (IO io) = IO $ maskAsyncExceptions# io
227+unblock :: IO a -> IO a
228+unblock = unsafeUnmask
216--------------------------------------------------------------------------------
230--------------------------------------------------------------------------------
217-- Initialization --
231-- Initialization --
218--------------------------------------------------------------------------------
232--------------------------------------------------------------------------------
@@ -352,11 +366,14 @@ runProcess node proc = do
353-- | Spawn a new process on a local node
367-- | Spawn a new process on a local node
354forkProcess :: LocalNode -> Process () -> IO ProcessId
368forkProcess :: LocalNode -> Process () -> IO ProcessId
355−forkProcess node proc =
369+forkProcess node proc = do
370+ ms <- getMaskingState
356− modifyMVarMasked (localState node) startProcess
371+ modifyMVarMasked (localState node) (startProcess ms)
373+ startProcess :: MaskingState
358− startProcess :: LocalNodeState -> IO (LocalNodeState, ProcessId)
375+ -> IO (LocalNodeState, ProcessId)
359− startProcess (LocalNodeValid vst) = do
376+ startProcess ms (LocalNodeValid vst) = do
360 let lpid = LocalProcessId { lpidCounter = vst ^. localPidCounter
377 let lpid = LocalProcessId { lpidCounter = vst ^. localPidCounter
361 , lpidUnique = vst ^. localPidUnique
378 , lpidUnique = vst ^. localPidUnique
@@ -378,7 +395,13 @@ forkProcess node proc =
378 , processThread = tid
395 , processThread = tid
379 , processNode = node
396 , processNode = node
398+ -- Rewrite this code when this is fixed:
399+ -- https://ghc.haskell.org/trac/ghc/ticket/10149
400+ let unmask = case ms of
402+ MaskedInterruptible -> block
403+ MaskedUninterruptible -> id
381− tid' <- uninterruptibleMask_ $ forkIOWithUnmask $ \unmask -> do
404+ tid' <- uninterruptibleMask_ $ forkIO $ do
382 reason <- Exception.catches
405 reason <- Exception.catches
383 (unmask $ runLocalProcess lproc proc >> return DiedNormal)
406 (unmask $ runLocalProcess lproc proc >> return DiedNormal)
384 [ (Exception.Handler (\ex@(ProcessExitException from msg) -> do
407 [ (Exception.Handler (\ex@(ProcessExitException from msg) -> do
@@ -424,7 +447,7 @@ forkProcess node proc =
427− startProcess LocalNodeClosed =
450+ startProcess _ LocalNodeClosed =
428 throwIO $ NodeClosedException $ localNodeId node
451 throwIO $ NodeClosedException $ localNodeId node
430 cleanupProcess :: ProcessId
453 cleanupProcess :: ProcessId