git.iko.soy/distributed-process
on master help sign in
Re-work linked shutdown between NC and listener threads

Using `throwTo` seems sensible, but holding on to a ThreadId can prevent BlockedIndefinitely exceptions (such as BlockedIndefinitelyOnMVar) from propagating. Instead we ensure that once the NC terminates, the endpoint gets closed, and vice versa. The NC handles its termination signal with throwIO, avoiding this problem.

commitc52e8decaa2332804e61f5d873249bed3feac755 authorTim Watson <tim@rabbitmq.com> dateMon 29 Apr 2013, 10:10 (13 years ago) parent263cb13
1 file changed+12−21
src/Control/Distributed/Process/Node.hs+12−21
src/Control/Distributed/Process/Node.hs+12−21
@@ -56,8 +56,8 @@ import Control.Exception
5656 , Exception
5757 , throwTo
5858 )
59−import qualified Control.Exception as Exception (catch)
60−import Control.Concurrent (forkIO, mkWeakThreadId, ThreadId)
59+import qualified Control.Exception as Exception (catch, finally)
60+import Control.Concurrent (forkIO)
6161import Control.Distributed.Process.Internal.StrictMVar
6262 ( newMVar
6363 , withMVar
@@ -216,19 +216,14 @@ createBareLocalNode endPoint rtable = do
216216 }
217217 tracedNode <- startTracing node
218218
219− ncGo <- newEmptyMVar
220− ncTid <- forkIO $ do
221− tid <- takeMVar ncGo
222− (runNodeController tracedNode
223− `Exception.catch` \(e :: SomeException) -> reThrow tid e)
219+ -- Once the NC terminates, the endpoint isn't much use,
220+ void $ forkIO $ Exception.finally (runNodeController tracedNode)
221+ (NT.closeEndPoint (localEndPoint node))
224222
225− weakNcTid <- mkWeakThreadId ncTid
226− evTid <- forkIO $ do
227− (handleIncomingMessages tracedNode >> (stopNC node))
228− `Exception.catch` \(e :: SomeException) -> reThrow weakNcTid e
223+ -- whilst a closed/failing endpoint will terminate the NC
224+ void $ forkIO $ Exception.finally (handleIncomingMessages tracedNode)
225+ (stopNC node)
229226
230− weakEvTid <- mkWeakThreadId evTid
231− putMVar ncGo weakEvTid
232227 return tracedNode
233228 where
234229 stopNC node =
@@ -237,13 +232,6 @@ createBareLocalNode endPoint rtable = do
237232 , ctrlMsgSignal = SigShutdown
238233 }
239234
240− reThrow :: (Exception e) => Weak ThreadId -> e -> IO ()
241− reThrow wTid ex = do
242− tid <- deRefWeak wTid
243− case tid of
244− Nothing -> return ()
245− Just t -> throwTo t ex
246−
247235-- | Start and register the service processes on a node
248236-- (for now, this is only the logger)
249237startServiceProcesses :: LocalNode -> IO ()
@@ -619,7 +607,10 @@ nodeController = do
619607 NCMsg (ProcessIdentifier from) (GetInfo pid) ->
620608 ncEffectGetInfo from pid
621609 NCMsg _ SigShutdown ->
622− liftIO $ throwIO ThreadKilled -- seems to make more sense than fail/error
610+ liftIO $ do
611+ NT.closeEndPoint (localEndPoint node)
612+ `Exception.finally` throwIO ThreadKilled
613+ -- ThreadKilled seems to make more sense than fail/error here
623614 unexpected ->
624615 error $ "nodeController: unexpected message " ++ show unexpected
625616