@@ -357,7 +357,7 @@ data RemoteState =
357357 -- | Invalid remote endpoint (for example, invalid address)
358358 RemoteEndPointInvalid !(TransportError ConnectErrorCode)
359359 -- | The remote endpoint is being initialized
360− | RemoteEndPointInit !(MVar ()) !RequestedBy
360+ | RemoteEndPointInit !(MVar ()) !(MVar ()) !RequestedBy
361361 -- | "Normal" working endpoint
362362 | RemoteEndPointValid !ValidRemoteEndPointState
363363 -- | The remote endpoint is being closed (garbage collected)
@@ -604,7 +604,7 @@ apiSend (ourEndPoint, theirEndPoint) connId connAlive payload =
604604 act <- withMVar (remoteState theirEndPoint) $ \st -> case st of
605605 RemoteEndPointInvalid _ ->
606606 relyViolation (ourEndPoint, theirEndPoint) "apiSend"
607− RemoteEndPointInit _ _ ->
607+ RemoteEndPointInit _ _ _ ->
608608 relyViolation (ourEndPoint, theirEndPoint) "apiSend"
609609 RemoteEndPointValid vst -> do
610610 alive <- readIORef connAlive
@@ -660,7 +660,7 @@ apiCloseEndPoint transport evs ourEndPoint =
660660 case st of
661661 RemoteEndPointInvalid _ ->
662662 return (st, Nothing)
663− RemoteEndPointInit resolved _ -> do
663+ RemoteEndPointInit resolved _ _ -> do
664664 putMVar resolved ()
665665 return (closed, Nothing)
666666 RemoteEndPointValid vst -> do
@@ -764,7 +764,7 @@ handleIncomingMessages (ourEndPoint, theirEndPoint) = do
764764 RemoteEndPointInvalid _ ->
765765 relyViolation (ourEndPoint, theirEndPoint)
766766 "handleIncomingMessages (invalid)"
767− RemoteEndPointInit _ _ ->
767+ RemoteEndPointInit _ _ _ ->
768768 relyViolation (ourEndPoint, theirEndPoint)
769769 "handleIncomingMessages (init)"
770770 RemoteEndPointValid ep ->
@@ -820,7 +820,7 @@ handleIncomingMessages (ourEndPoint, theirEndPoint) = do
820820 RemoteEndPointInvalid _ ->
821821 relyViolation (ourEndPoint, theirEndPoint)
822822 "handleIncomingMessages:createNewConnection (invalid)"
823− RemoteEndPointInit _ _ ->
823+ RemoteEndPointInit _ _ _ ->
824824 relyViolation (ourEndPoint, theirEndPoint)
825825 "handleIncomingMessages:createNewConnection (init)"
826826 RemoteEndPointValid vst ->
@@ -854,7 +854,7 @@ handleIncomingMessages (ourEndPoint, theirEndPoint) = do
854854 RemoteEndPointInvalid _ ->
855855 relyViolation (ourEndPoint, theirEndPoint)
856856 "readControlResponse (invalid)"
857− RemoteEndPointInit _ _ ->
857+ RemoteEndPointInit _ _ _ ->
858858 relyViolation (ourEndPoint, theirEndPoint)
859859 "readControlResponse (init)"
860860 RemoteEndPointValid vst ->
@@ -884,7 +884,7 @@ handleIncomingMessages (ourEndPoint, theirEndPoint) = do
884884 modifyMVar_ theirState $ \st -> case st of
885885 RemoteEndPointInvalid _ ->
886886 relyViolation (ourEndPoint, theirEndPoint) "closeConnection (invalid)"
887− RemoteEndPointInit _ _ ->
887+ RemoteEndPointInit _ _ _ ->
888888 relyViolation (ourEndPoint, theirEndPoint) "closeConnection (init)"
889889 RemoteEndPointValid vst -> do
890890 unless (IntSet.member cid (vst ^. remoteIncoming)) $
@@ -913,7 +913,7 @@ handleIncomingMessages (ourEndPoint, theirEndPoint) = do
913913 RemoteEndPointInvalid _ ->
914914 relyViolation (ourEndPoint, theirEndPoint)
915915 "handleIncomingMessages:closeSocket (invalid)"
916− RemoteEndPointInit _ _ ->
916+ RemoteEndPointInit _ _ _ ->
917917 relyViolation (ourEndPoint, theirEndPoint)
918918 "handleIncomingMessages:closeSocket (init)"
919919 RemoteEndPointValid vst -> do
@@ -971,7 +971,7 @@ handleIncomingMessages (ourEndPoint, theirEndPoint) = do
971971 RemoteEndPointInvalid _ ->
972972 relyViolation (ourEndPoint, theirEndPoint)
973973 "handleIncomingMessages:prematureExit"
974− RemoteEndPointInit _ _ ->
974+ RemoteEndPointInit _ _ _ ->
975975 relyViolation (ourEndPoint, theirEndPoint)
976976 "handleIncomingMessages:prematureExit"
977977 RemoteEndPointValid vst -> do
@@ -1055,7 +1055,13 @@ setupRemoteEndPoint params (ourEndPoint, theirEndPoint) hints = do
10551055 tryCloseSocket sock
10561056 return False
10571057 Right (sock, ConnectionRequestCrossed) -> do
1058− resolveInit (ourEndPoint, theirEndPoint) RemoteEndPointClosed
1058+ withMVar (remoteState theirEndPoint) $ \st -> case st of
1059+ RemoteEndPointInit _ crossed _ ->
1060+ putMVar crossed ()
1061+ RemoteEndPointFailed ex ->
1062+ throwIO ex
1063+ _ ->
1064+ relyViolation (ourEndPoint, theirEndPoint) "setupRemoteEndPoint: Crossed"
10591065 tryCloseSocket sock
10601066 return False
10611067 Left err -> do
@@ -1088,7 +1094,7 @@ doRemoteRequest (ourEndPoint, theirEndPoint) header = do
10881094 -- Error cases
10891095 RemoteEndPointInvalid err ->
10901096 throwIO err
1091− RemoteEndPointInit _ _ ->
1097+ RemoteEndPointInit _ _ _ ->
10921098 relyViolation (ourEndPoint, theirEndPoint) "doRemoteRequest (init)"
10931099 RemoteEndPointClosing _ _ ->
10941100 relyViolation (ourEndPoint, theirEndPoint) "doRemoteRequest (closing)"
@@ -1193,7 +1199,7 @@ connectToSelf ourEndPoint = do
11931199resolveInit :: EndPointPair -> RemoteState -> IO ()
11941200resolveInit (ourEndPoint, theirEndPoint) newState =
11951201 modifyMVar_ (remoteState theirEndPoint) $ \st -> case st of
1196− RemoteEndPointInit resolved _ -> do
1202+ RemoteEndPointInit resolved _ _ -> do
11971203 putMVar resolved ()
11981204 case newState of
11991205 RemoteEndPointClosed ->
@@ -1307,7 +1313,8 @@ findRemoteEndPoint ourEndPoint theirAddress findOrigin = go
13071313 return (st, (theirEndPoint, False))
13081314 Nothing -> do
13091315 resolved <- newEmptyMVar
1310− theirState <- newMVar (RemoteEndPointInit resolved findOrigin)
1316+ crossed <- newEmptyMVar
1317+ theirState <- newMVar (RemoteEndPointInit resolved crossed findOrigin)
13111318 scheduled <- newChan
13121319 let theirEndPoint = RemoteEndPoint
13131320 { remoteAddress = theirAddress
@@ -1347,7 +1354,7 @@ findRemoteEndPoint ourEndPoint theirAddress findOrigin = go
13471354 case snapshot of
13481355 RemoteEndPointInvalid err ->
13491356 throwIO err
1350− RemoteEndPointInit resolved initOrigin ->
1357+ RemoteEndPointInit resolved crossed initOrigin ->
13511358 case (findOrigin, initOrigin) of
13521359 (RequestedByUs, RequestedByUs) ->
13531360 readMVar resolved >> go
@@ -1355,9 +1362,10 @@ findRemoteEndPoint ourEndPoint theirAddress findOrigin = go
13551362 readMVar resolved >> go
13561363 (RequestedByThem, RequestedByUs) ->
13571364 if ourAddress > theirAddress
1358− then
1365+ then do
13591366 -- Wait for the Crossed message
1360− readMVar resolved >> go
1367+ readMVar crossed
1368+ return (theirEndPoint, True)
13611369 else
13621370 return (theirEndPoint, False)
13631371 (RequestedByThem, RequestedByThem) ->
@@ -1531,7 +1539,7 @@ internalSocketBetween transport ourAddress theirAddress = do
15311539 Nothing -> throwIO $ userError "Remote endpoint not found"
15321540 Just ep -> return ep
15331541 withMVar (remoteState theirEndPoint) $ \st -> case st of
1534− RemoteEndPointInit _ _ ->
1542+ RemoteEndPointInit _ _ _ ->
15351543 throwIO $ userError "Remote endpoint not yet initialized"
15361544 RemoteEndPointValid vst ->
15371545 return $ remoteSocket vst