@@ -15,7 +15,9 @@ import qualified Data.ByteString.Lazy as BSL (toChunks)
1515import qualified Data.ByteString as BSS (ByteString)
1616import Control.Distributed.Process.Serializable ()
1717
18+import Control.Concurrent (forkIO)
1819import Control.Concurrent.Chan (writeChan)
20+import Control.Exception (mask_)
1921import Control.Monad (unless)
2022import Control.Monad.IO.Class (liftIO)
2123import Control.Monad.Reader (ask)
@@ -30,6 +32,7 @@ import qualified Network.Transport as NT
3032import Control.Distributed.Process.Internal.Types
3133 ( LocalNode(localState, localEndPoint, localCtrlChan)
3234 , withValidLocalState
35+ , modifyValidLocalState
3336 , modifyValidLocalState_
3437 , Identifier
3538 , localConnections
@@ -51,6 +54,7 @@ import Control.Distributed.Process.Internal.Types
5154 , Identifier(NodeIdentifier, ProcessIdentifier, SendPortIdentifier)
5255 )
5356import Control.Distributed.Process.Serializable (Serializable)
57+import Data.Foldable (forM_)
5458
5559--------------------------------------------------------------------------------
5660-- Message sending --
@@ -135,24 +139,28 @@ connBetween node from to implicitReconnect = do
135139 setupConnBetween node from to implicitReconnect
136140
137141disconnect :: LocalNode -> Identifier -> Identifier -> IO ()
138−disconnect node from to =
139− modifyValidLocalState_ node $ \vst ->
142+disconnect node from to = mask_ $ do
143+ mio <- modifyValidLocalState node $ \vst ->
140144 case vst ^. localConnectionBetween from to of
141145 Nothing ->
142− return vst
146+ return (vst, return ())
143147 Just (conn, _) -> do
144− NT.close conn
145− return $ localConnectionBetween from to ^= Nothing $ vst
148+ return ( localConnectionBetween from to ^= Nothing $ vst
149+ , NT.close conn
150+ )
151+ forM_ mio forkIO
146152
147153closeImplicitReconnections :: LocalNode -> Identifier -> IO ()
148−closeImplicitReconnections node to =
149− modifyValidLocalState_ node $ \vst -> do
154+closeImplicitReconnections node to = mask_ $ do
155+ mconns <- modifyValidLocalState node $ \vst -> do
150156 let shouldClose (_, to') (_, WithImplicitReconnect) = to `impliesDeathOf` to'
151157 shouldClose _ _ = False
152158 let (affected, unaffected) =
153159 Map.partitionWithKey shouldClose (vst ^. localConnections)
154− mapM_ (NT.close . fst) (Map.elems affected)
155− return $ localConnections ^= unaffected $ vst
160+ return ( localConnections ^= unaffected $ vst
161+ , map fst $ Map.elems affected
162+ )
163+ forM_ mconns $ forkIO . mapM_ NT.close
156164
157165-- | @a `impliesDeathOf` b@ is true if the death of @a@ (for instance, a node)
158166-- implies the death of @b@ (for instance, a process on that node)