public void RaceConditionBetweenCancellingAndReleasingWaiterFromTheQueue() { FifoSemaphore fs = new FifoSemaphore(2); var cts = new CancellationTokenSource[4]; for (int i = 0; i < cts.Length; i++) { cts[i] = new CancellationTokenSource(TimeSpan.FromSeconds(5)); } try { Parallel.For(0, 20, x => { CancellationTokenSource cancellationTokenSource = cts[x % cts.Length]; while (cancellationTokenSource.IsCancellationRequested == false) { fs.Acquire(cancellationTokenSource.Token); try { Thread.Sleep(13); } finally { fs.Release(); } } }); } catch { // ignored } Assert.True(fs.TryAcquire(TimeSpan.Zero, CancellationToken.None)); try { Assert.True(fs.TryAcquire(TimeSpan.Zero, CancellationToken.None)); try { } finally { fs.Release(); } } finally { fs.Release(); } Assert.Empty(fs._waitQueue); }
public void ShouldNotLeaveWaitersInQueueIfTimeout() { var @lock = new FifoSemaphore(1); @lock.Acquire(CancellationToken.None); Assert.False(@lock.TryAcquire(TimeSpan.Zero, CancellationToken.None)); Assert.Empty(@lock._waitQueue); }
public void ShouldNotLeaveWaitersInQueueIfTimeoutAfterCallingRelease() { var @lock = new FifoSemaphore(1); @lock.Acquire(CancellationToken.None); try { Assert.False(@lock.TryAcquire(TimeSpan.Zero, CancellationToken.None)); Assert.Equal(1, @lock._waitQueue.Count); Assert.True(@lock._waitQueue.First().IsTimedOut); } finally { @lock.Release(); } Assert.Empty(@lock._waitQueue); }