git.iko.soy/distributed-process
on master help sign in
Protect callLocal from asynchronous exceptions during the clean up.

Interrupting the cleanup could cause the original exception to be ignored (i.e. the exception which caused the clean up to be executed). Ignoring the exception could be problematic. For instance, the exception can be meant to kill the thread. A later exception comming during the clean up could come from a wrapping call of System.Timeout.timeout, which would rather interrupt the computation but certainly not kill the thread.

commitff07b9f514c0b5a1dcdb00d8bd9a66266804d63c authorFacundo Domínguez <facundo.dominguez@tweag.io> dateFri 25 Sep 2015, 17:23 (11 years ago) parentc59ad49
1 file changed+13−4
src/Control/Distributed/Process.hs+13−4
src/Control/Distributed/Process.hs+13−4
@@ -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