zcbot/windows-node/Zcbot.WindowsNode/Adapters/JobExecutionGate.cs

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