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;
}
}
}