public void Dispose() { if (_mutex == null) { return; } AsyncLockTracker.Remove(_mutex); _mutex = null; }
public RecursiveLockAwaitable LockAsync(CancellationToken token) { var key = AsyncLockTracker.Lookup(this); if (key == null) { key = mutex.LockAsync(token).AsTask(); } return(new RecursiveLockAwaitable(key, this)); }
public async Task RecursiveAsyncLock_DoesNotPermitIndependentWaits() { var mutex0 = new RecursiveAsyncLock(); using (await mutex0.LockAsync()) { var mutex = new RecursiveAsyncLock(); Func <TaskCompletionSource, TaskCompletionSource, Task> taker = async(ready, finish) => { Assert.IsFalse(AsyncLockTracker.Contains(mutex)); using (await mutex.LockAsync()) { Assert.IsTrue(AsyncLockTracker.Contains(mutex)); ready.TrySetResult(); await finish.Task; Assert.IsTrue(AsyncLockTracker.Contains(mutex)); } Assert.IsFalse(AsyncLockTracker.Contains(mutex)); }; var ready1 = new TaskCompletionSource(); var finish1 = new TaskCompletionSource(); Assert.IsFalse(AsyncLockTracker.Contains(mutex)); var task1 = taker(ready1, finish1); Assert.IsFalse(AsyncLockTracker.Contains(mutex)); await Task.WhenAny(ready1.Task, task1); Assert.IsFalse(AsyncLockTracker.Contains(mutex)); var ready2 = new TaskCompletionSource(); var finish2 = new TaskCompletionSource(); Assert.IsFalse(AsyncLockTracker.Contains(mutex)); var task2 = taker(ready2, finish2); Assert.IsFalse(AsyncLockTracker.Contains(mutex)); Assert.IsFalse(ready2.Task.Wait(1000)); finish1.SetResult(); await Task.WhenAny(ready2.Task, task2); Assert.IsFalse(AsyncLockTracker.Contains(mutex)); finish2.SetResult(); await Task.WhenAll(task1, task2); Assert.IsFalse(AsyncLockTracker.Contains(mutex)); } }
public async Task RecursiveAsyncLock_PermitsRecursiveWaits() { var mutex = new RecursiveAsyncLock(); Assert.IsFalse(AsyncLockTracker.Contains(mutex)); var task1 = mutex.LockAsync(); var key1 = await task1; Assert.IsTrue(AsyncLockTracker.Contains(mutex)); var task2 = mutex.LockAsync(); var key2 = await task2; Assert.IsTrue(AsyncLockTracker.Contains(mutex)); key2.Dispose(); Assert.IsTrue(AsyncLockTracker.Contains(mutex)); key1.Dispose(); Assert.IsFalse(AsyncLockTracker.Contains(mutex)); }
public KeyDisposable(Task <IDisposable> keyTask, RecursiveAsyncLock mutex) { _mutex = mutex; AsyncLockTracker.Add(mutex, keyTask); }