public override Task SendAsync( ArraySegment <byte> buffer, WebSocketMessageType messageType, bool endOfMessage, CancellationToken cancellationToken) { _operation.InterlockedCheckValidStates(s_validSendStates); using (CancellationTokenRegistration ctr = ThrowOrRegisterCancellation(cancellationToken)) { var bufferType = WebSocketMessageTypeAdapter.GetWinHttpMessageType(messageType, endOfMessage); _operation.PinSendBuffer(buffer); bool sendOperationAlreadyPending = false; if (_operation.PendingWriteOperation == false) { lock (_operation.Lock) { _operation.CheckValidState(s_validSendStates); if (_operation.PendingWriteOperation == false) { _operation.PendingWriteOperation = true; _operation.TcsSend = new TaskCompletionSource <bool>(TaskCreationOptions.RunContinuationsAsynchronously); uint ret = Interop.WinHttp.WinHttpWebSocketSend( _operation.WebSocketHandle, bufferType, buffer.Count > 0 ? Marshal.UnsafeAddrOfPinnedArrayElement(buffer.Array, buffer.Offset) : IntPtr.Zero, (uint)buffer.Count); if (Interop.WinHttp.ERROR_SUCCESS != ret) { throw WinHttpException.CreateExceptionUsingError((int)ret); } } else { sendOperationAlreadyPending = true; } } } else { sendOperationAlreadyPending = true; } if (sendOperationAlreadyPending) { var exception = new InvalidOperationException( SR.Format(SR.net_Websockets_AlreadyOneOutstandingOperation, "SendAsync")); _operation.TcsSend.TrySetException(exception); Abort(); } return(_operation.TcsSend.Task); } }
public override Task SendAsync( ArraySegment <byte> buffer, WebSocketMessageType messageType, bool endOfMessage, CancellationToken cancellationToken) { _operation.InterlockedCheckValidStates(s_validSendStates); using (CancellationTokenRegistration ctr = ThrowOrRegisterCancellation(cancellationToken)) { var bufferType = WebSocketMessageTypeAdapter.GetWinHttpMessageType(messageType, endOfMessage); // TODO (Issue 2505): replace with PinnableBufferCache. if (!_cachedSendPinnedBuffer.IsAllocated || _cachedSendPinnedBuffer.Target != buffer.Array) { if (_cachedSendPinnedBuffer.IsAllocated) { _cachedSendPinnedBuffer.Free(); } _cachedSendPinnedBuffer = GCHandle.Alloc(buffer.Array, GCHandleType.Pinned); } bool sendOperationAlreadyPending = false; if (_operation.PendingWriteOperation == false) { lock (_operation.Lock) { _operation.CheckValidState(s_validSendStates); if (_operation.PendingWriteOperation == false) { _operation.PendingWriteOperation = true; _operation.TcsSend = new TaskCompletionSource <bool>(); uint ret = Interop.WinHttp.WinHttpWebSocketSend( _operation.WebSocketHandle, bufferType, buffer.Count > 0 ? Marshal.UnsafeAddrOfPinnedArrayElement(buffer.Array, buffer.Offset) : IntPtr.Zero, (uint)buffer.Count); if (Interop.WinHttp.ERROR_SUCCESS != ret) { throw WinHttpException.CreateExceptionUsingError((int)ret); } } else { sendOperationAlreadyPending = true; } } } else { sendOperationAlreadyPending = true; } if (sendOperationAlreadyPending) { var exception = new InvalidOperationException( SR.Format(SR.net_Websockets_AlreadyOneOutstandingOperation, "SendAsync")); _operation.TcsSend.TrySetException(exception); Abort(); } return(_operation.TcsSend.Task); } }