From 3b3d20de81f35392fd78a344eb9f7795d73f6bc2 Mon Sep 17 00:00:00 2001 From: Tomas Weinfurt Date: Sat, 26 Jun 2021 20:20:39 +0200 Subject: [PATCH] add pre-cancellation check and enable ReadWriteAsync_PrecanceledOperations_ThrowsCancellationException for QUIC (#54540) --- .../Quic/Implementations/MsQuic/MsQuicStream.cs | 27 ++++++++++++++++++++++ .../QuicStreamConnectedStreamConformanceTests.cs | 2 -- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicStream.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicStream.cs index e796496..a0fea55 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicStream.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicStream.cs @@ -215,6 +215,7 @@ namespace System.Net.Quic.Implementations.MsQuic internal override async ValueTask WriteAsync(ReadOnlyMemory buffer, bool endStream, CancellationToken cancellationToken = default) { ThrowIfDisposed(); + using CancellationTokenRegistration registration = await HandleWriteStartState(cancellationToken).ConfigureAwait(false); await SendReadOnlyMemoryAsync(buffer, endStream ? QUIC_SEND_FLAGS.FIN : QUIC_SEND_FLAGS.NONE).ConfigureAwait(false); @@ -229,6 +230,19 @@ namespace System.Net.Quic.Implementations.MsQuic throw new InvalidOperationException(SR.net_quic_writing_notallowed); } + if (cancellationToken.IsCancellationRequested) + { + lock (_state) + { + if (_state.SendState == SendState.None || _state.SendState == SendState.Pending) + { + _state.SendState = SendState.Aborted; + } + } + + throw new System.OperationCanceledException(cancellationToken); + } + // Make sure start has completed if (!_started) { @@ -304,6 +318,19 @@ namespace System.Net.Quic.Implementations.MsQuic throw new InvalidOperationException(SR.net_quic_reading_notallowed); } + if (cancellationToken.IsCancellationRequested) + { + lock (_state) + { + if (_state.ReadState == ReadState.None) + { + _state.ReadState = ReadState.Aborted; + } + } + + throw new System.OperationCanceledException(cancellationToken); + } + if (NetEventSource.Log.IsEnabled()) { NetEventSource.Info(_state, $"[Stream#{_state.GetHashCode()}] reading into Memory of '{destination.Length}' bytes."); diff --git a/src/libraries/System.Net.Quic/tests/FunctionalTests/QuicStreamConnectedStreamConformanceTests.cs b/src/libraries/System.Net.Quic/tests/FunctionalTests/QuicStreamConnectedStreamConformanceTests.cs index cd83662..908fdb3 100644 --- a/src/libraries/System.Net.Quic/tests/FunctionalTests/QuicStreamConnectedStreamConformanceTests.cs +++ b/src/libraries/System.Net.Quic/tests/FunctionalTests/QuicStreamConnectedStreamConformanceTests.cs @@ -40,8 +40,6 @@ namespace System.Net.Quic.Tests // TODO: new additions, find out the actual reason for hanging [ActiveIssue("https://github.com/dotnet/runtime/issues/49157")] - public override Task ReadWriteAsync_PrecanceledOperations_ThrowsCancellationException() => base.ReadWriteAsync_PrecanceledOperations_ThrowsCancellationException(); - [ActiveIssue("https://github.com/dotnet/runtime/issues/49157")] public override Task Read_DataStoredAtDesiredOffset(ReadWriteMode mode) => base.Read_DataStoredAtDesiredOffset(mode); [ActiveIssue("https://github.com/dotnet/runtime/issues/49157")] public override Task ReadAsync_DuringReadAsync_ThrowsIfUnsupported() => base.ReadAsync_DuringReadAsync_ThrowsIfUnsupported(); -- 2.7.4