public void TestInvaildExitReadLockUsage() { var l = new AsyncReaderWriterLock(); var readReleaser = l.ReadLock(); var readReleaser2 = l.ReadLock(); readReleaser.Dispose(); readReleaser2.Dispose(); Assert.Throws <InvalidOperationException>(() => readReleaser.Dispose()); Assert.Throws <InvalidOperationException>(() => readReleaser2.Dispose()); }
public void TestBlocking() { var l = new AsyncReaderWriterLock(); for (var i = 0; i < 2; i++) { var readReleaser = l.ReadLock(); Assert.That(l.CurrentReaders, Is.EqualTo(1)); var readReleaserTask = Task.Run(() => l.ReadLock()); AssertEqualValue(() => l.CurrentReaders, 2, readReleaserTask); AssertTaskCompleted(readReleaserTask); var writeReleaserTask = Task.Run(() => l.WriteLock()); AssertEqualValue(() => l.AcquiredWriteLock, true, writeReleaserTask); AssertEqualValue(() => l.Writing, false, writeReleaserTask); Assert.That(writeReleaserTask.IsCompleted, Is.False); readReleaser.Dispose(); Assert.That(l.CurrentReaders, Is.EqualTo(1)); Assert.That(writeReleaserTask.IsCompleted, Is.False); readReleaserTask.Result.Dispose(); Assert.That(l.CurrentReaders, Is.EqualTo(0)); AssertEqualValue(() => l.Writing, true, writeReleaserTask); AssertTaskCompleted(writeReleaserTask); readReleaserTask = Task.Run(() => l.ReadLock()); AssertEqualValue(() => l.ReadersWaiting, 1, readReleaserTask); Assert.That(readReleaserTask.IsCompleted, Is.False); var writeReleaserTask2 = Task.Run(() => l.WriteLock()); AssertEqualValue(() => l.WritersWaiting, 1, writeReleaserTask2); Assert.That(writeReleaserTask2.IsCompleted, Is.False); writeReleaserTask.Result.Dispose(); AssertEqualValue(() => l.WritersWaiting, 0, writeReleaserTask2); AssertEqualValue(() => l.Writing, true, writeReleaserTask2); Assert.That(readReleaserTask.IsCompleted, Is.False); AssertTaskCompleted(writeReleaserTask2); writeReleaserTask2.Result.Dispose(); AssertEqualValue(() => l.Writing, false, writeReleaserTask2); AssertEqualValue(() => l.ReadersWaiting, 0, readReleaserTask); AssertEqualValue(() => l.CurrentReaders, 1, readReleaserTask); AssertTaskCompleted(readReleaserTask); readReleaserTask.Result.Dispose(); Assert.That(l.ReadersWaiting, Is.EqualTo(0)); Assert.That(l.WritersWaiting, Is.EqualTo(0)); Assert.That(l.CurrentReaders, Is.EqualTo(0)); Assert.That(l.Writing, Is.False); } }
public virtual bool IsUpToDate(ISet <string> spaces, long timestamp /* H2.1 has Long here */) { if (spaces.Count == 0) { return(true); } using (_asyncReaderWriterLock.ReadLock()) { var lastUpdates = _updateTimestamps.GetMany(spaces.ToArray <object>()); return(lastUpdates.All(lastUpdate => !IsOutdated(lastUpdate as long?, timestamp))); } }
public void TestMixingSyncAndAsync() { var l = new AsyncReaderWriterLock(); var readReleaser = l.ReadLock(); Assert.That(l.CurrentReaders, Is.EqualTo(1)); var readReleaserTask = l.ReadLockAsync(); AssertEqualValue(() => l.CurrentReaders, 2, readReleaserTask); AssertTaskCompleted(readReleaserTask); readReleaser.Dispose(); Assert.That(l.CurrentReaders, Is.EqualTo(1)); readReleaserTask.Result.Dispose(); Assert.That(l.CurrentReaders, Is.EqualTo(0)); var writeReleaser = l.WriteLock(); Assert.That(l.AcquiredWriteLock, Is.True); var writeReleaserTask = l.WriteLockAsync(); AssertEqualValue(() => l.WritersWaiting, 1, writeReleaserTask); Assert.That(writeReleaserTask.IsCompleted, Is.False); readReleaserTask = Task.Run(() => l.ReadLock()); AssertEqualValue(() => l.ReadersWaiting, 1, readReleaserTask); Assert.That(readReleaserTask.IsCompleted, Is.False); var readReleaserTask2 = l.ReadLockAsync(); AssertEqualValue(() => l.ReadersWaiting, 2, readReleaserTask2); Assert.That(readReleaserTask2.IsCompleted, Is.False); writeReleaser.Dispose(); AssertEqualValue(() => l.WritersWaiting, 0, writeReleaserTask); AssertEqualValue(() => l.Writing, true, writeReleaserTask); AssertTaskCompleted(writeReleaserTask); Assert.That(readReleaserTask.IsCompleted, Is.False); Assert.That(readReleaserTask2.IsCompleted, Is.False); writeReleaserTask.Result.Dispose(); AssertEqualValue(() => l.CurrentReaders, 2, readReleaserTask); AssertEqualValue(() => l.ReadersWaiting, 0, readReleaserTask2); AssertTaskCompleted(readReleaserTask); AssertTaskCompleted(readReleaserTask2); }
public void TestOperationAfterDispose() { var l = new AsyncReaderWriterLock(); l.Dispose(); Assert.Throws <ObjectDisposedException>(() => l.ReadLock()); Assert.Throws <ObjectDisposedException>(() => l.WriteLock()); }
private static void Lock( AsyncReaderWriterLock readWriteLock, Random random, LockStatistics lockStatistics, System.Action checkLockAction, Func <bool> canContinue) { while (canContinue()) { var isRead = random.Next(100) < 80; var releaser = isRead ? readWriteLock.ReadLock() : readWriteLock.WriteLock(); lock (readWriteLock) { if (isRead) { lockStatistics.ReadLockCount++; } else { lockStatistics.WriteLockCount++; } checkLockAction(); } Thread.Sleep(10); lock (readWriteLock) { releaser.Dispose(); if (isRead) { lockStatistics.ReadLockCount--; } else { lockStatistics.WriteLockCount--; } checkLockAction(); } } }
public async Task TestConcurrentReadWriteAsync() { var l = new AsyncReaderWriterLock(); for (var i = 0; i < 2; i++) { var writeReleaser = await(l.WriteLockAsync()); Assert.That(l.Writing, Is.True); var secondWriteSemaphore = new SemaphoreSlim(0); var secondWriteReleaser = default(AsyncReaderWriterLock.Releaser); var secondWriteThread = new Thread( () => { secondWriteSemaphore.Wait(); secondWriteReleaser = l.WriteLock(); }); secondWriteThread.Priority = ThreadPriority.Highest; secondWriteThread.Start(); await(AssertEqualValueAsync(() => secondWriteThread.ThreadState == ThreadState.WaitSleepJoin, true)); var secondReadThreads = new Thread[20]; var secondReadReleasers = new AsyncReaderWriterLock.Releaser[secondReadThreads.Length]; var secondReadSemaphore = new SemaphoreSlim(0); for (var j = 0; j < secondReadReleasers.Length; j++) { var index = j; var thread = new Thread( () => { secondReadSemaphore.Wait(); secondReadReleasers[index] = l.ReadLock(); }); thread.Priority = ThreadPriority.Highest; secondReadThreads[j] = thread; thread.Start(); } await(AssertEqualValueAsync(() => secondReadThreads.All(o => o.ThreadState == ThreadState.WaitSleepJoin), true)); var firstReadReleaserTasks = new Task[30]; var firstReadStopSemaphore = new SemaphoreSlim(0); for (var j = 0; j < firstReadReleaserTasks.Length; j++) { firstReadReleaserTasks[j] = Task.Run(async() => { var releaser = await(l.ReadLockAsync()); await(firstReadStopSemaphore.WaitAsync()); releaser.Dispose(); }); } await(AssertEqualValueAsync(() => l.ReadersWaiting, firstReadReleaserTasks.Length, waitDelay: 60000)); writeReleaser.Dispose(); secondWriteSemaphore.Release(); secondReadSemaphore.Release(secondReadThreads.Length); await(Task.Delay(1000)); firstReadStopSemaphore.Release(firstReadReleaserTasks.Length); await(AssertEqualValueAsync(() => firstReadReleaserTasks.All(o => o.IsCompleted), true)); Assert.That(l.ReadersWaiting, Is.EqualTo(secondReadThreads.Length)); Assert.That(l.CurrentReaders, Is.EqualTo(0)); await(AssertEqualValueAsync(() => secondWriteThread.IsAlive, false)); await(AssertEqualValueAsync(() => secondReadThreads.All(o => o.IsAlive), true)); secondWriteReleaser.Dispose(); await(AssertEqualValueAsync(() => secondReadThreads.All(o => !o.IsAlive), true)); Assert.That(l.ReadersWaiting, Is.EqualTo(0)); Assert.That(l.CurrentReaders, Is.EqualTo(secondReadThreads.Length)); foreach (var secondReadReleaser in secondReadReleasers) { secondReadReleaser.Dispose(); } Assert.That(l.ReadersWaiting, Is.EqualTo(0)); Assert.That(l.CurrentReaders, Is.EqualTo(0)); } }