CancellationTokenSourcePool
using System;
using System.Runtime.CompilerServices;
using System.Threading;
namespace Polly.Utils
{
    [NullableContext(1)]
    [Nullable(0)]
    internal abstract class CancellationTokenSourcePool
    {
        [Nullable(0)]
        private sealed class PooledCancellationTokenSourcePool : CancellationTokenSourcePool
        {
            public static readonly PooledCancellationTokenSourcePool SystemInstance = new PooledCancellationTokenSourcePool(TimeProvider.System);
            private readonly ObjectPool<CancellationTokenSource> _pool;
            public PooledCancellationTokenSourcePool(TimeProvider timeProvider)
            {
                _pool = new ObjectPool<CancellationTokenSource>(() => new CancellationTokenSource(System.Threading.Timeout.InfiniteTimeSpan, timeProvider), (CancellationTokenSource cts) => true);
            }
            protected override CancellationTokenSource GetCore(TimeSpan delay)
            {
                CancellationTokenSource cancellationTokenSource = _pool.Get();
                if (IsCancellable(delay))
                    cancellationTokenSource.CancelAfter(delay);
                return cancellationTokenSource;
            }
            public override void Return(CancellationTokenSource source)
            {
                if (source.TryReset())
                    _pool.Return(source);
                else
                    source.Dispose();
            }
        }
        public static CancellationTokenSourcePool Create(TimeProvider timeProvider)
        {
            if (timeProvider == TimeProvider.System)
                return PooledCancellationTokenSourcePool.SystemInstance;
            return new PooledCancellationTokenSourcePool(timeProvider);
        }
        public CancellationTokenSource Get(TimeSpan delay)
        {
            if (delay <= TimeSpan.Zero && delay != System.Threading.Timeout.InfiniteTimeSpan)
                throw new ArgumentOutOfRangeException("delay", delay, "Invalid delay specified.");
            return GetCore(delay);
        }
        protected abstract CancellationTokenSource GetCore(TimeSpan delay);
        public abstract void Return(CancellationTokenSource source);
        protected static bool IsCancellable(TimeSpan delay)
        {
            return delay != System.Threading.Timeout.InfiniteTimeSpan;
        }
    }
}