public void EnterExit() { using (ReaderWriterLockSlim rwls = new ReaderWriterLockSlim()) { Assert.IsFalse(rwls.IsReadLockHeld); rwls.EnterReadLock(); Assert.IsTrue(rwls.IsReadLockHeld); rwls.ExitReadLock(); Assert.IsFalse(rwls.IsReadLockHeld); Assert.IsFalse(rwls.IsUpgradeableReadLockHeld); rwls.EnterUpgradeableReadLock(); Assert.IsTrue(rwls.IsUpgradeableReadLockHeld); rwls.ExitUpgradeableReadLock(); Assert.IsFalse(rwls.IsUpgradeableReadLockHeld); Assert.IsFalse(rwls.IsWriteLockHeld); rwls.EnterWriteLock(); Assert.IsTrue(rwls.IsWriteLockHeld); rwls.ExitWriteLock(); Assert.IsFalse(rwls.IsWriteLockHeld); Assert.IsFalse(rwls.IsUpgradeableReadLockHeld); rwls.EnterUpgradeableReadLock(); Assert.IsFalse(rwls.IsWriteLockHeld); Assert.IsTrue(rwls.IsUpgradeableReadLockHeld); rwls.EnterWriteLock(); Assert.IsTrue(rwls.IsWriteLockHeld); rwls.ExitWriteLock(); Assert.IsFalse(rwls.IsWriteLockHeld); Assert.IsTrue(rwls.IsUpgradeableReadLockHeld); rwls.ExitUpgradeableReadLock(); Assert.IsFalse(rwls.IsUpgradeableReadLockHeld); Assert.IsTrue(rwls.TryEnterReadLock(0)); rwls.ExitReadLock(); Assert.IsTrue(rwls.TryEnterReadLock(Timeout2.InfiniteTimeSpan)); rwls.ExitReadLock(); Assert.IsTrue(rwls.TryEnterUpgradeableReadLock(0)); rwls.ExitUpgradeableReadLock(); Assert.IsTrue(rwls.TryEnterUpgradeableReadLock(Timeout2.InfiniteTimeSpan)); rwls.ExitUpgradeableReadLock(); Assert.IsTrue(rwls.TryEnterWriteLock(0)); rwls.ExitWriteLock(); Assert.IsTrue(rwls.TryEnterWriteLock(Timeout2.InfiniteTimeSpan)); rwls.ExitWriteLock(); } }
public void InvalidTimeouts() { using (ReaderWriterLockSlim rwls = new ReaderWriterLockSlim()) { AssertExtensions.Throws <ArgumentOutOfRangeException>(() => rwls.TryEnterReadLock(-2)); AssertExtensions.Throws <ArgumentOutOfRangeException>(() => rwls.TryEnterUpgradeableReadLock(-3)); AssertExtensions.Throws <ArgumentOutOfRangeException>(() => rwls.TryEnterWriteLock(-4)); AssertExtensions.Throws <ArgumentOutOfRangeException>(() => rwls.TryEnterReadLock(TimeSpan.MaxValue)); AssertExtensions.Throws <ArgumentOutOfRangeException>(() => rwls.TryEnterUpgradeableReadLock(TimeSpan.MinValue)); AssertExtensions.Throws <ArgumentOutOfRangeException>(() => rwls.TryEnterWriteLock(TimeSpan.FromMilliseconds(-2))); } }
public void Dispose() { ReaderWriterLockSlim rwls; rwls = new ReaderWriterLockSlim(); rwls.Dispose(); AssertExtensions.Throws <ObjectDisposedException>(() => rwls.TryEnterReadLock(0)); AssertExtensions.Throws <ObjectDisposedException>(() => rwls.TryEnterUpgradeableReadLock(0)); AssertExtensions.Throws <ObjectDisposedException>(() => rwls.TryEnterWriteLock(0)); rwls.Dispose(); for (int i = 0; i < 3; i++) { rwls = new ReaderWriterLockSlim(); switch (i) { case 0: rwls.EnterReadLock(); break; case 1: rwls.EnterUpgradeableReadLock(); break; case 2: rwls.EnterWriteLock(); break; } AssertExtensions.Throws <SynchronizationLockException>(() => rwls.Dispose()); } }
public void WriterToWriterChain() { using (AutoResetEvent are = new AutoResetEvent(false)) using (ReaderWriterLockSlim rwls = new ReaderWriterLockSlim()) { rwls.EnterWriteLock(); Task t = Task.Factory.StartNew(() => { Assert.IsFalse(rwls.TryEnterWriteLock(10)); Task.Run(() => are.Set()); // ideally this won't fire until we've called EnterWriteLock, but it's a benign race in that the test will succeed either way rwls.EnterWriteLock(); rwls.ExitWriteLock(); }, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default); are.WaitOne(); rwls.ExitWriteLock(); t.GetAwaiter().GetResult(); } }
public void WritersAreMutuallyExclusiveFromWriters() { using (Barrier barrier = new Barrier(2)) using (ReaderWriterLockSlim rwls = new ReaderWriterLockSlim()) { Task.WaitAll( Task.Run(() => { rwls.EnterWriteLock(); barrier.SignalAndWait(); Assert.IsTrue(rwls.IsWriteLockHeld); barrier.SignalAndWait(); rwls.ExitWriteLock(); }), Task.Run(() => { barrier.SignalAndWait(); Assert.IsFalse(rwls.TryEnterWriteLock(0)); Assert.IsFalse(rwls.IsReadLockHeld); barrier.SignalAndWait(); })); } }
//[OuterLoop] //[SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework, "Hangs in desktop, issue dotnet/corefx#3364 is not fixed there")] public void ReleaseReadersWhenWaitingWriterTimesOut() { using (var rwls = new ReaderWriterLockSlim()) { // Enter the read lock rwls.EnterReadLock(); // Typical order of execution: 0 Thread writeWaiterThread; using (var beforeTryEnterWriteLock = new ManualResetEvent(false)) { writeWaiterThread = new Thread(() => { // Typical order of execution: 1 // Add a writer to the wait list for enough time to allow successive readers to enter the wait list while this // writer is waiting beforeTryEnterWriteLock.Set(); if (rwls.TryEnterWriteLock(1000)) { // The typical order of execution is not guaranteed, as sleep times are not guaranteed. For // instance, before this write lock is added to the wait list, the two new read locks may be // acquired. In that case, the test may complete before or while the write lock is taken. rwls.ExitWriteLock(); } // Typical order of execution: 4 }); writeWaiterThread.IsBackground = true; writeWaiterThread.Start(); beforeTryEnterWriteLock.WaitOne(); } Thread.Sleep(500); // wait for TryEnterWriteLock to enter the wait list // A writer should now be waiting, add readers to the wait list. Since a read lock is still acquired, the writer // should time out waiting, then these readers should enter and exit the lock. ThreadStart EnterAndExitReadLock = () => { // Typical order of execution: 2, 3 rwls.EnterReadLock(); // Typical order of execution: 5, 6 rwls.ExitReadLock(); }; var readerThreads = new Thread[] { new Thread(EnterAndExitReadLock), new Thread(EnterAndExitReadLock) }; foreach (var readerThread in readerThreads) { readerThread.IsBackground = true; readerThread.Start(); } foreach (var readerThread in readerThreads) { readerThread.Join(); } rwls.ExitReadLock(); // Typical order of execution: 7 writeWaiterThread.Join(); } }