public void WriteLocked_PreventsAnotherWriterLock()
 {
     Test.Async(async () =>
     {
         var rwl = new AsyncReaderWriterLock();
         await rwl.WriterLockAsync();
         var task = rwl.WriterLockAsync().AsTask();
         await AssertEx.NeverCompletesAsync(task);
     });
 }
 public void Unlocked_PermitsWriterLock()
 {
     Test.Async(async () =>
     {
         var rwl = new AsyncReaderWriterLock();
         await rwl.WriterLockAsync();
     });
 }
 public void Unlocked_PermitsWriterLock()
 {
     AsyncContext.Run(async () =>
     {
         var rwl = new AsyncReaderWriterLock();
         await rwl.WriterLockAsync();
     });
 }
 public void WriteLocked_PreventsUpgradeableReaderLock()
 {
     AsyncContext.Run(async () =>
     {
         var rwl = new AsyncReaderWriterLock();
         await rwl.WriterLockAsync();
         var task = rwl.UpgradeableReaderLockAsync();
         await AssertEx.NeverCompletesAsync(task);
     });
 }
 public void WriteLocked_Unlocked_PermitsAnotherWriterLock()
 {
     AsyncContext.Run(async () =>
     {
         var rwl = new AsyncReaderWriterLock();
         var firstWriteLockTaken = new TaskCompletionSource();
         var releaseFirstWriteLock = new TaskCompletionSource();
         var task = Task.Run(async () =>
         {
             using (await rwl.WriterLockAsync())
             {
                 firstWriteLockTaken.SetResult();
                 await releaseFirstWriteLock.Task;
             }
         });
         await firstWriteLockTaken.Task;
         var lockTask = rwl.WriterLockAsync();
         Assert.IsFalse(lockTask.IsCompleted);
         releaseFirstWriteLock.SetResult();
         await lockTask;
     });
 }
        public void ReaderLocked_ReaderReleased_ReaderAndWriterWaiting_DoesNotReleaseReaderOrWriter()
        {
            Test.Async(async () =>
            {
                var rwl = new AsyncReaderWriterLock();
                Task readLock, writeLock;
                await rwl.ReaderLockAsync();
                using (await rwl.ReaderLockAsync())
                {
                    writeLock = rwl.WriterLockAsync().AsTask();
                    readLock = rwl.ReaderLockAsync().AsTask();
                }

                await TaskShim.WhenAll(AssertEx.NeverCompletesAsync(writeLock),
                    AssertEx.NeverCompletesAsync(readLock));
            });
        }
        public void LockReleased_AllowsUpgradeableReadAndMultipleReaders()
        {
            Test.Async(async () =>
            {
                var rwl = new AsyncReaderWriterLock();
                Task upgradeableReadLock, readLock1, readLock2;
                using (await rwl.WriterLockAsync())
                {
                    upgradeableReadLock = rwl.UpgradeableReaderLockAsync().AsTask();
                    readLock1 = rwl.ReaderLockAsync().AsTask();
                    readLock2 = rwl.ReaderLockAsync().AsTask();
                }

                await TaskShim.WhenAll(upgradeableReadLock, readLock1, readLock2);
            });
        }
        public void LockReleased_WriteTakesPriorityOverRead()
        {
            Test.Async(async () =>
            {
                var rwl = new AsyncReaderWriterLock();
                Task writeLock, readLock;
                using (await rwl.WriterLockAsync())
                {
                    readLock = rwl.ReaderLockAsync().AsTask();
                    writeLock = rwl.WriterLockAsync().AsTask();
                }

                await writeLock;
                await AssertEx.NeverCompletesAsync(readLock);
            });
        }
        public void WriteLocked_UpgradeableReaderLockCancelled_DoesNotTakeLockWhenUnlocked()
        {
            Test.Async(async () =>
            {
                var rwl = new AsyncReaderWriterLock();
                using (await rwl.WriterLockAsync())
                {
                    var cts = new CancellationTokenSource();
                    var task = rwl.UpgradeableReaderLockAsync(cts.Token).AsTask();
                    cts.Cancel();
                    await AssertEx.ThrowsExceptionAsync<OperationCanceledException>(() => task);
                }

                await rwl.UpgradeableReaderLockAsync();
            });
        }
        public void UpgradeableReaderLock_PreCancelled_LockNotAvailable_SynchronouslyCancels()
        {
            var rwl = new AsyncReaderWriterLock();
            var token = new CancellationToken(true);
            rwl.WriterLockAsync();

            var task = rwl.UpgradeableReaderLockAsync(token).AsTask();

            Assert.IsTrue(task.IsCompleted);
            Assert.IsTrue(task.IsCanceled);
            Assert.IsFalse(task.IsFaulted);
        }
 public void UpgradeableReadLocked_Upgraded_PreventsReaderLock()
 {
     Test.Async(async () =>
     {
         var rwl = new AsyncReaderWriterLock();
         var key = await rwl.UpgradeableReaderLockAsync();
         await key.UpgradeAsync();
         Assert.IsTrue(key.Upgraded);
         var task = rwl.WriterLockAsync().AsTask();
         await AssertEx.NeverCompletesAsync(task);
     });
 }
 public void UpgradeableReadLocked_Unlocked_AllowsWriterLock()
 {
     Test.Async(async () =>
     {
         var rwl = new AsyncReaderWriterLock();
         using (var key = await rwl.UpgradeableReaderLockAsync())
         {
             Assert.IsFalse(key.Upgraded);
         }
         await rwl.WriterLockAsync();
     });
 }
 public void WriterKey_MultiDispose_DoesNothing()
 {
     AsyncContext.Run(async () =>
     {
         var rwl = new AsyncReaderWriterLock();
         var key = await rwl.WriterLockAsync();
         key.Dispose();
         key.Dispose();
         await rwl.WriterLockAsync();
     });
 }
        public void LockReleased_WriteTakesPriorityOverUpgradeableRead()
        {
            AsyncContext.Run(async () =>
            {
                var rwl = new AsyncReaderWriterLock();
                Task writeLock, upgradeableReadLock;
                using (await rwl.WriterLockAsync())
                {
                    upgradeableReadLock = rwl.UpgradeableReaderLockAsync();
                    writeLock = rwl.WriterLockAsync();
                }

                await writeLock;
                await AssertEx.NeverCompletesAsync(upgradeableReadLock);
            });
        }
        public void WriterLock_PreCancelled_LockAvailable_SynchronouslyTakesLock()
        {
            var rwl = new AsyncReaderWriterLock();
            var token = new CancellationToken(true);
            
            var task = rwl.WriterLockAsync(token);

            Assert.IsTrue(task.IsCompleted);
            Assert.IsFalse(task.IsCanceled);
            Assert.IsFalse(task.IsFaulted);
        }
 public void UpgradeableReadLocked_PreventsWriterLock()
 {
     AsyncContext.Run(async () =>
     {
         var rwl = new AsyncReaderWriterLock();
         var key = await rwl.UpgradeableReaderLockAsync();
         Assert.IsFalse(key.Upgraded);
         var task = rwl.WriterLockAsync();
         await AssertEx.NeverCompletesAsync(task);
     });
 }