@@ -76,7 +76,6 @@ import Control.Distributed.Process.Internal.StrictMVar
7676 , newEmptyMVar
7777 , putMVar
7878 , takeMVar
79− , readMVar
8079 )
8180import Control.Concurrent.Chan (newChan, writeChan, readChan)
8281import qualified Control.Concurrent.MVar as MVar (newEmptyMVar, takeMVar)
@@ -119,6 +118,9 @@ import Control.Distributed.Process.Internal.Types
119118 , LocalNode(..)
120119 , MxEventBus(..)
121120 , LocalNodeState(..)
121+ , ValidLocalNodeState(..)
122+ , withValidLocalState
123+ , modifyValidLocalState_
122124 , LocalProcess(..)
123125 , LocalProcessState(..)
124126 , Process(..)
@@ -231,7 +233,7 @@ newLocalNode transport rtable = do
231233createBareLocalNode :: NT.EndPoint -> RemoteTable -> IO LocalNode
232234createBareLocalNode endPoint rtable = do
233235 unq <- randomIO
234− state <- newMVar LocalNodeState
236+ state <- newMVar $ LocalNodeValid $ ValidLocalNodeState
235237 { _localProcesses = Map.empty
236238 , _localPidCounter = firstNonReservedProcessId
237239 , _localPidUnique = unq
@@ -322,7 +324,8 @@ startServiceProcesses node = do
322324--
323325-- TODO: for now we just close the associated endpoint
324326closeLocalNode :: LocalNode -> IO ()
325−closeLocalNode node =
327+closeLocalNode node = do
328+ modifyMVar_ (localState node) $ const $ return LocalNodeClosed
326329 -- TODO: close all our processes, surely!?
327330 NT.closeEndPoint (localEndPoint node)
328331
@@ -342,9 +345,9 @@ forkProcess node proc =
342345 modifyMVarMasked (localState node) startProcess
343346 where
344347 startProcess :: LocalNodeState -> IO (LocalNodeState, ProcessId)
345− startProcess st = do
346− let lpid = LocalProcessId { lpidCounter = st ^. localPidCounter
347− , lpidUnique = st ^. localPidUnique
348+ startProcess (LocalNodeValid vst) = do
349+ let lpid = LocalProcessId { lpidCounter = vst ^. localPidCounter
350+ , lpidUnique = vst ^. localPidUnique
348351 }
349352 let pid = ProcessId { processNodeId = localNodeId node
350353 , processLocalId = lpid
@@ -376,7 +379,7 @@ forkProcess node proc =
376379 (return . DiedException . (show :: SomeException -> String)))]
377380
378381 -- [Unified: Table 4, rules termination and exiting]
379− modifyMVar_ (localState node) (cleanupProcess pid)
382+ modifyValidLocalState_ (localState node) (cleanupProcess pid)
380383 writeChan (localCtrlChan node) NCMsg
381384 { ctrlMsgSender = ProcessIdentifier pid
382385 , ctrlMsgSignal = Died (ProcessIdentifier pid) reason
@@ -391,27 +394,30 @@ forkProcess node proc =
391394 -- TODO: this doesn't look right at all - how do we know
392395 -- that newUnique represents a process id that is available!?
393396 newUnique <- randomIO
394− return ( (localProcessWithId lpid ^= Just lproc)
397+ return ( LocalNodeValid
398+ $ (localProcessWithId lpid ^= Just lproc)
395399 . (localPidCounter ^= firstNonReservedProcessId)
396400 . (localPidUnique ^= newUnique)
397− $ st
401+ $ vst
398402 , pid
399403 )
400404 else
401− return ( (localProcessWithId lpid ^= Just lproc)
405+ return ( LocalNodeValid
406+ $ (localProcessWithId lpid ^= Just lproc)
402407 . (localPidCounter ^: (+ 1))
403− $ st
408+ $ vst
404409 , pid
405410 )
411+ startProcess LocalNodeClosed = throwIO $ userError "LocalNode closed"
406412
407− cleanupProcess :: ProcessId -> LocalNodeState -> IO LocalNodeState
408− cleanupProcess pid st = do
413+ cleanupProcess :: ProcessId -> ValidLocalNodeState -> IO ValidLocalNodeState
414+ cleanupProcess pid vst = do
409415 let pid' = ProcessIdentifier pid
410− let (affected, unaffected) = Map.partitionWithKey (\(fr, _to) !_v -> impliesDeathOf pid' fr) (st ^. localConnections)
416+ let (affected, unaffected) = Map.partitionWithKey (\(fr, _to) !_v -> impliesDeathOf pid' fr) (vst ^. localConnections)
411417 mapM_ (NT.close . fst) (Map.elems affected)
412418 return $ (localProcessWithId (processLocalId pid) ^= Nothing)
413419 . (localConnections ^= unaffected)
414− $ st
420+ $ vst
415421
416422-- note [tracer/forkProcess races]
417423--
@@ -500,7 +506,7 @@ handleIncomingMessages node = go initConnectionState
500506 case decode (BSL.fromChunks payload) of
501507 ProcessIdentifier pid -> do
502508 let lpid = processLocalId pid
503− mProc <- withMVar state $ return . (^. localProcessWithId lpid)
509+ mProc <- withValidLocalState state $ return . (^. localProcessWithId lpid)
504510 case mProc of
505511 Just proc ->
506512 go (incomingAt cid ^= Just (src, ToProc pid (processWeakQ proc)) $ st)
@@ -509,7 +515,7 @@ handleIncomingMessages node = go initConnectionState
509515 SendPortIdentifier chId -> do
510516 let lcid = sendPortLocalId chId
511517 lpid = processLocalId (sendPortProcessId chId)
512− mProc <- withMVar state $ return . (^. localProcessWithId lpid)
518+ mProc <- withValidLocalState state $ return . (^. localProcessWithId lpid)
513519 case mProc of
514520 Just proc -> do
515521 mChannel <- withMVar (processState proc) $ return . (^. typedChannelWithId lcid)
@@ -970,8 +976,8 @@ ncEffectGetInfo from pid =
970976 them = (ProcessIdentifier pid)
971977 in do
972978 node <- ask
973− mProc <- liftIO $
974− withMVar (localState node) $ return . (^. localProcessWithId lpid)
979+ mProc <- liftIO $ withValidLocalState (localState node)
980+ $ return . (^. localProcessWithId lpid)
975981 case mProc of
976982 Nothing -> dispatch (isLocal node (ProcessIdentifier from))
977983 from node (ProcessInfoNone DiedUnknownId)
@@ -1014,17 +1020,17 @@ ncEffectGetNodeStats :: ProcessId -> NodeId -> NC ()
10141020ncEffectGetNodeStats from _nid = do
10151021 node <- ask
10161022 ncState <- StateT.get
1017− nodeState <- liftIO $ readMVar (localState node)
1018− let localProcesses' = nodeState ^. localProcesses
1019− stats =
1023+ nodeState <- liftIO $ withValidLocalState (localState node) return
1024+ let stats =
10201025 NodeStats {
10211026 nodeStatsNode = localNodeId node
10221027 , nodeStatsRegisteredNames = Map.size $ ncState ^. registeredHere
10231028 , nodeStatsMonitors = Map.size $ ncState ^. monitors
10241029 , nodeStatsLinks = Map.size $ ncState ^. links
1025− , nodeStatsProcesses = Map.size localProcesses'
1030+ , nodeStatsProcesses = Map.size (nodeState ^. localProcesses)
10261031 }
10271032 postAsMessage from stats
1033+
10281034--------------------------------------------------------------------------------
10291035-- Auxiliary --
10301036--------------------------------------------------------------------------------
@@ -1097,7 +1103,7 @@ unClosure closure = do
10971103isValidLocalIdentifier :: Identifier -> NC Bool
10981104isValidLocalIdentifier ident = do
10991105 node <- ask
1100− liftIO . withMVar (localState node) $ \nSt ->
1106+ liftIO . withValidLocalState (localState node) $ \nSt ->
11011107 case ident of
11021108 NodeIdentifier nid ->
11031109 return $ nid == localNodeId node
@@ -1135,8 +1141,8 @@ withLocalProc node pid p =
11351141 -- By [Unified: table 6, rule missing_process] messages to dead processes
11361142 -- can silently be dropped
11371143 let lpid = processLocalId pid in do
1138− mProc <- withMVar (localState node) $ return . (^. localProcessWithId lpid)
1139− forM_ mProc p
1144+ withValidLocalState (localState node) $ \vst ->
1145+ forM_ (vst ^. localProcessWithId lpid) p
11401146
11411147--------------------------------------------------------------------------------
11421148-- Accessors --