public void GetWaitQueueLengthChokesWhenNotLocked(bool isFair)
        {
            _lock = new ReentrantLock(isFair);
            ICondition c = (_lock.NewCondition());

            _lock.GetWaitQueueLength(c);
        }
        [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();
        }
        [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 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 HasWaitersChokesWhenNotLocked(bool isFair)
        {
            _lock = new ReentrantLock(isFair);
            ICondition c = _lock.NewCondition();

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

            c.Signal();
        }
        public void GetWaitQueueLengthChokesWhenNotOwned([Values(true, false)] bool isFair)
        {
            _lock = new ReentrantLock(isFair);
            ICondition    c     = (_lock.NewCondition());
            ReentrantLock lock2 = new ReentrantLock(isFair);

            lock2.GetWaitQueueLength(c);
        }
        public void HasWaitersChokesWhenNotOwned([Values(true, false)] bool isFair)
        {
            _lock = new ReentrantLock(isFair);
            ICondition    c     = _lock.NewCondition();
            ReentrantLock lock2 = new ReentrantLock(isFair);

            lock2.HasWaiters(c);
        }
        [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();
        }
        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 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 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 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();
        }