Sync shared code from runtime (#24845)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
This commit is contained in:
github-actions[bot] 2020-08-13 03:08:49 +00:00 committed by GitHub
parent 93cfbe46fd
commit da6aa6fc6a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 30 additions and 26 deletions

View File

@ -56,7 +56,7 @@ namespace System.Net.Quic.Implementations.MsQuic.Internal
QuicExceptionHelpers.ThrowIfFailed(MsQuicApi.Api.ListenerOpenDelegate( QuicExceptionHelpers.ThrowIfFailed(MsQuicApi.Api.ListenerOpenDelegate(
_nativeObjPtr, _nativeObjPtr,
MsQuicListener.NativeCallbackHandler, MsQuicListener.s_listenerDelegate,
IntPtr.Zero, IntPtr.Zero,
out IntPtr listenerPointer), out IntPtr listenerPointer),
"Could not open listener."); "Could not open listener.");

View File

@ -37,8 +37,8 @@ namespace System.Net.Quic.Implementations.MsQuic
private SslApplicationProtocol _negotiatedAlpnProtocol; private SslApplicationProtocol _negotiatedAlpnProtocol;
// TODO: only allocate these when there is an outstanding connect/shutdown. // TODO: only allocate these when there is an outstanding connect/shutdown.
private readonly TaskCompletionSource<uint> _connectTcs = new TaskCompletionSource<uint>(); private readonly TaskCompletionSource<uint> _connectTcs = new TaskCompletionSource<uint>(TaskCreationOptions.RunContinuationsAsynchronously);
private readonly TaskCompletionSource<uint> _shutdownTcs = new TaskCompletionSource<uint>(); private readonly TaskCompletionSource<uint> _shutdownTcs = new TaskCompletionSource<uint>(TaskCreationOptions.RunContinuationsAsynchronously);
private bool _disposed; private bool _disposed;
private bool _connected; private bool _connected;
@ -291,6 +291,8 @@ namespace System.Net.Quic.Implementations.MsQuic
ErrorCode); ErrorCode);
QuicExceptionHelpers.ThrowIfFailed(status, "Failed to shutdown connection."); QuicExceptionHelpers.ThrowIfFailed(status, "Failed to shutdown connection.");
Debug.Assert(_shutdownTcs.Task.IsCompleted == false);
return new ValueTask(_shutdownTcs.Task); return new ValueTask(_shutdownTcs.Task);
} }
@ -349,6 +351,8 @@ namespace System.Net.Quic.Implementations.MsQuic
_disposed = true; _disposed = true;
} }
// TODO: this appears abortive and will cause prior successfully shutdown and closed streams to drop data.
// It's unclear how to gracefully wait for a connection to be 100% done.
internal override ValueTask CloseAsync(long errorCode, CancellationToken cancellationToken = default) internal override ValueTask CloseAsync(long errorCode, CancellationToken cancellationToken = default)
{ {
ThrowIfDisposed(); ThrowIfDisposed();

View File

@ -26,7 +26,7 @@ namespace System.Net.Quic.Implementations.MsQuic
private GCHandle _handle; private GCHandle _handle;
// Delegate that wraps the static function that will be called when receiving an event. // Delegate that wraps the static function that will be called when receiving an event.
private static readonly ListenerCallbackDelegate s_listenerDelegate = new ListenerCallbackDelegate(NativeCallbackHandler); internal static readonly ListenerCallbackDelegate s_listenerDelegate = new ListenerCallbackDelegate(NativeCallbackHandler);
// Ssl listening options (ALPN, cert, etc) // Ssl listening options (ALPN, cert, etc)
private readonly SslServerAuthenticationOptions _sslOptions; private readonly SslServerAuthenticationOptions _sslOptions;
@ -189,7 +189,7 @@ namespace System.Net.Quic.Implementations.MsQuic
_acceptConnectionQueue.Writer.TryComplete(); _acceptConnectionQueue.Writer.TryComplete();
} }
internal static uint NativeCallbackHandler( private static uint NativeCallbackHandler(
IntPtr listener, IntPtr listener,
IntPtr context, IntPtr context,
ref ListenerEvent connectionEventStruct) ref ListenerEvent connectionEventStruct)

