public override Task <int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
            {
                WebSocketHelpers.ValidateBuffer(buffer, offset, count);

                if (!m_InOpaqueMode)
                {
                    return(base.ReadAsync(buffer, offset, count, cancellationToken));
                }

                return(ReadAsyncCore(buffer, offset, count, cancellationToken, false));
            }
            public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
            {
                WebSocketHelpers.ValidateBuffer(buffer, offset, count);

                if (!m_InOpaqueMode)
                {
                    return(base.WriteAsync(buffer, offset, count, cancellationToken));
                }

                if (WebSocketBase.LoggingEnabled)
                {
                    Logging.Enter(Logging.WebSockets, this, Methods.WriteAsync,
                                  WebSocketHelpers.GetTraceMsgForParameters(offset, count, cancellationToken));
                }

                bool completedAsynchronously = false;

                try
                {
                    cancellationToken.ThrowIfCancellationRequested();
#if DEBUG
                    // When using fast path only one outstanding read is permitted. By switching into opaque mode
                    // via IWebSocketStream.SwitchToOpaqueMode (see more detailed comments in interface definition)
                    // caller takes responsibility for enforcing this constraint.
                    Contract.Assert(Interlocked.Increment(ref m_OutstandingOperations.m_Writes) == 1,
                                    "Only one outstanding write allowed at any given time.");
#endif
                    WebSocketHelpers.ThrowIfConnectionAborted(m_InnerStream, false);
                    m_WriteTaskCompletionSource = new TaskCompletionSource <object>();
                    m_WriteEventArgs.BufferList = null;
                    m_WriteEventArgs.SetBuffer(buffer, offset, count);
                    completedAsynchronously = InnerSocket.SendAsync(m_WriteEventArgs);
                    if (!completedAsynchronously)
                    {
                        if (m_WriteEventArgs.SocketError != SocketError.Success)
                        {
                            throw new SocketException(m_WriteEventArgs.SocketError);
                        }

                        return(Task.CompletedTask);
                    }

                    return(m_WriteTaskCompletionSource.Task);
                }
                finally
                {
                    if (WebSocketBase.LoggingEnabled)
                    {
                        Logging.Exit(Logging.WebSockets, this, Methods.WriteAsync, completedAsynchronously);
                    }
                }
            }
示例#3
0
        // This method is not thread safe. It must only be called after enforcing at most 1 outstanding send operation
        internal void PinSendBuffer(ArraySegment <byte> payload, out bool bufferHasBeenPinned)
        {
            bufferHasBeenPinned = false;
            WebSocketHelpers.ValidateBuffer(payload.Array, payload.Offset, payload.Count);
            int previousState = Interlocked.Exchange(ref m_SendBufferState, SendBufferState.SendPayloadSpecified);

            if (previousState != SendBufferState.None)
            {
                Contract.Assert(false, "'m_SendBufferState' MUST BE 'None' at this point.");
                // Indicates a violation in the API contract that could indicate
                // memory corruption because the pinned sendbuffer is shared between managed and native code
                throw new AccessViolationException();
            }
            m_PinnedSendBuffer             = payload;
            m_PinnedSendBufferHandle       = GCHandle.Alloc(m_PinnedSendBuffer.Array, GCHandleType.Pinned);
            bufferHasBeenPinned            = true;
            m_PinnedSendBufferStartAddress =
                Marshal.UnsafeAddrOfPinnedArrayElement(m_PinnedSendBuffer.Array, m_PinnedSendBuffer.Offset).ToInt64();
            m_PinnedSendBufferEndAddress = m_PinnedSendBufferStartAddress + m_PinnedSendBuffer.Count;
        }
        public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
        {
            WebSocketHelpers.ValidateBuffer(buffer, offset, count);

            return(WriteAsyncCore(buffer, offset, count, cancellationToken));
        }