| File: System\IO\Pipelines\PipeCompletion.cs | Web Access |
| Project: src\runtime\src\libraries\System.IO.Pipelines\src\System.IO.Pipelines.csproj (System.IO.Pipelines) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; using System.Diagnostics; using System.Runtime.CompilerServices; using System.Runtime.ExceptionServices; namespace System.IO.Pipelines { [DebuggerDisplay("IsCompleted = {" + nameof(IsCompleted) + "}")] internal struct PipeCompletion { private static readonly object s_completedSuccessfully = new object(); private object? _state; private List<PipeCompletionCallback>? _callbacks; public bool IsCompleted => _state != null; public bool IsFaulted => _state is ExceptionDispatchInfo; public PipeCompletionCallbacks? TryComplete(Exception? exception = null) { if (_state == null) { if (exception != null) { _state = ExceptionDispatchInfo.Capture(exception); } else { _state = s_completedSuccessfully; } } return GetCallbacks(); } public PipeCompletionCallbacks? AddCallback(Action<Exception?, object?> callback, object? state) { _callbacks ??= new List<PipeCompletionCallback>(); _callbacks.Add(new PipeCompletionCallback(callback, state)); if (IsCompleted) { return GetCallbacks(); } return null; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool IsCompletedOrThrow() { if (!IsCompleted) { return false; } if (_state is ExceptionDispatchInfo edi) { edi.Throw(); } return true; } private PipeCompletionCallbacks? GetCallbacks() { Debug.Assert(IsCompleted); var callbacks = _callbacks; if (callbacks == null) { return null; } _callbacks = null; return new PipeCompletionCallbacks(callbacks, _state as ExceptionDispatchInfo); } public void Reset() { Debug.Assert(IsCompleted); Debug.Assert(_callbacks == null); _state = null; } public override string ToString() { return $"{nameof(IsCompleted)}: {IsCompleted}"; } } }