< Summary

Information
Class: System.Net.Http.CreditWaiter
Assembly: System.Net.Http
File(s): D:\runner\runtime\src\libraries\System.Net.Http\src\System\Net\Http\SocketsHttpHandler\CreditWaiter.cs
Line coverage
0%
Covered lines: 0
Uncovered lines: 35
Coverable lines: 35
Total lines: 104
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 6
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

File(s)

D:\runner\runtime\src\libraries\System.Net.Http\src\System\Net\Http\SocketsHttpHandler\CreditWaiter.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3
 4using System.Runtime.ExceptionServices;
 5using System.Threading;
 6using System.Threading.Tasks;
 7using System.Threading.Tasks.Sources;
 8
 9namespace System.Net.Http
 10{
 11    /// <summary>Represents a waiter for credit.</summary>
 12    internal sealed class CreditWaiter : IValueTaskSource<int>
 13    {
 14        // State for the implementation of the CreditWaiter. Note that neither _cancellationToken nor
 15        // _registration are zero'd out upon completion, because they're used for synchronization
 16        // between successful completion and cancellation.  This means an instance may end up
 17        // referencing the underlying CancellationTokenSource even after the await operation has completed.
 18
 19        /// <summary>Cancellation token for the current wait operation.</summary>
 20        private CancellationToken _cancellationToken;
 21        /// <summary>Cancellation registration for the current wait operation.</summary>
 22        private CancellationTokenRegistration _registration;
 23        /// <summary><see cref="IValueTaskSource"/> implementation.</summary>
 24        private ManualResetValueTaskSourceCore<int> _source;
 25
 26        // State carried with the waiter for the consumer to use; these aren't used at all in the implementation.
 27
 28        /// <summary>Amount of credit desired by this waiter.</summary>
 29        public int Amount;
 30        /// <summary>Next waiter in a list of waiters.</summary>
 31        public CreditWaiter? Next;
 32
 33        /// <summary>Initializes a waiter for a credit wait operation.</summary>
 34        /// <param name="cancellationToken">The cancellation token for this wait operation.</param>
 035        public CreditWaiter(CancellationToken cancellationToken)
 036        {
 037            _source.RunContinuationsAsynchronously = true;
 038            RegisterCancellation(cancellationToken);
 039        }
 40
 41        /// <summary>Re-initializes a waiter for a credit wait operation.</summary>
 42        /// <param name="cancellationToken">The cancellation token for this wait operation.</param>
 43        public void ResetForAwait(CancellationToken cancellationToken)
 044        {
 045            _source.Reset();
 046            RegisterCancellation(cancellationToken);
 047        }
 48
 49        /// <summary>Registers with the cancellation token to transition the source to a canceled state.</summary>
 50        /// <param name="cancellationToken">The cancellation token with which to register.</param>
 51        private void RegisterCancellation(CancellationToken cancellationToken)
 052        {
 053            _cancellationToken = cancellationToken;
 054            _registration = cancellationToken.UnsafeRegister(static (s, cancellationToken) =>
 055            {
 056                // The callback will only fire if cancellation owns the right to complete the instance.
 057                ((CreditWaiter)s!)._source.SetException(ExceptionDispatchInfo.SetCurrentStackTrace(new OperationCanceled
 058            }, this);
 059        }
 60
 61        /// <summary>Wraps the instance as a <see cref="ValueTask{TResult}"/> to make it awaitable.</summary>
 062        public ValueTask<int> AsValueTask() => new ValueTask<int>(this, _source.Version);
 63
 64        /// <summary>Completes the instance with the specified result.</summary>
 65        /// <param name="result">The result value.</param>
 66        /// <returns>true if the instance was successfully completed; false if it was or is being canceled.</returns>
 67        public bool TrySetResult(int result)
 068        {
 069            if (UnregisterAndOwnCompletion())
 070            {
 071                _source.SetResult(result);
 072                return true;
 73            }
 74
 075            return false;
 076        }
 77
 78        /// <summary>Disposes the instance, failing any outstanding wait.</summary>
 79        public void Dispose()
 080        {
 081            if (UnregisterAndOwnCompletion())
 082            {
 083                _source.SetException(ExceptionDispatchInfo.SetCurrentStackTrace(new ObjectDisposedException(nameof(Credi
 084            }
 085        }
 86
 87        /// <summary>Unregisters the cancellation callback.</summary>
 88        /// <returns>true if the non-cancellation caller has the right to complete the instance; false if the instance w
 89        private bool UnregisterAndOwnCompletion() =>
 90            // Unregister the cancellation callback.  If Unregister returns true, then the cancellation callback was suc
 91            // meaning it hasn't run and won't ever run.  If it returns false, a) cancellation already occurred or is oc
 92            // the callback couldn't be removed, b) cancellation occurred prior to the UnsafeRegister call such that _re
 93            // set to a default value (or hasn't been set yet), or c) a default CancellationToken was used.  (a) and (b)
 94            // the same, and (c) can be checked via CanBeCanceled.
 095            _registration.Unregister() || !_cancellationToken.CanBeCanceled;
 96
 97        int IValueTaskSource<int>.GetResult(short token) =>
 098            _source.GetResult(token);
 99        ValueTaskSourceStatus IValueTaskSource<int>.GetStatus(short token) =>
 0100            _source.GetStatus(token);
 101        void IValueTaskSource<int>.OnCompleted(Action<object?> continuation, object? state, short token, ValueTaskSource
 0102            _source.OnCompleted(continuation, state, token, flags);
 103    }
 104}