public void CanAcquireAndReleaseWriteLock() { var l = new ReaderWriterLockSlimEx(); using (l.AcquireWriteLock()) { // access lock here so it's not optimized-away after release build Assert.IsNotNull(l); } }
public void WriteLockIsHeld__AnotherThreadBlocksOnReadLockAcquisition() { var l = new ReaderWriterLockSlimEx(); using (l.AcquireWriteLock()) { Task.Factory.StartNew(() => { var acquisition = (IReadLockAcquisition)null; if(l.TryAcquireReadLock(TEST_DefaultTimeout, out acquisition)) { // should not get here Assert.Fail(); } }).Wait(); } }
public void using_child_locks__avoids_deadlock_situations() { // Lock_1 (more coarse than Lock_2) // Lock_2 (child of Lock_1, more granual) // Thread_1 accesses Lock_1 then Lock_2 // Thread_2 accesses Lock_2 only var l1 = new ReaderWriterLockSlimEx(LockRecursionPolicy.NoRecursion); var l2 = new ReaderWriterLockSlimEx(LockRecursionPolicy.NoRecursion); l1.AddChild(l2); bool oh_no = false; var t1 = Task.Run(() => { using (l1.AcquireWriteLockIfNotHeld()) { Trace.WriteLine("t1 acquired l1"); Thread.Sleep(1000); using (l2.AcquireReadLockIfNotHeld()) { if (oh_no) Assert.Fail(":("); } } }); var t2 = Task.Run(() => { Thread.Sleep(100); using (l2.AcquireWriteLock()) { oh_no = true; Trace.WriteLine("t2 acquired l2"); } }); Task.WaitAll(new[] { t1, t2 }); }