public void DelockTest_1Lock_2Tasks_0Complete() { const string key = "aKey"; var counter = new[] { 0L }; var locks = new MultiLock(1, 10, true); Task <long> task1 = new Task <long>(() => { return(locks.LockAndLoad(key, () => Interlocked.Increment(ref counter[0]))); }); Task <long> task2 = new Task <long>(() => { return(locks.LockAndLoad(key, () => { task1.Start(); task1.Wait(); return Interlocked.Increment(ref counter[0]); })); }); try { task2.Start(); task2.Wait(); } finally { Assert.AreEqual(0L, Interlocked.Read(ref counter[0])); } }
public void DelockTest_1Lock_1Task_2Complete() { const string key = "aKey"; var counter = new[] { 0L }; var locks = new MultiLock(1, 10, true); locks.LockAndLoad(key, () => { locks.LockAndLoad(key, () => Interlocked.Increment(ref counter[0])); return(Interlocked.Increment(ref counter[0])); }); Assert.AreEqual(2L, Interlocked.Read(ref counter[0])); }
public void DelockTest_1Lock_1Task_DisabledReentrance_0Complete() { const string key = "aKey"; var counter = new[] { 0L }; var locks = new MultiLock(1, 10, true, doEnableReentrantLocking: false); try { locks.LockAndLoad(key, () => { locks.LockAndLoad(key, () => Interlocked.Increment(ref counter[0])); return(Interlocked.Increment(ref counter[0])); }); } finally { Assert.AreEqual(0L, Interlocked.Read(ref counter[0])); } }
public void LockAndLoad_WaitsForLock() { const int numberOfLocks = 512; const string key = "key1"; multiLock = new MultiLock(numberOfLocks, doEnableReentrantLocking: false); long[] entered = { 0L }; long[] locked = { 0L }; multiLock.Take(key); var runResult = Task.Run(action: () => multiLock.LockAndLoad(key, () => { var result = Interlocked.Increment(ref entered[0]); var ln = GetLockNumber(key); var l = GetLock(ln); if (l.CurrentCount > 0) { Interlocked.Increment(ref locked[0]); } return(result); })); // Give the task time to start Thread.Sleep(100); try { Assert.IsTrue(Interlocked.Read(ref entered[0]) == 0L, "Should wait for lock"); } finally { multiLock.Release(key); } runResult.Wait(100); Assert.IsTrue(Interlocked.Read(ref entered[0]) == 1L, "Should have gotten lock"); Assert.IsTrue(Interlocked.Read(ref locked[0]) == 0L, "Lock should have been taken"); var lockNumber = GetLockNumber(key); var lck = GetLock(lockNumber); Assert.IsTrue(lck.CurrentCount > 0, "Lock should have been released"); }
public void LockAndLoad_WaitsForLock_Timeout_NoThrow() { const int numberOfLocks = 512; const string key = "key1"; multiLock = new MultiLock(numberOfLocks, 10, false, doEnableReentrantLocking: false); long[] entered = { 0L }; long[] locked = { 0L }; multiLock.Take(key); var lockNumber = GetLockNumber(key); var lck = GetLock(lockNumber); try { multiLock.LockAndLoad(key, () => { var result = Interlocked.Increment(ref entered[0]); var ln = GetLockNumber(key); var l = GetLock(ln); if (l.CurrentCount > 0) { Interlocked.Increment(ref locked[0]); } return(result); }); } finally { var lockCount = lck.CurrentCount; multiLock.Release(key); Assert.IsTrue(Interlocked.Read(ref entered[0]) != 0L, "Should have timed out and entered"); Assert.IsTrue(lockCount == 0, "Lock should have been taken"); Assert.IsTrue(lck.CurrentCount == 1, "Lock should have been released"); } }