@@ -34,7 +34,8 @@ internal sealed class MsQuicStream : QuicStreamProvider
34
34
// Resettable completions to be used for multiple calls to receive.
35
35
private readonly ResettableCompletionSource < uint > _receiveResettableCompletionSource ;
36
36
37
- private readonly ResettableCompletionSource < uint > _shutdownWriteResettableCompletionSource ;
37
+ // Set once writes have been shutdown.
38
+ private readonly TaskCompletionSource _shutdownWriteCompletionSource = new TaskCompletionSource ( TaskCreationOptions . RunContinuationsAsynchronously ) ;
38
39
39
40
// Buffers to hold during a call to send.
40
41
private MemoryHandle [ ] _bufferArrays = new MemoryHandle [ 1 ] ;
@@ -49,7 +50,7 @@ internal sealed class MsQuicStream : QuicStreamProvider
49
50
private ReadState _readState ;
50
51
private long _readErrorCode = - 1 ;
51
52
52
- private ShutdownWriteState _shutdownState ;
53
+ private ShutdownWriteState _shutdownWriteState ;
53
54
54
55
private SendState _sendState ;
55
56
private long _sendErrorCode = - 1 ;
@@ -76,7 +77,6 @@ internal MsQuicStream(MsQuicConnection connection, QUIC_STREAM_OPEN_FLAG flags,
76
77
77
78
_sendResettableCompletionSource = new ResettableCompletionSource < uint > ( ) ;
78
79
_receiveResettableCompletionSource = new ResettableCompletionSource < uint > ( ) ;
79
- _shutdownWriteResettableCompletionSource = new ResettableCompletionSource < uint > ( ) ;
80
80
SetCallbackHandler ( ) ;
81
81
82
82
bool isBidirectional = ! flags . HasFlag ( QUIC_STREAM_OPEN_FLAG . UNIDIRECTIONAL ) ;
@@ -323,16 +323,16 @@ internal override void AbortWrite(long errorCode)
323
323
324
324
lock ( _sync )
325
325
{
326
- if ( _shutdownState == ShutdownWriteState . None )
326
+ if ( _shutdownWriteState == ShutdownWriteState . None )
327
327
{
328
- _shutdownState = ShutdownWriteState . Canceled ;
328
+ _shutdownWriteState = ShutdownWriteState . Canceled ;
329
329
shouldComplete = true ;
330
330
}
331
331
}
332
332
333
333
if ( shouldComplete )
334
334
{
335
- _shutdownWriteResettableCompletionSource . CompleteException ( new QuicStreamAbortedException ( "Shutdown was aborted." , errorCode ) ) ;
335
+ _shutdownWriteCompletionSource . SetException ( new QuicStreamAbortedException ( "Shutdown was aborted." , errorCode ) ) ;
336
336
}
337
337
338
338
MsQuicApi . Api . StreamShutdownDelegate ( _ptr , ( uint ) QUIC_STREAM_SHUTDOWN_FLAG . ABORT_SEND , errorCode ) ;
@@ -348,20 +348,20 @@ internal override ValueTask ShutdownWriteCompleted(CancellationToken cancellatio
348
348
bool shouldComplete = false ;
349
349
lock ( _sync )
350
350
{
351
- if ( _shutdownState == ShutdownWriteState . None )
351
+ if ( _shutdownWriteState == ShutdownWriteState . None )
352
352
{
353
- _shutdownState = ShutdownWriteState . Canceled ;
353
+ _shutdownWriteState = ShutdownWriteState . Canceled ;
354
354
shouldComplete = true ;
355
355
}
356
356
}
357
357
358
358
if ( shouldComplete )
359
359
{
360
- _shutdownWriteResettableCompletionSource . CompleteException ( new OperationCanceledException ( "Shutdown was canceled" , cancellationToken ) ) ;
360
+ _shutdownWriteCompletionSource . SetException ( new OperationCanceledException ( "Shutdown was canceled" , cancellationToken ) ) ;
361
361
}
362
362
} ) ;
363
363
364
- return _shutdownWriteResettableCompletionSource . GetTypelessValueTask ( ) ;
364
+ return new ValueTask ( _shutdownWriteCompletionSource . Task ) ;
365
365
}
366
366
367
367
internal override void Shutdown ( )
@@ -408,8 +408,6 @@ public override ValueTask DisposeAsync()
408
408
return default ;
409
409
}
410
410
411
- CleanupSendState ( ) ;
412
-
413
411
if ( _ptr != IntPtr . Zero )
414
412
{
415
413
// TODO resolve graceful vs abortive dispose here. Will file a separate issue.
@@ -419,6 +417,8 @@ public override ValueTask DisposeAsync()
419
417
420
418
_handle . Free ( ) ;
421
419
420
+ CleanupSendState ( ) ;
421
+
422
422
_disposed = true ;
423
423
424
424
return default ;
@@ -442,8 +442,6 @@ private void Dispose(bool disposing)
442
442
return ;
443
443
}
444
444
445
- CleanupSendState ( ) ;
446
-
447
445
if ( _ptr != IntPtr . Zero )
448
446
{
449
447
// TODO resolve graceful vs abortive dispose here. Will file a separate issue.
@@ -453,6 +451,8 @@ private void Dispose(bool disposing)
453
451
454
452
_handle . Free ( ) ;
455
453
454
+ CleanupSendState ( ) ;
455
+
456
456
_disposed = true ;
457
457
}
458
458
@@ -461,7 +461,7 @@ private void EnableReceive()
461
461
MsQuicApi . Api . StreamReceiveSetEnabledDelegate ( _ptr , enabled : true ) ;
462
462
}
463
463
464
- internal static uint NativeCallbackHandler (
464
+ private static uint NativeCallbackHandler (
465
465
IntPtr stream ,
466
466
IntPtr context ,
467
467
ref StreamEvent streamEvent )
@@ -614,16 +614,16 @@ private uint HandleEventSendShutdownComplete(ref MsQuicNativeMethods.StreamEvent
614
614
bool shouldComplete = false ;
615
615
lock ( _sync )
616
616
{
617
- if ( _shutdownState == ShutdownWriteState . None )
617
+ if ( _shutdownWriteState == ShutdownWriteState . None )
618
618
{
619
- _shutdownState = ShutdownWriteState . Finished ;
619
+ _shutdownWriteState = ShutdownWriteState . Finished ;
620
620
shouldComplete = true ;
621
621
}
622
622
}
623
623
624
624
if ( shouldComplete )
625
625
{
626
- _shutdownWriteResettableCompletionSource . Complete ( MsQuicStatusCodes . Success ) ;
626
+ _shutdownWriteCompletionSource . TrySetResult ( ) ;
627
627
}
628
628
629
629
return MsQuicStatusCodes . Success ;
@@ -646,9 +646,9 @@ private uint HandleEventShutdownComplete()
646
646
647
647
_readState = ReadState . ReadsCompleted ;
648
648
649
- if ( _shutdownState == ShutdownWriteState . None )
649
+ if ( _shutdownWriteState == ShutdownWriteState . None )
650
650
{
651
- _shutdownState = ShutdownWriteState . Finished ;
651
+ _shutdownWriteState = ShutdownWriteState . Finished ;
652
652
shouldShutdownWriteComplete = true ;
653
653
}
654
654
}
@@ -660,7 +660,7 @@ private uint HandleEventShutdownComplete()
660
660
661
661
if ( shouldShutdownWriteComplete )
662
662
{
663
- _shutdownWriteResettableCompletionSource . Complete ( MsQuicStatusCodes . Success ) ;
663
+ _shutdownWriteCompletionSource . TrySetResult ( ) ;
664
664
}
665
665
666
666
return MsQuicStatusCodes . Success ;
0 commit comments