@@ -199,6 +199,7 @@ import Control.Distributed.Process.Internal.Types
199199 , WhereIsReply(..)
200200 , RegisterReply(..)
201201 , LocalProcess(processNode)
202+ , runLocalProcess
202203 , Message
203204 )
204205import Control.Distributed.Process.Serializable (Serializable)
@@ -316,7 +317,7 @@ import Control.Distributed.Process.Internal.Spawn
316317 , spawnSupervised
317318 , call
318319 )
319−import Control.Exception (SomeException, throw)
320+import Control.Exception (SomeException, throw, uninterruptibleMask_)
320321
321322-- INTERNAL NOTES
322323--
@@ -421,7 +422,15 @@ callLocal proc = mask $ \release -> do
421422 try (sendChan spInit () >> release proc) >>= liftIO . putMVar mv
422423 rs <- liftIO (takeMVar mv)
423424 `onException`
424− do receiveChan rpInit
425− kill child "exception in parent process"
426− liftIO (takeMVar mv)
425+ -- Exceptions need to be prevented from interrupting the clean up or
426+ -- the original exception which caused entering the handler could be
427+ -- forgotten. For instance, this could have a problematic effect
428+ -- when the original exception was meant to kill the thread and the
429+ -- second exception doesn't (like the exception thrown by
430+ -- 'System.Timeout.timeout').
431+ do lproc <- ask
432+ liftIO $ uninterruptibleMask_ $ runLocalProcess lproc $ do
433+ receiveChan rpInit
434+ kill child "exception in parent process"
435+ liftIO (takeMVar mv)
427436 either throw return rs