32 lines
840 B
C#
32 lines
840 B
C#
namespace Zcbot.WindowsNode;
|
|
|
|
internal sealed class JobExecutionGate : IDisposable
|
|
{
|
|
private readonly SemaphoreSlim gate = new(1, 1);
|
|
private int activeCount;
|
|
|
|
internal bool IsActive => Volatile.Read(ref activeCount) > 0;
|
|
|
|
internal async Task<IDisposable> EnterAsync(CancellationToken cancellationToken)
|
|
{
|
|
await gate.WaitAsync(cancellationToken);
|
|
Interlocked.Increment(ref activeCount);
|
|
return new Lease(this);
|
|
}
|
|
|
|
public void Dispose() => gate.Dispose();
|
|
|
|
private void Release()
|
|
{
|
|
Interlocked.Decrement(ref activeCount);
|
|
gate.Release();
|
|
}
|
|
|
|
private sealed class Lease(JobExecutionGate owner) : IDisposable
|
|
{
|
|
private JobExecutionGate? current = owner;
|
|
|
|
public void Dispose() => Interlocked.Exchange(ref current, null)?.Release();
|
|
}
|
|
}
|