internal void Complete(OperationCompletionFlags completionFlags) { bool cancelled = (completionFlags & OperationCompletionFlags.OperationCancelled) != 0; if (cancelled) { SocketError = SocketError.OperationAborted; } // Reset state. ExecutionContext?context = _context; _context = null; CurrentSocket = null; CurrentOperation = System.Net.Sockets.SocketAsyncOperation.None; // Call OnCompleted only when completed async. bool completedAsync = (completionFlags & OperationCompletionFlags.CompletedSync) == 0; if (completedAsync) { if (context == null) { OnCompleted(this); } else { ExecutionContext.Run(context, s_executionCallback, this); } } }
// Requests the operation to be marked as cancelled. // Returns CancellationRequestResult.Cancelled when the operation was cancelled synchronously. // Returns CancellationRequestResult.Requested when the operation is marked for async cancellation. public CancellationRequestResult RequestCancellationAsync(OperationCompletionFlags flags) { Debug.Assert((CompletionFlags & (OperationCompletionFlags.OperationFinished | OperationCompletionFlags.OperationCancelled)) == 0); CompletionFlags = OperationCompletionFlags.CompletedCanceled | flags; return(IsExecuting ? CancellationRequestResult.Requested : CancellationRequestResult.Cancelled); }
// Requests operation to be cancelled. public void TryCancelAndComplete(OperationCompletionFlags completionFlags = OperationCompletionFlags.None) { AsyncContext?context = CurrentAsyncContext; // When context is null, the operation completed already. if (context != null) { context.TryCancelAndComplete(this, completionFlags); } }
internal override void TryCancelAndComplete(AsyncOperation operation, OperationCompletionFlags flags) { if (operation.IsReadNotWrite) { _readQueue.TryCancelAndComplete(operation, flags); } else { _writeQueue.TryCancelAndComplete(operation, flags); } }
public void GetResult(short token) { // Capture values. SocketError socketError = Saea.SocketError; OperationCompletionFlags completionFlags = CompletionFlags; // Reset this object and allow it to be reused. ResetAndReturnThis(); ThrowForSocketError(socketError, completionFlags); }
void IThreadPoolWorkItem.Execute() { // Capture state. OperationCompletionFlags completionStatus = CompletionFlags; // Reset state. CompletionFlags = OperationCompletionFlags.None; CurrentAsyncContext = null; // Complete. _saea.Complete(completionStatus); }
public void SetResult(T result, SocketError socketError, OperationCompletionFlags completionFlags) { _vts.SetResult(result); _socketError = socketError; _completionFlags = completionFlags; ManualResetEventSlim?mre = Interlocked.Exchange(ref _mre, s_completedSentinel); // This ManualResetEventSlim is used to wait until the operation completed. // After that a direct call is made to get the result. mre?.Set(); }
int IValueTaskSource <int> .GetResult(short token) { // Capture values. int bytesTransferred = Saea.BytesTransferred; SocketError socketError = Saea.SocketError; OperationCompletionFlags completionFlags = CompletionFlags; // Reset this object and allow it to be reused. ResetAndReturnThis(); ThrowForSocketError(socketError, completionFlags); return(bytesTransferred); }
Socket IValueTaskSource <Socket> .GetResult(short token) { // Capture values. Socket?socket = Saea.AcceptSocket; Saea.AcceptSocket = null; // Don't hold a reference. SocketError socketError = Saea.SocketError; OperationCompletionFlags completionFlags = CompletionFlags; // Reset this object and allow it to be reused. ResetAndReturnThis(); ThrowForSocketError(socketError, completionFlags); return(socket !); }
protected void ReturnThis() { AsyncContext asyncContext = CurrentAsyncContext !; CurrentAsyncContext = null; CompletionFlags = OperationCompletionFlags.None; if (IsReadNotWrite) { asyncContext.ReturnReadOperation(this); } else { asyncContext.ReturnWriteOperation(this); } }
private static void ThrowForSocketError(SocketError socketError, OperationCompletionFlags completionFlags) { if (socketError != System.Net.Sockets.SocketError.Success) { bool cancelledByToken = (completionFlags & OperationCompletionFlags.CancelledByToken) != 0; if (cancelledByToken) { throw new OperationCanceledException(); } bool cancelledByTimeout = (completionFlags & OperationCompletionFlags.CancelledByTimeout) != 0; if (cancelledByTimeout) { socketError = SocketError.TimedOut; } throw new SocketException((int)socketError); } }
public Result(T value, SocketError socketError, OperationCompletionFlags completionFlags) { _value = value; _socketError = socketError; _completionFlags = completionFlags; }
// Cancel AsyncOperation. internal abstract void TryCancelAndComplete(AsyncOperation asyncOperation, OperationCompletionFlags completionFlags);
// Requests cancellation of a queued operation. // If the operation is not on the queue (because it already completed), NotFound is returned. // If the operation is not executing, it is removed from the queue and Cancelled is returned. // If the operation is executing, it stays on the queue, the operation gets marked as cancellation requested, // and Requested is returned. protected CancellationRequestResult RequestCancellationAsync(AsyncOperation operation, OperationCompletionFlags flags) { CancellationRequestResult result = CancellationRequestResult.NotFound; if (_tail == operation) // We're the last operation { result = operation.RequestCancellationAsync(flags); if (result == CancellationRequestResult.Cancelled) { if (operation.Next == operation) // We're the only operation. { _tail = null; } else { // Update tail do { _tail = _tail.Next; } while (_tail !.Next != operation); // Update head _tail.Next = operation.Next; } operation.Next = null; } } else if (_tail != null) // The list is multiple operations and we're not the last { ref AsyncOperation nextOperation = ref _tail.Next !; do { if (nextOperation == operation) { result = operation.RequestCancellationAsync(flags); if (result == CancellationRequestResult.Cancelled) { nextOperation = operation.Next !; operation.Next = null; } break; } nextOperation = ref nextOperation.Next !; } while (nextOperation != _tail); }