internal IAsyncResult BeginWrite(BufferOffsetSize[] buffers, AsyncCallback asyncCallback, object asyncState) { LazyAsyncResult userAsyncResult = new LazyAsyncResult(this, asyncState, asyncCallback); SplitWriteAsyncProtocolRequest asyncRequest = new SplitWriteAsyncProtocolRequest(userAsyncResult); this.ProcessWrite(buffers, asyncRequest); return userAsyncResult; }
// // Assuming InnerStream type == typeof(NetworkStream) // private static void MulitpleWriteCallback(IAsyncResult transportResult) { if (transportResult.CompletedSynchronously) { return; } GlobalLog.Assert(transportResult.AsyncState is AsyncProtocolRequest, "SslStream::MulitpleWriteCallback|State type is wrong, expected AsyncProtocolRequest."); SplitWriteAsyncProtocolRequest asyncRequest = (SplitWriteAsyncProtocolRequest)transportResult.AsyncState; _SslStream sslStream = (_SslStream)asyncRequest.AsyncObject; try { ((NetworkStream)(sslStream._SslState.InnerStream)).EndMultipleWrite(transportResult); sslStream._SslState.FinishWrite(); sslStream.StartWriting(asyncRequest.SplitWritesState, asyncRequest); } catch (Exception e) { if (asyncRequest.IsUserCompleted) { // This will throw on a worker thread. throw; } sslStream._SslState.FinishWrite(); asyncRequest.CompleteWithError(e); } }
// // Assumes that InnerStream type == typeof(NetworkStream) // internal IAsyncResult BeginWrite(BufferOffsetSize[] buffers, AsyncCallback asyncCallback, object asyncState) { LazyAsyncResult lazyResult = new LazyAsyncResult(this, asyncState, asyncCallback); SplitWriteAsyncProtocolRequest asyncRequest = new SplitWriteAsyncProtocolRequest(lazyResult); ProcessWrite(buffers, asyncRequest); return(lazyResult); }
// // This method assumes that InnerStream type == typeof(NetwokrStream) // It will produce a set of buffers for one MultipleWrite call // private void StartWriting(SplitWritesState splitWrite, SplitWriteAsyncProtocolRequest asyncRequest) { while (!splitWrite.IsDone) { // request a write IO slot if (_SslState.CheckEnqueueWrite(asyncRequest)) { // operation is async and has been queued, return. return; } byte[] lastHandshakePayload = null; if (_SslState.LastPayload != null) { // // !!! LastPayload Only used in TlsStream for HTTP and it needs re-work for a general case !!! // lastHandshakePayload = _SslState.LastPayload; _SslState.LastPayloadConsumed(); } BufferOffsetSize[] buffers = splitWrite.GetNextBuffers(); buffers = EncryptBuffers(buffers, lastHandshakePayload); if (asyncRequest != null) { // prepare for the next request IAsyncResult ar = ((NetworkStream)(_SslState.InnerStream)).BeginMultipleWrite(buffers, _MulitpleWriteCallback, asyncRequest); if (!ar.CompletedSynchronously) { return; } ((NetworkStream)(_SslState.InnerStream)).EndMultipleWrite(ar); } else { ((NetworkStream)(_SslState.InnerStream)).MultipleWrite(buffers); } // release write IO slot _SslState.FinishWrite(); } if (asyncRequest != null) { asyncRequest.CompleteUser(); } }
// // Combined sync/async write method. For sync case asyncRequest==null // private void ProcessWrite(BufferOffsetSize[] buffers, SplitWriteAsyncProtocolRequest asyncRequest) { _SslState.CheckThrow(authSuccessCheck: true, shutdownCheck: true); foreach (BufferOffsetSize buffer in buffers) { ValidateParameters(buffer.Buffer, buffer.Offset, buffer.Size); } if (Interlocked.Exchange(ref _NestedWrite, 1) == 1) { throw new NotSupportedException(SR.GetString(SR.net_io_invalidnestedcall, (asyncRequest != null? "BeginWrite":"Write"), "write")); } bool failed = false; try { SplitWritesState splitWrite = new SplitWritesState(buffers); if (asyncRequest != null) { asyncRequest.SetNextRequest(splitWrite, _ResumeAsyncWriteCallback); } StartWriting(splitWrite, asyncRequest); } catch (Exception e) { _SslState.FinishWrite(); failed = true; if (e is IOException) { throw; } throw new IOException(SR.GetString(SR.net_io_write), e); } finally { if (asyncRequest == null || failed) { _NestedWrite = 0; } } }
private void ProcessWrite(BufferOffsetSize[] buffers, SplitWriteAsyncProtocolRequest asyncRequest) { foreach (BufferOffsetSize size in buffers) { this.ValidateParameters(size.Buffer, size.Offset, size.Size); } if (Interlocked.Exchange(ref this._NestedWrite, 1) == 1) { throw new NotSupportedException(SR.GetString("net_io_invalidnestedcall", new object[] { (asyncRequest != null) ? "BeginWrite" : "Write", "write" })); } bool flag = false; try { SplitWritesState splitWritesState = new SplitWritesState(buffers); if (asyncRequest != null) { asyncRequest.SetNextRequest(splitWritesState, _ResumeAsyncWriteCallback); } this.StartWriting(splitWritesState, asyncRequest); } catch (Exception exception) { this._SslState.FinishWrite(); flag = true; if (exception is IOException) { throw; } throw new IOException(SR.GetString("net_io_write"), exception); } finally { if ((asyncRequest == null) || flag) { this._NestedWrite = 0; } } }
// // This is used in a rare situation when async Write is resumed from completed handshake // private static void ResumeAsyncWriteCallback(AsyncProtocolRequest asyncRequest) { try { SplitWriteAsyncProtocolRequest splitWriteRequest = asyncRequest as SplitWriteAsyncProtocolRequest; if (splitWriteRequest != null) { ((_SslStream)asyncRequest.AsyncObject).StartWriting(splitWriteRequest.SplitWritesState, splitWriteRequest); } else { ((_SslStream)asyncRequest.AsyncObject).StartWriting(asyncRequest.Buffer, asyncRequest.Offset, asyncRequest.Count, asyncRequest); } } catch (Exception e) { if (asyncRequest.IsUserCompleted) { // This will throw on a worker thread. throw; } ((_SslStream)asyncRequest.AsyncObject)._SslState.FinishWrite(); asyncRequest.CompleteWithError(e); } }
private static void MulitpleWriteCallback(IAsyncResult transportResult) { if (!transportResult.CompletedSynchronously) { SplitWriteAsyncProtocolRequest asyncState = (SplitWriteAsyncProtocolRequest)transportResult.AsyncState; _SslStream asyncObject = (_SslStream)asyncState.AsyncObject; try { ((NetworkStream)asyncObject._SslState.InnerStream).EndMultipleWrite(transportResult); asyncObject._SslState.FinishWrite(); asyncObject.StartWriting(asyncState.SplitWritesState, asyncState); } catch (Exception exception) { if (asyncState.IsUserCompleted) { throw; } asyncObject._SslState.FinishWrite(); asyncState.CompleteWithError(exception); } } }
private void StartWriting(SplitWritesState splitWrite, SplitWriteAsyncProtocolRequest asyncRequest) { while (!splitWrite.IsDone) { if (this._SslState.CheckEnqueueWrite(asyncRequest)) { return; } byte[] lastHandshakePayload = null; if (this._SslState.LastPayload != null) { lastHandshakePayload = this._SslState.LastPayload; this._SslState.LastPayloadConsumed(); } BufferOffsetSize[] nextBuffers = splitWrite.GetNextBuffers(); nextBuffers = this.EncryptBuffers(nextBuffers, lastHandshakePayload); if (asyncRequest != null) { IAsyncResult asyncResult = ((NetworkStream)this._SslState.InnerStream).BeginMultipleWrite(nextBuffers, _MulitpleWriteCallback, asyncRequest); if (!asyncResult.CompletedSynchronously) { return; } ((NetworkStream)this._SslState.InnerStream).EndMultipleWrite(asyncResult); } else { ((NetworkStream)this._SslState.InnerStream).MultipleWrite(nextBuffers); } this._SslState.FinishWrite(); } if (asyncRequest != null) { asyncRequest.CompleteUser(); } }
// // This method assumes that InnerStream type == typeof(NetwokrStream) // It will produce a set of buffers for one MultipleWrite call // private void StartWriting(SplitWritesState splitWrite, SplitWriteAsyncProtocolRequest asyncRequest) { while (!splitWrite.IsDone) { // request a write IO slot if (_SslState.CheckEnqueueWrite(asyncRequest)) { // operation is async and has been queued, return. return; } byte[] lastHandshakePayload = null; if (_SslState.LastPayload != null) { // // !!! LastPayload Only used in TlsStream for HTTP and it needs re-work for a general case !!! // lastHandshakePayload = _SslState.LastPayload; _SslState.LastPayloadConsumed(); } BufferOffsetSize[] buffers = splitWrite.GetNextBuffers(); buffers = EncryptBuffers(buffers, lastHandshakePayload); if (asyncRequest != null) { // prepare for the next request IAsyncResult ar = ((NetworkStream)(_SslState.InnerStream)).BeginMultipleWrite(buffers, _MulitpleWriteCallback, asyncRequest); if (!ar.CompletedSynchronously) return; ((NetworkStream)(_SslState.InnerStream)).EndMultipleWrite(ar); } else { ((NetworkStream)(_SslState.InnerStream)).MultipleWrite(buffers); } // release write IO slot _SslState.FinishWrite(); } if (asyncRequest != null) asyncRequest.CompleteUser(); }
// // Combined [....]/async write method. For [....] case asyncRequest==null // private void ProcessWrite(BufferOffsetSize[] buffers, SplitWriteAsyncProtocolRequest asyncRequest) { foreach (BufferOffsetSize buffer in buffers) { ValidateParameters(buffer.Buffer, buffer.Offset, buffer.Size); } if (Interlocked.Exchange(ref _NestedWrite, 1) == 1) { throw new NotSupportedException(SR.GetString(SR.net_io_invalidnestedcall, (asyncRequest != null? "BeginWrite":"Write"), "write")); } bool failed = false; try { SplitWritesState splitWrite = new SplitWritesState(buffers); if (asyncRequest != null) asyncRequest.SetNextRequest(splitWrite, _ResumeAsyncWriteCallback); StartWriting(splitWrite, asyncRequest); } catch (Exception e) { _SslState.FinishWrite(); failed = true; if (e is IOException) { throw; } throw new IOException(SR.GetString(SR.net_io_write), e); } finally { if (asyncRequest == null || failed) { _NestedWrite = 0; } } }
private void StartWriting(SplitWritesState splitWrite, SplitWriteAsyncProtocolRequest asyncRequest) { while (!splitWrite.IsDone) { if (this._SslState.CheckEnqueueWrite(asyncRequest)) { return; } byte[] lastHandshakePayload = null; if (this._SslState.LastPayload != null) { lastHandshakePayload = this._SslState.LastPayload; this._SslState.LastPayloadConsumed(); } BufferOffsetSize[] nextBuffers = splitWrite.GetNextBuffers(); nextBuffers = this.EncryptBuffers(nextBuffers, lastHandshakePayload); if (asyncRequest != null) { IAsyncResult asyncResult = ((NetworkStream) this._SslState.InnerStream).BeginMultipleWrite(nextBuffers, _MulitpleWriteCallback, asyncRequest); if (!asyncResult.CompletedSynchronously) { return; } ((NetworkStream) this._SslState.InnerStream).EndMultipleWrite(asyncResult); } else { ((NetworkStream) this._SslState.InnerStream).MultipleWrite(nextBuffers); } this._SslState.FinishWrite(); } if (asyncRequest != null) { asyncRequest.CompleteUser(); } }