@@ -83,6 +83,12 @@ import Control.Distributed.Process.Internal.StrictMVar
8383 , putMVar
8484 , takeMVar
8585 )
86+import Control.Distributed.Process.Internal.ThreadPool
87+ ( newThreadPool
88+ , submitTask
89+ , lookupWorker
90+ , ThreadPool
91+ )
8692import Control.Concurrent.Chan (newChan, writeChan, readChan)
8793import qualified Control.Concurrent.MVar as MVar (newEmptyMVar, takeMVar)
8894import Control.Concurrent.STM
@@ -249,12 +255,14 @@ createBareLocalNode endPoint rtable = do
249255 , _localConnections = Map.empty
250256 }
251257 ctrlChan <- newChan
258+ sendPool <- newThreadPool
252259 let node = LocalNode { localNodeId = NodeId $ NT.address endPoint
253260 , localEndPoint = endPoint
254261 , localState = state
255262 , localCtrlChan = ctrlChan
256263 , localEventBus = MxEventBusInitialising
257264 , remoteTable = rtable
265+ , localSendPool = sendPool
258266 }
259267 tracedNode <- startMxAgent node
260268
@@ -580,6 +588,8 @@ handleIncomingMessages node = go initConnectionState
580588 , ctrlMsgSignal = Died nid DiedDisconnect
581589 }
582590 let notLost k = not (k `Set.member` (st ^. incomingFrom theirAddr))
591+ liftIO $ lookupWorker (localSendPool node) (NodeId theirAddr)
592+ >>= maybe (return ()) killThread
583593 closeImplicitReconnections node nid
584594 go ( (incomingFrom theirAddr ^= Set.empty)
585595 . (incoming ^: Map.filterWithKey (const . notLost))
@@ -634,6 +644,12 @@ data NCState = NCState
634644 , _registeredOnNodes :: !(Map ProcessId [(NodeId,Int)])
635645 }
636646
647+submitSendPool :: LocalNode -> NodeId -> IO () -> IO ()
648+submitSendPool node nid task = submitTask (localSendPool node) fork nid task
649+ where
650+ fork io =
651+ forkIO $ io `Exception.catch` \(NodeClosedException _) -> return ()
652+
637653newtype NC a = NC { unNC :: StateT NCState (ReaderT LocalNode IO) a }
638654 deriving ( Applicative
639655 , Functor
@@ -644,11 +660,12 @@ newtype NC a = NC { unNC :: StateT NCState (ReaderT LocalNode IO) a }
644660 )
645661
646662initNCState :: NCState
647−initNCState = NCState { _links = Map.empty
648− , _monitors = Map.empty
649− , _registeredHere = Map.empty
650− , _registeredOnNodes = Map.empty
651− }
663+initNCState = NCState
664+ { _links = Map.empty
665+ , _monitors = Map.empty
666+ , _registeredHere = Map.empty
667+ , _registeredOnNodes = Map.empty
668+ }
652669
653670-- | Thrown in response to the user invoking 'kill' (see Primitives.hs). This
654671-- type is deliberately not exported so it cannot be caught explicitly.
@@ -666,7 +683,7 @@ ncSendToProcess pid msg = do
666683 node <- ask
667684 if processNodeId pid == localNodeId node
668685 then ncEffectLocalSend node pid msg
669− else liftIO $ sendBinary node
686+ else liftIO $ submitSendPool node (processNodeId pid) $ sendBinary node
670687 (NodeIdentifier $ localNodeId node)
671688 (NodeIdentifier $ processNodeId pid)
672689 WithImplicitReconnect
@@ -679,7 +696,7 @@ ncSendToNode to msg = do
679696 node <- ask
680697 liftIO $ if to == localNodeId node
681698 then writeChan (localCtrlChan node) $! msg
682− else sendBinary node
699+ else submitSendPool node to $ sendBinary node
683700 (NodeIdentifier $ localNodeId node)
684701 (NodeIdentifier to)
685702 WithImplicitReconnect