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 CanUpgradeUpgradeableReadLock() { var l = new ReaderWriterLockSlimEx(); using (var rl = l.AcquireUpgradeableReadLock()) { // access lock here so it's not optimized-away after release build Assert.IsNotNull(l); using(rl.UpgradeToWriteLock()) { // access lock here so it's not optimized-away after release build Assert.IsNotNull(l); } } }
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 }); }
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 SupportsRecursion__WriteLockIsHeld__AnotherLockCanBeAcquired() { var l = new ReaderWriterLockSlimEx(LockRecursionPolicy.SupportsRecursion); IReadLockAcquisition r; IUpgradeableReadLockAcquisition ur; IWriteLockAcquisition w; var a1 = l.AcquireReadLock(); var a2 = l.TryAcquireReadLock(TEST_DefaultTimeout, out r); var a3 = l.TryAcquireUpgradeableReadLock(TEST_DefaultTimeout, out ur); var a4 = l.TryAcquireWriteLock(TEST_DefaultTimeout, out w); Assert.IsTrue(a2); Assert.IsFalse(a3); Assert.IsFalse(a4); }
public void UpgradeableReadLockIsHeld__AnotherThreadDoesNotBlockOnUpgradeableReadLockAcquisition() { // NOTE: this is how Reader Writer Lock Slim works // only one thread can own Upgradeable Read Lock at the time var l = new ReaderWriterLockSlimEx(); using (l.AcquireUpgradeableReadLock()) { Task.Factory.StartNew(() => { var acquisition = (IUpgradeableReadLockAcquisition)null; if (l.TryAcquireUpgradeableReadLock(TEST_DefaultTimeout, out acquisition)) { Assert.Fail(); } }).Wait(); } }
public void ReadLockIsHeld__AnotherThreadDoesNotBlockOnUpgradeableReadLockAcquisition() { var l = new ReaderWriterLockSlimEx(); using (l.AcquireReadLock()) { Task.Factory.StartNew(() => { var acquisition = (IUpgradeableReadLockAcquisition)null; if (!l.TryAcquireUpgradeableReadLock(TEST_DefaultTimeout, out acquisition)) { // should be able to acquire Assert.Fail(); } }).Wait(); } }
public void ReadLockIsHeld__CannotAcquireUpgradeableReadLock() { var l = new ReaderWriterLockSlimEx(); using (var rl = l.AcquireReadLock()) { var acquisition = (IUpgradeableReadLockAcquisition)null; if (l.TryAcquireUpgradeableReadLock(TEST_DefaultTimeout, out acquisition)) { // should not get here Assert.Fail(); } } }
public ReadLockAcquisition(ReaderWriterLockSlimEx owner, IDisposable disposeWhenDone) { this.Owner = owner; this.Disposable = disposeWhenDone; }
public UpgradeableReadLockAcquisition(ReaderWriterLockSlimEx owner) { this.Owner = owner; }
public WriteLockAcquisition(ReaderWriterLockSlimEx owner) { this.Owner = owner; }