// return value indicates sync vs async completion
        // false: sync completion
        // true: async completion
        private unsafe bool ReadAsyncFast(HttpListenerAsyncEventArgs eventArgs)
        {
            if (NetEventSource.IsEnabled)
            {
                NetEventSource.Enter(this);
            }

            eventArgs.StartOperationCommon(this, _inputStream.InternalHttpContext.RequestQueueBoundHandle);
            eventArgs.StartOperationReceive();

            uint statusCode = 0;
            bool completedAsynchronously = false;
            try
            {
                Debug.Assert(eventArgs.Buffer != null, "'BufferList' is not supported for read operations.");
                if (eventArgs.Count == 0 || _inputStream.Closed)
                {
                    eventArgs.FinishOperationSuccess(0, true);
                    return false;
                }

                uint dataRead = 0;
                int offset = eventArgs.Offset;
                int remainingCount = eventArgs.Count;

                if (_inputStream.BufferedDataChunksAvailable)
                {
                    dataRead = _inputStream.GetChunks(eventArgs.Buffer, eventArgs.Offset, eventArgs.Count);
                    if (_inputStream.BufferedDataChunksAvailable && dataRead == eventArgs.Count)
                    {
                        eventArgs.FinishOperationSuccess(eventArgs.Count, true);
                        return false;
                    }
                }

                Debug.Assert(!_inputStream.BufferedDataChunksAvailable, "'m_InputStream.BufferedDataChunksAvailable' MUST BE 'FALSE' at this point.");
                Debug.Assert(dataRead <= eventArgs.Count, "'dataRead' MUST NOT be bigger than 'eventArgs.Count'.");

                if (dataRead != 0)
                {
                    offset += (int)dataRead;
                    remainingCount -= (int)dataRead;
                    //the http.sys team recommends that we limit the size to 128kb
                    if (remainingCount > HttpRequestStream.MaxReadSize)
                    {
                        remainingCount = HttpRequestStream.MaxReadSize;
                    }

                    eventArgs.SetBuffer(eventArgs.Buffer, offset, remainingCount);
                }
                else if (remainingCount > HttpRequestStream.MaxReadSize)
                {
                    remainingCount = HttpRequestStream.MaxReadSize;
                    eventArgs.SetBuffer(eventArgs.Buffer, offset, remainingCount);
                }

                uint flags = 0;
                uint bytesReturned = 0;
                statusCode =
                    Interop.HttpApi.HttpReceiveRequestEntityBody(
                        _inputStream.InternalHttpContext.RequestQueueHandle,
                        _inputStream.InternalHttpContext.RequestId,
                        flags,
                        (byte*)_webSocket.InternalBuffer.ToIntPtr(eventArgs.Offset),
                        (uint)eventArgs.Count,
                        out bytesReturned,
                        eventArgs.NativeOverlapped);

                if (statusCode != Interop.HttpApi.ERROR_SUCCESS &&
                    statusCode != Interop.HttpApi.ERROR_IO_PENDING &&
                    statusCode != Interop.HttpApi.ERROR_HANDLE_EOF)
                {
                    throw new HttpListenerException((int)statusCode);
                }
                else if (statusCode == Interop.HttpApi.ERROR_SUCCESS &&
                    HttpListener.SkipIOCPCallbackOnSuccess)
                {
                    // IO operation completed synchronously. No IO completion port callback is used because 
                    // it was disabled in SwitchToOpaqueMode()
                    eventArgs.FinishOperationSuccess((int)bytesReturned, true);
                    completedAsynchronously = false;
                }
                else
                {
                    completedAsynchronously = true;
                }
            }
            catch (Exception e)
            {
                _readEventArgs.FinishOperationFailure(e, true);
                _outputStream.SetClosedFlag();
                _outputStream.InternalHttpContext.Abort();

                throw;
            }
            finally
            {
                if (NetEventSource.IsEnabled)
                {
                    NetEventSource.Exit(this, completedAsynchronously);
                }
            }

            return completedAsynchronously;
        }
        // return value indicates sync vs async completion
        // false: sync completion
        // true: async completion or error
        private unsafe bool ReadAsyncFast(HttpListenerAsyncEventArgs eventArgs)
        {
            eventArgs.StartOperationCommon(this, _inputStream.InternalHttpContext.RequestQueueBoundHandle);
            eventArgs.StartOperationReceive();

            bool completedAsynchronouslyOrWithError;

            try
            {
                Debug.Assert(eventArgs.Buffer != null, "'BufferList' is not supported for read operations.");
                if (eventArgs.Count == 0 || _inputStream.Closed)
                {
                    eventArgs.FinishOperationSuccess(0, true);
                    return(false);
                }

                uint dataRead       = 0;
                int  offset         = eventArgs.Offset;
                int  remainingCount = eventArgs.Count;

                if (_inputStream.BufferedDataChunksAvailable)
                {
                    dataRead = _inputStream.GetChunks(eventArgs.Buffer, eventArgs.Offset, eventArgs.Count);
                    if (_inputStream.BufferedDataChunksAvailable && dataRead == eventArgs.Count)
                    {
                        eventArgs.FinishOperationSuccess(eventArgs.Count, true);
                        return(false);
                    }
                }

                Debug.Assert(!_inputStream.BufferedDataChunksAvailable, "'m_InputStream.BufferedDataChunksAvailable' MUST BE 'FALSE' at this point.");
                Debug.Assert(dataRead <= eventArgs.Count, "'dataRead' MUST NOT be bigger than 'eventArgs.Count'.");

                if (dataRead != 0)
                {
                    offset         += (int)dataRead;
                    remainingCount -= (int)dataRead;
                    //the http.sys team recommends that we limit the size to 128kb
                    if (remainingCount > HttpRequestStream.MaxReadSize)
                    {
                        remainingCount = HttpRequestStream.MaxReadSize;
                    }

                    eventArgs.SetBuffer(eventArgs.Buffer, offset, remainingCount);
                }
                else if (remainingCount > HttpRequestStream.MaxReadSize)
                {
                    remainingCount = HttpRequestStream.MaxReadSize;
                    eventArgs.SetBuffer(eventArgs.Buffer, offset, remainingCount);
                }

                uint flags         = 0;
                uint bytesReturned = 0;
                uint statusCode    =
                    Interop.HttpApi.HttpReceiveRequestEntityBody(
                        _inputStream.InternalHttpContext.RequestQueueHandle,
                        _inputStream.InternalHttpContext.RequestId,
                        flags,
                        (byte *)_webSocket !.InternalBuffer.ToIntPtr(eventArgs.Offset),
                        (uint)eventArgs.Count,
                        out bytesReturned,
                        eventArgs.NativeOverlapped);

                if (statusCode != Interop.HttpApi.ERROR_SUCCESS &&
                    statusCode != Interop.HttpApi.ERROR_IO_PENDING &&
                    statusCode != Interop.HttpApi.ERROR_HANDLE_EOF)
                {
                    throw new HttpListenerException((int)statusCode);
                }
                else if (statusCode == Interop.HttpApi.ERROR_SUCCESS &&
                         HttpListener.SkipIOCPCallbackOnSuccess)
                {
                    // IO operation completed synchronously. No IO completion port callback is used because
                    // it was disabled in SwitchToOpaqueMode()
                    eventArgs.FinishOperationSuccess((int)bytesReturned, true);
                    completedAsynchronouslyOrWithError = false;
                }
                else if (statusCode == Interop.HttpApi.ERROR_HANDLE_EOF)
                {
                    eventArgs.FinishOperationSuccess(0, true);
                    completedAsynchronouslyOrWithError = false;
                }
                else
                {
                    completedAsynchronouslyOrWithError = true;
                }
            }
            catch (Exception e)
            {
                _readEventArgs !.FinishOperationFailure(e, true);
                _outputStream.SetClosedFlag();
                _outputStream.InternalHttpContext.Abort();

                completedAsynchronouslyOrWithError = true;
            }

            return(completedAsynchronouslyOrWithError);
        }
        // return value indicates [....] vs async completion
        // false: [....] completion
        // true: async completion
        private unsafe bool ReadAsyncFast(HttpListenerAsyncEventArgs eventArgs)
        {
            if (WebSocketBase.LoggingEnabled)
            {
                Logging.Enter(Logging.WebSockets, this, Methods.ReadAsyncFast, string.Empty);
            }

            eventArgs.StartOperationCommon(this);
            eventArgs.StartOperationReceive();

            uint statusCode = 0;
            bool completedAsynchronously = false;

            try
            {
                Contract.Assert(eventArgs.Buffer != null, "'BufferList' is not supported for read operations.");
                if (eventArgs.Count == 0 || m_InputStream.Closed)
                {
                    eventArgs.FinishOperationSuccess(0, true);
                    return(false);
                }

                uint dataRead       = 0;
                int  offset         = eventArgs.Offset;
                int  remainingCount = eventArgs.Count;

                if (m_InputStream.BufferedDataChunksAvailable)
                {
                    dataRead = m_InputStream.GetChunks(eventArgs.Buffer, eventArgs.Offset, eventArgs.Count);
                    if (m_InputStream.BufferedDataChunksAvailable && dataRead == eventArgs.Count)
                    {
                        eventArgs.FinishOperationSuccess(eventArgs.Count, true);
                        return(false);
                    }
                }

                Contract.Assert(!m_InputStream.BufferedDataChunksAvailable, "'m_InputStream.BufferedDataChunksAvailable' MUST BE 'FALSE' at this point.");
                Contract.Assert(dataRead <= eventArgs.Count, "'dataRead' MUST NOT be bigger than 'eventArgs.Count'.");

                if (dataRead != 0)
                {
                    offset         += (int)dataRead;
                    remainingCount -= (int)dataRead;
                    //the http.sys team recommends that we limit the size to 128kb
                    if (remainingCount > HttpRequestStream.MaxReadSize)
                    {
                        remainingCount = HttpRequestStream.MaxReadSize;
                    }

                    eventArgs.SetBuffer(eventArgs.Buffer, offset, remainingCount);
                }
                else if (remainingCount > HttpRequestStream.MaxReadSize)
                {
                    remainingCount = HttpRequestStream.MaxReadSize;
                    eventArgs.SetBuffer(eventArgs.Buffer, offset, remainingCount);
                }

                m_InputStream.InternalHttpContext.EnsureBoundHandle();
                uint flags         = 0;
                uint bytesReturned = 0;
                statusCode =
                    UnsafeNclNativeMethods.HttpApi.HttpReceiveRequestEntityBody2(
                        m_InputStream.InternalHttpContext.RequestQueueHandle,
                        m_InputStream.InternalHttpContext.RequestId,
                        flags,
                        (byte *)m_WebSocket.InternalBuffer.ToIntPtr(eventArgs.Offset),
                        (uint)eventArgs.Count,
                        out bytesReturned,
                        eventArgs.NativeOverlapped);

                if (statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS &&
                    statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_IO_PENDING &&
                    statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_HANDLE_EOF)
                {
                    throw new HttpListenerException((int)statusCode);
                }
                else if (statusCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS &&
                         HttpListener.SkipIOCPCallbackOnSuccess)
                {
                    // IO operation completed synchronously. No IO completion port callback is used because
                    // it was disabled in SwitchToOpaqueMode()
                    eventArgs.FinishOperationSuccess((int)bytesReturned, true);
                    completedAsynchronously = false;
                }
                else
                {
                    completedAsynchronously = true;
                }
            }
            catch (Exception e)
            {
                m_ReadEventArgs.FinishOperationFailure(e, true);
                m_OutputStream.SetClosedFlag();
                m_OutputStream.InternalHttpContext.Abort();

                throw;
            }
            finally
            {
                if (WebSocketBase.LoggingEnabled)
                {
                    Logging.Exit(Logging.WebSockets, this, Methods.ReadAsyncFast, completedAsynchronously);
                }
            }

            return(completedAsynchronously);
        }