|
1 | 1 | {-# LANGUAGE BangPatterns #-} |
| 2 | +{-# LANGUAGE BlockArguments #-} |
2 | 3 | {-# LANGUAGE DataKinds #-} |
3 | 4 | {-# LANGUAGE ExistentialQuantification #-} |
4 | 5 | {-# LANGUAGE FlexibleContexts #-} |
@@ -362,28 +363,31 @@ makeConnectionHandler muxTracer forkPolicy |
362 | 363 | hVersionData = agreedOptions |
363 | 364 | } |
364 | 365 | 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' = contramap (Mx.WithBearer connectionId) |
| 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.MuxTracerBundle { |
| 388 | + muxTracer = muxTracer', |
| 389 | + channelTracer = Mx.WithBearer connectionId `contramap` muxTracer } |
| 390 | + mux bearer |
387 | 391 |
|
388 | 392 | Right (HandshakeQueryResult vMap) -> do |
389 | 393 | atomically $ writePromise (Right HandshakeConnectionQuery) |
|
0 commit comments