Skip to content

Commit d4381fe

Browse files
fixup! Refactor Connection Handler
1 parent 81bd006 commit d4381fe

File tree

1 file changed

+24
-22
lines changed

1 file changed

+24
-22
lines changed

ouroboros-network-framework/src/Ouroboros/Network/ConnectionHandler.hs

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
{-# LANGUAGE BangPatterns #-}
2+
{-# LANGUAGE BlockArguments #-}
23
{-# LANGUAGE DataKinds #-}
34
{-# LANGUAGE ExistentialQuantification #-}
45
{-# LANGUAGE FlexibleContexts #-}
@@ -362,28 +363,29 @@ makeConnectionHandler muxTracer forkPolicy
362363
hVersionData = agreedOptions
363364
}
364365
atomically $ writePromise (Right $ HandshakeConnectionResult handle (versionNumber, agreedOptions))
365-
withBuffer (\buffer -> do
366-
bearer <- mkMuxBearer sduTimeout socket buffer
367-
case inResponderMode of
368-
InResponderMode (inboundGovChannelTracer, connectionDataFlow)
369-
| Duplex <- connectionDataFlow agreedOptions ->
370-
-- Following this call, the muxer is racing with the CM,
371-
-- was was informed of a new remote via the promise.
372-
-- The IG tracer pauses the muxer main thread when it reaches mature state
373-
-- until the CM informs the former of new peer connection to ensure
374-
-- proper sequencing of events.
375-
Mx.run (Mx.WithBearer connectionId `contramap` (muxTracer <> inboundGovChannelTracer))
376-
mux bearer
377-
_notResponder ->
378-
-- If this is InitiatorOnly, or a server where unidirectional flow was negotiated
379-
-- the IG will never be informed of this remote for obvious reasons. We should not pass
380-
-- the IG tracer to mux, and must not in the latter case as the muxer will
381-
-- deadlock itself before it launches any miniprotocols from the command queue.
382-
-- It will be stuck when reaches mature state, forever waiting for the incoming
383-
-- peer handle.
384-
Mx.run (Mx.WithBearer connectionId `contramap` muxTracer)
385-
mux bearer
386-
)
366+
withBuffer \buffer -> do
367+
bearer <- mkMuxBearer sduTimeout socket buffer
368+
let muxTracer' =
369+
case inResponderMode of
370+
InResponderMode (inboundGovChannelTracer, connectionDataFlow)
371+
| Duplex <- connectionDataFlow agreedOptions ->
372+
-- In this case, following the Mx.run call below, the muxer begins racing with
373+
-- the CM to write to the information channel queue. The tracer of mux activity,
374+
-- while the CM of new connection notification. The latter *should* come first.
375+
-- The IG tracer will block the muxer on a TVar when it reaches mature state
376+
-- until the CM informs the former of new peer connection to ensure
377+
-- proper sequencing of events.
378+
muxTracer <> inboundGovChannelTracer
379+
_notResponder ->
380+
-- If this is InitiatorOnly, or a server where unidirectional flow was negotiated
381+
-- the IG will never be informed of this remote for obvious reasons. There is no
382+
-- need to pass the responder IG tracer here, and we must not in the latter case
383+
-- as the muxer will deadlock itself before it launches any miniprotocols from the
384+
-- command queue. It will be stuck when reaches mature state, forever waiting for
385+
-- the incoming peer handle.
386+
muxTracer
387+
Mx.run (Mx.WithBearer connectionId `contramap` muxTracer')
388+
mux bearer
387389

388390
Right (HandshakeQueryResult vMap) -> do
389391
atomically $ writePromise (Right HandshakeConnectionQuery)

0 commit comments

Comments
 (0)