git.iko.soy/distributed-process
on master help sign in
Fix potential deadlock
74293efEdsko de Vries
network-transport-2/src/Network/Transport/TCP.hs+14−11
@@ -406,18 +406,21 @@ apiCloseEndPoint transport ourEndPoint = do
406 -- Close the remote socket and return the set of all incoming connections
406 -- Close the remote socket and return the set of all incoming connections
407 tryCloseRemoteSocket :: RemoteEndPoint -> IO IntSet
407 tryCloseRemoteSocket :: RemoteEndPoint -> IO IntSet
408 tryCloseRemoteSocket theirEndPoint = do
408 tryCloseRemoteSocket theirEndPoint = do
409− -- Like above, we take but don't put back
410− st <- takeMVar (remoteState theirEndPoint)
411 -- We make an attempt to close the connection nicely (by sending a CloseSocket first)
409 -- We make an attempt to close the connection nicely (by sending a CloseSocket first)
410+ modifyMVar (remoteState theirEndPoint) $ \st ->
412− case st of
411+ case st of
413− RemoteEndPointInvalid _ -> do return IntSet.empty
412+ RemoteEndPointInvalid _ ->
413+ return (st, IntSet.empty)
414− RemoteEndPointValid conn -> do tryIO $ do
414+ RemoteEndPointValid conn -> do
415+ tryIO $ do
415− sendOn conn [encodeInt32 CloseSocket]
416+ sendOn conn [encodeInt32 CloseSocket]
416− N.sClose (remoteSocket conn)
417+ N.sClose (remoteSocket conn)
417− return (conn ^. remoteIncoming)
418+ return (RemoteEndPointClosed, conn ^. remoteIncoming)
418− RemoteEndPointClosing _ conn -> do tryIO $ N.sClose (remoteSocket conn)
419+ RemoteEndPointClosing _ conn -> do
420+ tryIO $ N.sClose (remoteSocket conn)
419− return IntSet.empty
421+ return (RemoteEndPointClosed, IntSet.empty)
420− RemoteEndPointClosed -> do return IntSet.empty
422+ RemoteEndPointClosed ->
423+ return (RemoteEndPointClosed, IntSet.empty)
421
424
422-- | Special case of 'apiConnect': connect an endpoint to itself
425-- | Special case of 'apiConnect': connect an endpoint to itself
423connectToSelf :: LocalEndPoint -> IO (Either (FailedWith ConnectErrorCode) Connection)
426connectToSelf :: LocalEndPoint -> IO (Either (FailedWith ConnectErrorCode) Connection)
network-transport-2/tests/TestTransport.hs+4
@@ -582,6 +582,10 @@ testCloseEndPoint transport _ = do
582 -- Close the endpoint
582 -- Close the endpoint
583 closeEndPoint endpoint
583 closeEndPoint endpoint
584 ErrorEvent (ErrorEventEndPointClosed [cid'']) <- receive endpoint; True <- return $ cid == cid''
584 ErrorEvent (ErrorEventEndPointClosed [cid'']) <- receive endpoint; True <- return $ cid == cid''
585+
586+ -- Attempt to send should fail with connection closed
587+ Left (FailedWith SendConnectionClosed _) <- send conn ["ping2"]
588+
585 return ()
589 return ()
586
590
587 putMVar clientDone ()
591 putMVar clientDone ()