Пример #1
0
        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]));
            }
        }
Пример #2
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]));
        }
Пример #3
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]));
            }
        }
Пример #4
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");
        }
Пример #5
0
        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");
            }
        }