[Test] public void HasWaitersReturnTrueWhenThreadIsWaitingElseFalse([Values(true, false)] bool isFair)
        {
            _lock = new ReentrantLock(true);
            ICondition c = _lock.NewCondition();

            ThreadManager.StartAndAssertRegistered(
                "T1",
                delegate
            {
                using (_lock.Lock())
                {
                    Assert.IsFalse(_lock.HasWaiters(c));
                    Assert.That(_lock.GetWaitQueueLength(c), Is.EqualTo(0));
                    c.Await();
                }
            });

            Thread.Sleep(Delays.Short);
            _lock.Lock();
            Assert.IsTrue(_lock.HasWaiters(c));
            Assert.AreEqual(1, _lock.GetWaitQueueLength(c));
            c.Signal();
            _lock.Unlock();

            Thread.Sleep(Delays.Short);
            _lock.Lock();
            Assert.IsFalse(_lock.HasWaiters(c));
            Assert.AreEqual(0, _lock.GetWaitQueueLength(c));
            _lock.Unlock();
            ThreadManager.JoinAndVerify();
        }
        public void GetWaitQueueLengthReturnsNumberOfThreads(bool isFair)
        {
            _lock = new ReentrantLock(isFair);

            ICondition c = _lock.NewCondition();

            ThreadManager.StartAndAssertRegistered(
                "T1",
                delegate
            {
                using (_lock.Lock())
                {
                    Assert.IsFalse(_lock.HasWaiters(c));
                    Assert.AreEqual(0, _lock.GetWaitQueueLength(c));
                    c.Await();
                }
            });

            Thread.Sleep(Delays.Short);
            ThreadManager.StartAndAssertRegistered(
                "T2",
                delegate
            {
                using (_lock.Lock())
                {
                    Assert.IsTrue(_lock.HasWaiters(c));
                    Assert.AreEqual(1, _lock.GetWaitQueueLength(c));
                    c.Await();
                }
            });
            try
            {
                Thread.Sleep(Delays.Short);
                _lock.Lock();
                Assert.IsTrue(_lock.HasWaiters(c));
                Assert.AreEqual(2, _lock.GetWaitQueueLength(c));
                c.SignalAll();
                _lock.Unlock();

                Thread.Sleep(Delays.Short);
                _lock.Lock();
                Assert.IsFalse(_lock.HasWaiters(c));
                Assert.AreEqual(0, _lock.GetWaitQueueLength(c));
                _lock.Unlock();
            }
            finally
            {
                ThreadManager.JoinAndVerify();
            }
        }
        public void GetQueuedThreadsIncludeWaitingThreads(bool isFair)
        {
            _lock = new PublicReentrantLock(isFair);

            Assert.That(_lock.QueuedThreads.Count, Is.EqualTo(0));
            _lock.Lock();
            Assert.IsTrue((_lock.QueuedThreads.Count == 0));
            Thread t1 = ThreadManager.StartAndAssertRegistered("T1", InterruptedLock);

            Thread.Sleep(Delays.Short);
            Assert.IsTrue(_lock.QueuedThreads.Contains(t1));
            Thread t2 = ThreadManager.StartAndAssertRegistered("T2", InterruptibleLock);

            Thread.Sleep(Delays.Short);
            Assert.IsTrue(_lock.QueuedThreads.Contains(t1));
            Assert.IsTrue(_lock.QueuedThreads.Contains(t2));
            t1.Interrupt();

            Thread.Sleep(Delays.Short);
            Assert.IsFalse(_lock.QueuedThreads.Contains(t1));
            Assert.IsTrue(_lock.QueuedThreads.Contains(t2));
            _lock.Unlock();

            Thread.Sleep(Delays.Short);
            Assert.IsTrue((_lock.QueuedThreads.Count == 0));

            ThreadManager.JoinAndVerify(t1, t2);
        }
        public void IsQueuedThreadReportsWhetherThreadIsQueued(bool isFair)
        {
            _lock = new ReentrantLock(isFair);
            Thread t1 = ThreadManager.NewManagedThread(InterruptedLock, "T1");
            Thread t2 = ThreadManager.NewManagedThread(InterruptibleLock, "T2");

            Assert.IsFalse(_lock.IsQueuedThread(t1));
            Assert.IsFalse(_lock.IsQueuedThread(t2));
            _lock.Lock();
            t1.Start();

            Thread.Sleep(Delays.Short);
            Assert.IsTrue(_lock.IsQueuedThread(t1));
            t2.Start();

            Thread.Sleep(Delays.Short);
            Assert.IsTrue(_lock.IsQueuedThread(t1));
            Assert.IsTrue(_lock.IsQueuedThread(t2));
            t1.Interrupt();

            Thread.Sleep(Delays.Short);
            Assert.IsFalse(_lock.IsQueuedThread(t1));
            Assert.IsTrue(_lock.IsQueuedThread(t2));
            _lock.Unlock();

            Thread.Sleep(Delays.Short);
            Assert.IsFalse(_lock.IsQueuedThread(t1));

            Thread.Sleep(Delays.Short);
            Assert.IsFalse(_lock.IsQueuedThread(t2));

            ThreadManager.JoinAndVerify(t1, t2);
        }
        public void GetQueueLengthReportsNumberOfWaitingThreads(bool isFair)
        {
            _lock = new ReentrantLock(isFair);

            Assert.AreEqual(0, _lock.QueueLength);
            _lock.Lock();
            Thread t1 = ThreadManager.StartAndAssertRegistered("T1", InterruptedLock);

            Thread.Sleep(Delays.Short);
            Assert.AreEqual(1, _lock.QueueLength);
            Thread t2 = ThreadManager.StartAndAssertRegistered("T2", InterruptibleLock);

            Thread.Sleep(Delays.Short);
            Assert.AreEqual(2, _lock.QueueLength);
            t1.Interrupt();

            Thread.Sleep(Delays.Short);
            Assert.AreEqual(1, _lock.QueueLength);
            _lock.Unlock();

            Thread.Sleep(Delays.Short);
            Assert.AreEqual(0, _lock.QueueLength);

            ThreadManager.JoinAndVerify(t1, t2);
        }
        [Test] public void AwaitUninterruptiblyCannotBeInterrupted([Values(true, false)] bool isFair)
        {
            _lock = new ReentrantLock(isFair);
            ICondition            c      = _lock.NewCondition();
            UninterruptableThread thread = new UninterruptableThread(_lock, c);

            thread.InternalThread.Start();

            while (!thread.LockStarted)
            {
                Thread.Sleep(100);
            }

            _lock.Lock();
            try
            {
                thread.InternalThread.Interrupt();
                thread.CanAwake = true;
                c.Signal();
            }
            finally
            {
                _lock.Unlock();
            }

            ThreadManager.JoinAndVerify(thread.InternalThread);
            Assert.IsTrue(thread.Interrupted);
        }
        [Test] public void TryLockSucceedsOnUnlockedLock([Values(true, false)] bool isFair)
        {
            ReentrantLock rl = new ReentrantLock(isFair);

            Assert.IsTrue(rl.TryLock());
            Assert.IsTrue(rl.IsLocked);
            rl.Unlock();
        }
 [Test] public void TryLockChokesWhenIsLocked([Values(true, false)] bool isFair)
 {
     _lock = new ReentrantLock(isFair);
     _lock.Lock();
     ThreadManager.StartAndAssertRegistered(
         "T1", delegate { Assert.IsFalse(_lock.TryLock()); });
     ThreadManager.JoinAndVerify();
     _lock.Unlock();
 }
 [Test] public void TimedTryLockTimesOutOnLockedLock([Values(true, false)] bool isFair)
 {
     _lock = new ReentrantLock(isFair);
     _lock.Lock();
     ThreadManager.StartAndAssertRegistered(
         "T1",
         () => Assert.IsFalse(_lock.TryLock(TimeSpan.FromMilliseconds(1))));
     ThreadManager.JoinAndVerify();
     _lock.Unlock();
 }
        [Test] public void AwaitUntilTimeoutWithoutSignal([Values(true, false)] bool isFair)
        {
            _lock = new ReentrantLock(isFair);
            ICondition c = _lock.NewCondition();

            _lock.Lock();
            DateTime until  = DateTime.UtcNow.AddMilliseconds(10);
            bool     result = c.AwaitUntil(until);

            Assert.That(DateTime.UtcNow, Is.GreaterThanOrEqualTo(until));
            Assert.IsFalse(result);
            _lock.Unlock();
        }
        [Test] public void IsLockedReportsIfLockOwnedByAnyThread([Values(true, false)] bool isFair)
        {
            _lock = new ReentrantLock(isFair);
            _lock.Lock();
            Assert.IsTrue(_lock.IsLocked);
            _lock.Unlock();
            Assert.IsFalse(_lock.IsLocked);
            Thread t1 = ThreadManager.StartAndAssertRegistered(
                "T1",
                delegate
            {
                _lock.Lock();
                Assert.Throws <ThreadInterruptedException>(() => Thread.Sleep(Delays.Long));
                _lock.Unlock();
            });

            Thread.Sleep(Delays.Short);
            Assert.IsTrue(_lock.IsLocked);
            t1.Interrupt();
            ThreadManager.JoinAndVerify();
            Assert.IsFalse(_lock.IsLocked);
        }
 private void RecursiveHolds(Action lockTask)
 {
     for (int i = 1; i <= DEFAULT_COLLECTION_SIZE; i++)
     {
         lockTask();
         Assert.AreEqual(i, _lock.HoldCount);
     }
     for (int i = DEFAULT_COLLECTION_SIZE; i > 0; i--)
     {
         _lock.Unlock();
         Assert.AreEqual(i - 1, _lock.HoldCount);
     }
 }
        [Test] public void LockIsNotInterruptibe([Values(true, false)] bool isFair)
        {
            _lock = new ReentrantLock(isFair);
            _lock.Lock();
            Thread t1 = ThreadManager.StartAndAssertRegistered(
                "T1",
                delegate
            {
                _lock.Lock();
                Assert.IsTrue(TestThreadManager.IsCurrentThreadInterrupted());
                Assert.IsTrue(_lock.IsLocked);
                Assert.IsTrue(_lock.IsHeldByCurrentThread);
                _lock.Unlock();
            });

            t1.Interrupt();
            Thread.Sleep(Delays.Short);
            Assert.IsTrue(t1.IsAlive);
            Assert.IsTrue(_lock.IsLocked);
            Assert.IsTrue(_lock.IsHeldByCurrentThread);
            _lock.Unlock();
            ThreadManager.JoinAndVerify();
        }
        [Test] public void AwaitReturnsWhenSignalled([Values(true, false)] bool isFair)
        {
            _lock = new ReentrantLock(isFair);
            ICondition c = _lock.NewCondition();

            ThreadManager.StartAndAssertRegistered(
                "T1",
                () => { using (_lock.Lock()) c.Await(); });

            Thread.Sleep(Delays.Short);
            _lock.Lock();
            c.Signal();
            _lock.Unlock();
            ThreadManager.JoinAndVerify();
        }
        [Test] public void SignalAllWakesUpAllThreads([Values(true, false)] bool isFair)
        {
            _lock = new ReentrantLock(isFair);
            ICondition  c      = _lock.NewCondition();
            ThreadStart cAwait = delegate { using (_lock.Lock()) c.Await(); };

            ThreadManager.StartAndAssertRegistered("T", cAwait, cAwait);

            Thread.Sleep(Delays.Short);
            _lock.Lock();
            c.SignalAll();
            _lock.Unlock();

            ThreadManager.JoinAndVerify();
        }
        [Test] public void TimedTryLockAllSucceedsFromMultipleThreads([Values(true, false)] bool isFair)
        {
            _lock = new ReentrantLock(isFair);
            _lock.LockInterruptibly();
            ThreadStart action =
                delegate
            {
                Assert.IsTrue(_lock.TryLock(Delays.Long));
                try
                {
                    Thread.Sleep(Delays.Short);
                }
                finally
                {
                    _lock.Unlock();
                }
            };

            ThreadManager.StartAndAssertRegistered("T", action, action);
            Assert.IsTrue(_lock.IsLocked);
            Assert.IsTrue(_lock.IsHeldByCurrentThread);
            _lock.Unlock();
            ThreadManager.JoinAndVerify();
        }
        [Test] public void LockInterruptiblySucceedsWhenUnlockedElseIsInterruptible([Values(true, false)] bool isFair)
        {
            _lock = new ReentrantLock(isFair);
            _lock.LockInterruptibly();
            var threads = ThreadManager.StartAndAssertRegistered("T",
                                                                 InterruptedLock,
                                                                 delegate { using (_lock.LockInterruptibly()) { } },
                                                                 delegate { using (_lock.LockInterruptibly()) { } });

            threads[0].Interrupt();
            ThreadManager.JoinAndVerify(threads[0]);
            Assert.IsTrue(_lock.IsLocked);
            Assert.IsTrue(_lock.IsHeldByCurrentThread);
            _lock.Unlock();
            ThreadManager.JoinAndVerify();
        }
        [Test] public void AwaitTimeoutWithoutSignal([Values(true, false)] bool isFair)
        {
            TimeSpan timeToWait = Delays.Short;

            _lock = new ReentrantLock(isFair);
            ICondition c = _lock.NewCondition();

            _lock.Lock();
            Stopwatch sw = new Stopwatch();

            sw.Start();
            bool result = c.Await(timeToWait);

            sw.Stop();
            Assert.IsFalse(result);
            Assert.That(sw.Elapsed + TimeSpan.FromMilliseconds(0.5), Is.Not.LessThan(timeToWait));
            _lock.Unlock();
        }
        [Test] public void SerializationDeserializesAsUnlocked([Values(true, false)] bool isFair)
        {
            ReentrantLock l = new ReentrantLock(isFair);

            l.Lock();
            l.Unlock();
            MemoryStream bout = new MemoryStream(10000);

            BinaryFormatter formatter = new BinaryFormatter();

            formatter.Serialize(bout, l);

            MemoryStream    bin        = new MemoryStream(bout.ToArray());
            BinaryFormatter formatter2 = new BinaryFormatter();
            ReentrantLock   r          = (ReentrantLock)formatter2.Deserialize(bin);

            r.Lock();
            r.Unlock();
        }
        public void HasQueuedThreadsReportsExistenceOfWaitingThreads(bool isFair)
        {
            _lock = new ReentrantLock(isFair);

            Assert.IsFalse(_lock.HasQueuedThreads);
            _lock.Lock();
            Thread t1 = ThreadManager.StartAndAssertRegistered("T1", InterruptedLock);

            Thread.Sleep(Delays.Short);
            Assert.IsTrue(_lock.HasQueuedThreads);
            Thread t2 = ThreadManager.StartAndAssertRegistered("T2", InterruptibleLock);

            Thread.Sleep(Delays.Short);
            Assert.IsTrue(_lock.HasQueuedThreads);
            t1.Interrupt();
            Thread.Sleep(Delays.Short);
            Assert.IsTrue(_lock.HasQueuedThreads);
            _lock.Unlock();
            Thread.Sleep(Delays.Short);
            Assert.IsFalse(_lock.HasQueuedThreads);

            ThreadManager.JoinAndVerify(t1, t2);
        }