[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();
        }
        [Test] public void AwaitAfterMultipleReentrantLockingPreservesLockCount([Values(true, false)] bool isFair)
        {
            _lock = new ReentrantLock(isFair);
            ICondition c = _lock.NewCondition();

            ThreadManager.StartAndAssertRegistered(
                "T",
                delegate
            {
                using (_lock.Lock())
                {
                    Assert.That(_lock.HoldCount, Is.EqualTo(1));
                    c.Await();
                    Assert.That(_lock.HoldCount, Is.EqualTo(1));
                }
            },
                delegate
            {
                using (_lock.Lock())
                    using (_lock.Lock())
                    {
                        Assert.That(_lock.HoldCount, Is.EqualTo(2));
                        c.Await();
                        Assert.That(_lock.HoldCount, Is.EqualTo(2));
                    }
            });

            Thread.Sleep(Delays.Short);
            Assert.IsFalse(_lock.IsLocked);
            using (_lock.Lock()) c.SignalAll();

            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();
            }
        }
        [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 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 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);
        }
        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 LockSucceedsOnUnlockedLock([Values(true, false)] bool isFair)
        {
            ReentrantLock rl = new ReentrantLock(isFair);

            rl.Lock();
            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 ToStringVerification([Values(true, false)] bool isFair)
 {
     _lock = new ReentrantLock(isFair);
     StringAssert.Contains("Unlocked", _lock.ToString());
     using (_lock.Lock())
     {
         StringAssert.Contains("Locked by thread", _lock.ToString());
     }
     StringAssert.Contains("Unlocked", _lock.ToString());
 }
        [Test] public void TimedTryLockIsInterruptible([Values(true, false)] bool isFair)
        {
            _lock = new ReentrantLock(isFair);
            _lock.Lock();
            Thread t = ThreadManager.StartAndAssertRegistered(
                "T1",
                () => Assert.Throws <ThreadInterruptedException>(
                    () => _lock.TryLock(Delays.Medium)));

            t.Interrupt();
            ThreadManager.JoinAndVerify(t);
        }
        [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 Run()
            {
                using (_myLock.Lock())
                {
                    LockStarted = true;

                    while (!CanAwake)
                    {
                        _condition.AwaitUninterruptibly();
                    }
                    Interrupted = TestThreadManager.IsCurrentThreadInterrupted();
                }
            }
        [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 GetHoldCountReturnsNumberOfRecursiveHolds([Values(true, false)] bool isFair)
        {
            _lock = new ReentrantLock(isFair);

            RecursiveHolds(delegate { _lock.Lock(); });
            RecursiveHolds((delegate
            {
                Assert.IsTrue(_lock.TryLock());
            }));
            RecursiveHolds(delegate
            {
                Assert.IsTrue(_lock.TryLock(Delays.Short));
            });
            RecursiveHolds(delegate { _lock.LockInterruptibly(); });
        }
        [Test] public void AwaitUntilIsInterruptible([Values(true, false)] bool isFair)
        {
            _lock = new ReentrantLock(isFair);

            ICondition c = _lock.NewCondition();
            Thread     t = ThreadManager.StartAndAssertRegistered(
                "T1",
                () => Assert.Throws <ThreadInterruptedException>(
                    () => { using (_lock.Lock()) c.AwaitUntil(DateTime.UtcNow.AddMilliseconds(10000)); }));

            Thread.Sleep(Delays.Short);
            t.Interrupt();

            ThreadManager.JoinAndVerify();
        }
        [Test] public void AwaitNanosIsInterruptible([Values(true, false)] bool isFair)
        {
            _lock = new ReentrantLock(isFair);

            ICondition c = _lock.NewCondition();
            Thread     t = ThreadManager.StartAndAssertRegistered(
                "T1",
                () => Assert.Throws <ThreadInterruptedException>(
                    () => { using (_lock.Lock()) c.Await(new TimeSpan(0, 0, 0, 1)); }));

            Thread.Sleep(Delays.Short);
            t.Interrupt();

            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);
        }