git.iko.soy/distributed-process
on master help sign in
fixup! Workaround race in callLocal.

This simplifies the workaround. Instead of monitoring the child, which can leak the monitor notification, we ensure the child has exceptions masked before trying to kill it.

commitc59ad491f1c4c4ceb67613bcb7aafea101af9395 authorFacundo Domínguez <facundo.dominguez@tweag.io> dateFri 11 Sep 2015, 16:01 (11 years ago) parent87bb129
1 file changed+7−15
src/Control/Distributed/Process.hs+7−15
src/Control/Distributed/Process.hs+7−15
@@ -415,21 +415,13 @@ spawnChannelLocal proc = do
415415callLocal :: Process a -> Process a
416416callLocal proc = mask $ \release -> do
417417 mv <- liftIO newEmptyMVar :: Process (MVar (Either SomeException a))
418− child <- spawnLocal $ mask_ $ try (release proc) >>= liftIO . putMVar mv
419− ref <- monitor child
418+ (spInit, rpInit) <- newChan -- TODO: Remove when spawnLocal inherits the
419+ -- masking state.
420+ child <- spawnLocal $ mask_ $
421+ try (sendChan spInit () >> release proc) >>= liftIO . putMVar mv
420422 rs <- liftIO (takeMVar mv)
421423 `onException`
422− (do kill child "exception in parent process"
423− waitFor ref
424− )
424+ do receiveChan rpInit
425+ kill child "exception in parent process"
426+ liftIO (takeMVar mv)
425427 either throw return rs
426− where
427− -- TODO: when processes spawned with spawnLocal inherit the masking state of
428− -- the parent, this can be simplified to simply reading the MVar.
429− --
430− -- At the time of this writing, the spawned process is unmasked and can be
431− -- killed before the MVar is filled.
432− waitFor ref = receiveWait
433− [ matchIf (\(ProcessMonitorNotification ref' _ _) -> ref == ref')
434− (\_ -> return ())
435− ]