View File

@ -34,7 +34,8 @@ namespace System.Net.Quic.Implementations.MsQuic
// Resettable completions to be used for multiple calls to receive. // Resettable completions to be used for multiple calls to receive.
private readonly ResettableCompletionSource<uint> _receiveResettableCompletionSource; private readonly ResettableCompletionSource<uint> _receiveResettableCompletionSource;
private readonly ResettableCompletionSource<uint> _shutdownWriteResettableCompletionSource; // Set once writes have been shutdown.
private readonly TaskCompletionSource _shutdownWriteCompletionSource = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
// Buffers to hold during a call to send. // Buffers to hold during a call to send.
private MemoryHandle[] _bufferArrays = new MemoryHandle[1]; private MemoryHandle[] _bufferArrays = new MemoryHandle[1];
@ -49,7 +50,7 @@ namespace System.Net.Quic.Implementations.MsQuic
private ReadState _readState; private ReadState _readState;
private long _readErrorCode = -1; private long _readErrorCode = -1;
private ShutdownWriteState _shutdownState; private ShutdownWriteState _shutdownWriteState;
private SendState _sendState; private SendState _sendState;
private long _sendErrorCode = -1; private long _sendErrorCode = -1;
@ -76,7 +77,6 @@ namespace System.Net.Quic.Implementations.MsQuic
_sendResettableCompletionSource = new ResettableCompletionSource<uint>(); _sendResettableCompletionSource = new ResettableCompletionSource<uint>();
_receiveResettableCompletionSource = new ResettableCompletionSource<uint>(); _receiveResettableCompletionSource = new ResettableCompletionSource<uint>();
_shutdownWriteResettableCompletionSource = new ResettableCompletionSource<uint>();
SetCallbackHandler(); SetCallbackHandler();
bool isBidirectional = !flags.HasFlag(QUIC_STREAM_OPEN_FLAG.UNIDIRECTIONAL); bool isBidirectional = !flags.HasFlag(QUIC_STREAM_OPEN_FLAG.UNIDIRECTIONAL);
@ -323,16 +323,16 @@ namespace System.Net.Quic.Implementations.MsQuic
lock (_sync) lock (_sync)
{ {
if (_shutdownState == ShutdownWriteState.None) if (_shutdownWriteState == ShutdownWriteState.None)
{ {
_shutdownState = ShutdownWriteState.Canceled; _shutdownWriteState = ShutdownWriteState.Canceled;
shouldComplete = true; shouldComplete = true;
} }
} }
if (shouldComplete) if (shouldComplete)
{ {
_shutdownWriteResettableCompletionSource.CompleteException(new QuicStreamAbortedException("Shutdown was aborted.", errorCode)); _shutdownWriteCompletionSource.SetException(new QuicStreamAbortedException("Shutdown was aborted.", errorCode));
} }
MsQuicApi.Api.StreamShutdownDelegate(_ptr, (uint)QUIC_STREAM_SHUTDOWN_FLAG.ABORT_SEND, errorCode); MsQuicApi.Api.StreamShutdownDelegate(_ptr, (uint)QUIC_STREAM_SHUTDOWN_FLAG.ABORT_SEND, errorCode);
@ -348,20 +348,20 @@ namespace System.Net.Quic.Implementations.MsQuic
bool shouldComplete = false; bool shouldComplete = false;
lock (_sync) lock (_sync)
{ {
if (_shutdownState == ShutdownWriteState.None) if (_shutdownWriteState == ShutdownWriteState.None)
{ {
_shutdownState = ShutdownWriteState.Canceled; _shutdownWriteState = ShutdownWriteState.Canceled;
shouldComplete = true; shouldComplete = true;
} }
} }
if (shouldComplete) if (shouldComplete)
{ {
_shutdownWriteResettableCompletionSource.CompleteException(new OperationCanceledException("Shutdown was canceled", cancellationToken)); _shutdownWriteCompletionSource.SetException(new OperationCanceledException("Shutdown was canceled", cancellationToken));
} }
}); });
return _shutdownWriteResettableCompletionSource.GetTypelessValueTask(); return new ValueTask(_shutdownWriteCompletionSource.Task);
} }
internal override void Shutdown() internal override void Shutdown()
@ -408,8 +408,6 @@ namespace System.Net.Quic.Implementations.MsQuic
return default; return default;
} }
CleanupSendState();
if (_ptr != IntPtr.Zero) if (_ptr != IntPtr.Zero)
{ {
// TODO resolve graceful vs abortive dispose here. Will file a separate issue. // TODO resolve graceful vs abortive dispose here. Will file a separate issue.
@ -419,6 +417,8 @@ namespace System.Net.Quic.Implementations.MsQuic
_handle.Free(); _handle.Free();
CleanupSendState();
_disposed = true; _disposed = true;
return default; return default;
@ -442,8 +442,6 @@ namespace System.Net.Quic.Implementations.MsQuic
return; return;
} }
CleanupSendState();
if (_ptr != IntPtr.Zero) if (_ptr != IntPtr.Zero)
{ {
// TODO resolve graceful vs abortive dispose here. Will file a separate issue. // TODO resolve graceful vs abortive dispose here. Will file a separate issue.
@ -453,6 +451,8 @@ namespace System.Net.Quic.Implementations.MsQuic
_handle.Free(); _handle.Free();
CleanupSendState();
_disposed = true; _disposed = true;
} }
@ -461,7 +461,7 @@ namespace System.Net.Quic.Implementations.MsQuic
MsQuicApi.Api.StreamReceiveSetEnabledDelegate(_ptr, enabled: true); MsQuicApi.Api.StreamReceiveSetEnabledDelegate(_ptr, enabled: true);
} }
internal static uint NativeCallbackHandler( private static uint NativeCallbackHandler(
IntPtr stream, IntPtr stream,
IntPtr context, IntPtr context,
ref StreamEvent streamEvent) ref StreamEvent streamEvent)
@ -614,16 +614,16 @@ namespace System.Net.Quic.Implementations.MsQuic
bool shouldComplete = false; bool shouldComplete = false;
lock (_sync) lock (_sync)
{ {
if (_shutdownState == ShutdownWriteState.None) if (_shutdownWriteState == ShutdownWriteState.None)
{ {
_shutdownState = ShutdownWriteState.Finished; _shutdownWriteState = ShutdownWriteState.Finished;
shouldComplete = true; shouldComplete = true;
} }
} }
if (shouldComplete) if (shouldComplete)
{ {
_shutdownWriteResettableCompletionSource.Complete(MsQuicStatusCodes.Success); _shutdownWriteCompletionSource.TrySetResult();
} }
return MsQuicStatusCodes.Success; return MsQuicStatusCodes.Success;
@ -646,9 +646,9 @@ namespace System.Net.Quic.Implementations.MsQuic
_readState = ReadState.ReadsCompleted; _readState = ReadState.ReadsCompleted;
if (_shutdownState == ShutdownWriteState.None) if (_shutdownWriteState == ShutdownWriteState.None)
{ {
_shutdownState = ShutdownWriteState.Finished; _shutdownWriteState = ShutdownWriteState.Finished;
shouldShutdownWriteComplete = true; shouldShutdownWriteComplete = true;
} }
} }
@ -660,7 +660,7 @@ namespace System.Net.Quic.Implementations.MsQuic
if (shouldShutdownWriteComplete) if (shouldShutdownWriteComplete)
{ {
_shutdownWriteResettableCompletionSource.Complete(MsQuicStatusCodes.Success); _shutdownWriteCompletionSource.TrySetResult();
} }
return MsQuicStatusCodes.Success; return MsQuicStatusCodes.Success;