From 5d4111f505152b607198dcc8a529998d3655452c Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Wed, 4 Jan 2017 09:56:58 -0500 Subject: [PATCH] Revert "SslStream WriteAsync" This reverts commit dotnet/corefx@6031c507a0ea912ede85ca9fc3b8afc9a0fe70f0. Commit migrated from https://github.com/dotnet/corefx/commit/64e0db74f9ba3fecb8e95f4149298e0355e065ce --- .../ref/System.Net.Security.cs | 1 - .../src/System/Net/Security/SslStream.cs | 5 - .../System/Net/Security/SslStreamInternal.cs | 162 ++---------------- 3 files changed, 11 insertions(+), 157 deletions(-) diff --git a/src/libraries/System.Net.Security/ref/System.Net.Security.cs b/src/libraries/System.Net.Security/ref/System.Net.Security.cs index aea8fb45bfe..17891ac318e 100644 --- a/src/libraries/System.Net.Security/ref/System.Net.Security.cs +++ b/src/libraries/System.Net.Security/ref/System.Net.Security.cs @@ -176,7 +176,6 @@ public partial class SslStream : AuthenticatedStream #endif public void Write(byte[] buffer) { } public override void Write(byte[] buffer, int offset, int count) { } - public override System.Threading.Tasks.Task WriteAsync(byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken) { throw null; } } } namespace System.Security.Authentication diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.cs index 8457125c01f..0f55e769b88 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.cs @@ -527,11 +527,6 @@ public override void Write(byte[] buffer, int offset, int count) _sslState.SecureStream.Write(buffer, offset, count); } - public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) - { - return _sslState.SecureStream.WriteAsync(buffer, offset, count, cancellationToken); - } - public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback asyncCallback, object asyncState) { return _sslState.SecureStream.BeginRead(buffer, offset, count, asyncCallback, asyncState); diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamInternal.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamInternal.cs index c946a2ea350..a0fe031f784 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamInternal.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamInternal.cs @@ -5,7 +5,6 @@ using System.Diagnostics; using System.IO; using System.Threading; -using System.Threading.Tasks; namespace System.Net.Security { @@ -31,8 +30,6 @@ internal class SslStreamInternal private AsyncProtocolRequest _readProtocolRequest; // cached, reusable AsyncProtocolRequest used for read operations private AsyncProtocolRequest _writeProtocolRequest; // cached, reusable AsyncProtocolRequest used for write operations - private SemaphoreSlim _asyncWriteActiveSemaphore; - // Never updated directly, special properties are used. This is the read buffer. private byte[] _internalBuffer; private bool _internalBufferFromPinnableCache; @@ -56,13 +53,6 @@ internal SslStreamInternal(SslState sslState) _reader = new FixedSizeReader(_sslState.InnerStream); } - internal SemaphoreSlim EnsureAsyncActiveWriteSemaphoreInitialized() - { - // Lazily-initialize _asyncWriteActiveSemaphore. As we're never accessing the SemaphoreSlim's - // WaitHandle, we don't need to worry about Disposing it. - return LazyInitializer.EnsureInitialized(ref _asyncWriteActiveSemaphore, () => new SemaphoreSlim(1, 1)); - } - // If we have a read buffer from the pinnable cache, return it. private void FreeReadBuffer() { @@ -141,55 +131,6 @@ internal void Write(byte[] buffer, int offset, int count) ProcessWrite(buffer, offset, count, null); } - internal Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) - { - if (!_sslState.InnerStream.CanWrite) return Task.FromException(new NotSupportedException(SR.NotSupported_UnwritableStream)); - // If cancellation was requested, bail early with an already completed task. - // Otherwise, return a task that represents the Begin/End methods. - return cancellationToken.IsCancellationRequested - ? Task.FromCanceled(cancellationToken) - : WriteAsyncImpl(buffer, offset, count, cancellationToken); - } - - private async Task WriteAsyncImpl(byte[] buffer, int offset, int count, CancellationToken cancellationToken) - { - var semaphore = EnsureAsyncActiveWriteSemaphoreInitialized(); - await semaphore.WaitAsync(cancellationToken).ConfigureAwait(false); - - InitiateWrite(buffer, offset, count, null); - - bool failed = false; - try - { - await StartWritingAsync(buffer, offset, count, cancellationToken).ConfigureAwait(false); - - if (Interlocked.Exchange(ref _nestedWrite, 0) == 0) - { - throw new InvalidOperationException(SR.Format(SR.net_io_invalidendcall, "WriteAsyncImpl")); - } - } - catch (Exception e) - { - _sslState.FinishWrite(); - - failed = true; - if (e is IOException) - { - throw; - } - - throw new IOException(SR.net_io_write, e); - } - finally - { - semaphore.Release(); - if (failed) - { - _nestedWrite = 0; - } - } - } - internal IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback asyncCallback, object asyncState) { var bufferResult = new BufferAsyncResult(this, buffer, offset, count, asyncState, asyncCallback); @@ -404,7 +345,17 @@ private AsyncProtocolRequest GetOrCreateProtocolRequest(ref AsyncProtocolRequest // private void ProcessWrite(byte[] buffer, int offset, int count, LazyAsyncResult asyncResult) { - var asyncRequest = InitiateWrite(buffer, offset, count, asyncResult); + _sslState.CheckThrow(authSuccessCheck:true, shutdownCheck:true); + ValidateParameters(buffer, offset, count); + + if (Interlocked.Exchange(ref _nestedWrite, 1) == 1) + { + throw new NotSupportedException(SR.Format(SR.net_io_invalidnestedcall, "Write", "write")); + } + + // If this is an async operation, get the AsyncProtocolRequest to use. + // We do this only after we verify we're the sole write operation in flight. + AsyncProtocolRequest asyncRequest = GetOrCreateProtocolRequest(ref _writeProtocolRequest, asyncResult); bool failed = false; @@ -433,22 +384,6 @@ private void ProcessWrite(byte[] buffer, int offset, int count, LazyAsyncResult } } - private AsyncProtocolRequest InitiateWrite(byte[] buffer, int offset, int count, LazyAsyncResult asyncResult) - { - _sslState.CheckThrow(authSuccessCheck: true, shutdownCheck: true); - ValidateParameters(buffer, offset, count); - - if (Interlocked.Exchange(ref _nestedWrite, 1) == 1) - { - throw new NotSupportedException(SR.Format(SR.net_io_invalidnestedcall, "Write", "write")); - } - - // If this is an async operation, get the AsyncProtocolRequest to use. - // We do this only after we verify we're the sole write operation in flight. - AsyncProtocolRequest asyncRequest = GetOrCreateProtocolRequest(ref _writeProtocolRequest, asyncResult); - return asyncRequest; - } - private void StartWriting(byte[] buffer, int offset, int count, AsyncProtocolRequest asyncRequest) { if (asyncRequest != null) @@ -557,81 +492,6 @@ private void StartWriting(byte[] buffer, int offset, int count, AsyncProtocolReq } } - private async Task StartWritingAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) - { - // We loop to this method from the callback. - // If the last chunk was just completed from async callback (count < 0), we complete user request. - if (count >= 0 ) - { - byte[] outBuffer = null; - if (_pinnableOutputBufferInUse == null) - { - if (_pinnableOutputBuffer == null) - { - _pinnableOutputBuffer = s_PinnableWriteBufferCache.AllocateBuffer(); - } - - _pinnableOutputBufferInUse = buffer; - outBuffer = _pinnableOutputBuffer; - if (PinnableBufferCacheEventSource.Log.IsEnabled()) - { - PinnableBufferCacheEventSource.Log.DebugMessage3("In System.Net._SslStream.StartWritingAsync Trying Pinnable", this.GetHashCode(), count, PinnableBufferCacheEventSource.AddressOfByteArray(outBuffer)); - } - } - else - { - if (PinnableBufferCacheEventSource.Log.IsEnabled()) - { - PinnableBufferCacheEventSource.Log.DebugMessage2("In System.Net._SslStream.StartWritingAsync BufferInUse", this.GetHashCode(), count); - } - } - - do - { - if (count == 0 && !SslStreamPal.CanEncryptEmptyMessage) - { - // If it's an empty message and the PAL doesn't support that, - // we're done. - break; - } - - int chunkBytes = Math.Min(count, _sslState.MaxDataSize); - int encryptedBytes; - SecurityStatusPal status = _sslState.EncryptData(buffer, offset, chunkBytes, ref outBuffer, out encryptedBytes); - if (status.ErrorCode != SecurityStatusPalErrorCode.OK) - { - // Re-handshake status is not supported. - ProtocolToken message = new ProtocolToken(null, status); - throw new IOException(SR.net_io_encrypt, message.GetException()); - } - - if (PinnableBufferCacheEventSource.Log.IsEnabled()) - { - PinnableBufferCacheEventSource.Log.DebugMessage3("In System.Net._SslStream.StartWritingAsync Got Encrypted Buffer", - this.GetHashCode(), encryptedBytes, PinnableBufferCacheEventSource.AddressOfByteArray(outBuffer)); - } - - await _sslState.InnerStream.WriteAsync(outBuffer, 0, encryptedBytes, cancellationToken); - - offset += chunkBytes; - count -= chunkBytes; - - // Release write IO slot. - _sslState.FinishWrite(); - - } while (count != 0); - } - - if (buffer == _pinnableOutputBufferInUse) - { - _pinnableOutputBufferInUse = null; - if (PinnableBufferCacheEventSource.Log.IsEnabled()) - { - PinnableBufferCacheEventSource.Log.DebugMessage1("In System.Net._SslStream.StartWritingAsync Freeing buffer.", this.GetHashCode()); - } - } - } - // // Combined sync/async read method. For sync request asyncRequest==null. // -- GitLab