System.Net.Security.SslState.CheckEnqueueWrite C# (CSharp) Method

CheckEnqueueWrite() private method

private CheckEnqueueWrite ( AsyncProtocolRequest asyncRequest ) : bool
asyncRequest AsyncProtocolRequest
return bool
        internal bool CheckEnqueueWrite(AsyncProtocolRequest asyncRequest)
        {
            // Clear previous request.
            _queuedWriteStateRequest = null;
            int lockState = Interlocked.CompareExchange(ref _lockWriteState, LockWrite, LockNone);
            if (lockState != LockHandshake)
            {
                // Proceed with write.
                return false;
            }

            LazyAsyncResult lazyResult = null;
            lock (this)
            {
                if (_lockWriteState != LockHandshake)
                {
                    // Handshake has completed before we grabbed the lock.
                    CheckThrow(true);
                    return false;
                }

                _lockWriteState = LockPendingWrite;

                // Still pending, wait or enqueue.
                if (asyncRequest != null)
                {
                    _queuedWriteStateRequest = asyncRequest;
                    return true;
                }

                lazyResult = new LazyAsyncResult(null, null, /*must be */null);
                _queuedWriteStateRequest = lazyResult;
            }

            // Need to exit from lock before waiting.
            lazyResult.InternalWaitForCompletion();
            CheckThrow(true);
            return false;
        }

Usage Example

Example #1
0
        private void StartWriting(byte[] buffer, int offset, int count, AsyncProtocolRequest asyncRequest)
        {
            if (asyncRequest != null)
            {
                asyncRequest.SetNextRequest(buffer, offset, count, s_resumeAsyncWriteCallback);
            }

            // 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.StartWriting Trying Pinnable", this.GetHashCode(), count, PinnableBufferCacheEventSource.AddressOfByteArray(outBuffer));
                    }
                }
                else
                {
                    if (PinnableBufferCacheEventSource.Log.IsEnabled())
                    {
                        PinnableBufferCacheEventSource.Log.DebugMessage2("In System.Net._SslStream.StartWriting 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;
                    }

                    // Request a write IO slot.
                    if (_sslState.CheckEnqueueWrite(asyncRequest))
                    {
                        // Operation is async and has been queued, return.
                        return;
                    }

                    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.StartWriting Got Encrypted Buffer",
                                                                         this.GetHashCode(), encryptedBytes, PinnableBufferCacheEventSource.AddressOfByteArray(outBuffer));
                    }

                    if (asyncRequest != null)
                    {
                        // Prepare for the next request.
                        asyncRequest.SetNextRequest(buffer, offset + chunkBytes, count - chunkBytes, s_resumeAsyncWriteCallback);
                        Task t = _sslState.InnerStream.WriteAsync(outBuffer, 0, encryptedBytes);
                        if (t.IsCompleted)
                        {
                            t.GetAwaiter().GetResult();
                        }
                        else
                        {
                            IAsyncResult ar = TaskToApm.Begin(t, s_writeCallback, asyncRequest);
                            if (!ar.CompletedSynchronously)
                            {
                                return;
                            }
                            TaskToApm.End(ar);
                        }
                    }
                    else
                    {
                        _sslState.InnerStream.Write(outBuffer, 0, encryptedBytes);
                    }

                    offset += chunkBytes;
                    count  -= chunkBytes;

                    // Release write IO slot.
                    _sslState.FinishWrite();
                } while (count != 0);
            }

            if (asyncRequest != null)
            {
                asyncRequest.CompleteUser();
            }

            if (buffer == _pinnableOutputBufferInUse)
            {
                _pinnableOutputBufferInUse = null;
                if (PinnableBufferCacheEventSource.Log.IsEnabled())
                {
                    PinnableBufferCacheEventSource.Log.DebugMessage1("In System.Net._SslStream.StartWriting Freeing buffer.", this.GetHashCode());
                }
            }
        }
All Usage Examples Of System.Net.Security.SslState::CheckEnqueueWrite