public void TestSignalAll()
        {
            Mutex sync = new Mutex();

            AbstractQueuedSynchronizer.ConditionObject c = sync.NewCondition();
            Pair data = new Pair(sync, c);

            Thread t1 = new Thread(TestSignalAllRunnable1);
            Thread t2 = new Thread(TestSignalAllRunnable2);

            try
            {
                t1.Start(data);
                t2.Start(data);
                Thread.Sleep(SHORT_DELAY_MS);
                sync.Acquire(1);
                c.SignalAll();
                sync.Release(1);
                t1.Join(SHORT_DELAY_MS);
                t2.Join(SHORT_DELAY_MS);
                Assert.IsFalse(t1.IsAlive);
                Assert.IsFalse(t2.IsAlive);
            }
            catch (Exception e)
            {
                UnexpectedException(e);
            }
        }
        public void TestHasWaiters()
        {
            Mutex sync = new Mutex();

            AbstractQueuedSynchronizer.ConditionObject c = sync.NewCondition();
            Pair   data = new Pair(sync, c);
            Thread t    = new Thread(TestHasWaitersRunnable);

            try
            {
                t.Start(data);
                Thread.Sleep(SHORT_DELAY_MS);
                sync.Acquire(1);
                Assert.IsTrue(sync.HasWaiters(c));
                Assert.AreEqual(1, sync.GetWaitQueueLength(c));
                c.Signal();
                sync.Release(1);
                Thread.Sleep(SHORT_DELAY_MS);
                sync.Acquire(1);
                Assert.IsFalse(sync.HasWaiters(c));
                Assert.AreEqual(0, sync.GetWaitQueueLength(c));
                sync.Release(1);
                t.Join(SHORT_DELAY_MS);
                Assert.IsFalse(t.IsAlive);
            }
            catch (Exception)
            {
                UnexpectedException();
            }
        }
        public void TestAwaitUnInterruptibly()
        {
            Mutex sync = new Mutex();

            AbstractQueuedSynchronizer.ConditionObject c = sync.NewCondition();
            Pair data = new Pair(sync, c);

            Thread t = new Thread(TestAwaitUnInterruptiblyRunnable);

            try
            {
                t.Start(data);
                Thread.Sleep(SHORT_DELAY_MS);
                t.Interrupt();
                sync.Acquire(1);
                c.Signal();
                sync.Release(1);
                t.Join(SHORT_DELAY_MS);
                Assert.IsFalse(t.IsAlive);
            }
            catch (Exception e)
            {
                UnexpectedException(e);
            }
        }
        public void TestOwns()
        {
            Mutex sync = new Mutex();

            AbstractQueuedSynchronizer.ConditionObject c = sync.NewCondition();
            Mutex sync2 = new Mutex();

            Assert.IsTrue(sync.Owns(c));
            Assert.IsFalse(sync2.Owns(c));
        }
        private void TestAwaitUnInterruptiblyRunnable(object state)
        {
            Pair  data = state as Pair;
            Mutex sync = data.first as Mutex;

            AbstractQueuedSynchronizer.ConditionObject c =
                data.second as AbstractQueuedSynchronizer.ConditionObject;

            sync.Acquire(1);
            c.AwaitUnInterruptibly();
            sync.Release(1);
        }
        public void TestAwaitTimeout()
        {
            Mutex sync = new Mutex();

            AbstractQueuedSynchronizer.ConditionObject c = sync.NewCondition();
            try
            {
                sync.Acquire(1);
                Assert.IsFalse(c.Await(SHORT_DELAY_MS) > 0);
                sync.Release(1);
            }
            catch (Exception e)
            {
                UnexpectedException(e);
            }
        }
        public void TestGetWaitQueueLengthTSE()
        {
            Mutex sync = new Mutex();

            AbstractQueuedSynchronizer.ConditionObject c = (sync.NewCondition());
            try
            {
                sync.GetWaitQueueLength(c);
                ShouldThrow();
            }
            catch (ThreadStateException)
            {
            }
            catch (Exception e)
            {
                UnexpectedException(e);
            }
        }
        public void TestAwaitUntilTimeout()
        {
            Mutex sync = new Mutex();

            AbstractQueuedSynchronizer.ConditionObject c = sync.NewCondition();

            try
            {
                sync.Acquire(1);
                DateTime deadline = DateTime.Now;
                Assert.IsFalse(c.AwaitUntil(deadline.AddSeconds(5)));
                sync.Release(1);
            }
            catch (Exception e)
            {
                UnexpectedException(e);
            }
        }
        public void TestSignalThreadStateException()
        {
            Mutex sync = new Mutex();

            AbstractQueuedSynchronizer.ConditionObject c = sync.NewCondition();
            try
            {
                c.Signal();
                ShouldThrow();
            }
            catch (ThreadStateException)
            {
            }
            catch (Exception e)
            {
                UnexpectedException(e);
            }
        }
        private void TestAwaitRunnable(object state)
        {
            Pair  data = state as Pair;
            Mutex sync = data.first as Mutex;

            AbstractQueuedSynchronizer.ConditionObject c =
                data.second as AbstractQueuedSynchronizer.ConditionObject;

            try
            {
                sync.Acquire(1);
                c.Await();
                sync.Release(1);
            }
            catch (ThreadInterruptedException e)
            {
                ThreadUnexpectedException(e);
            }
        }
        private void TestAwaitUntilInterruptRunnable(object state)
        {
            Pair  data = state as Pair;
            Mutex sync = data.first as Mutex;

            AbstractQueuedSynchronizer.ConditionObject c =
                data.second as AbstractQueuedSynchronizer.ConditionObject;

            try
            {
                sync.Acquire(1);
                c.AwaitUntil(DateTime.Now.AddMilliseconds(10000));
                sync.Release(1);
                ThreadShouldThrow();
            }
            catch (ThreadInterruptedException)
            {
            }
        }
        private void TestGetWaitQueueLengthRunnable2(object state)
        {
            Pair  data = state as Pair;
            Mutex sync = data.first as Mutex;

            AbstractQueuedSynchronizer.ConditionObject c = data.second as AbstractQueuedSynchronizer.ConditionObject;

            try
            {
                sync.Acquire(1);
                ThreadAssertTrue(sync.HasWaiters(c));
                ThreadAssertEquals(1, sync.GetWaitQueueLength(c));
                c.Await();
                sync.Release(1);
            }
            catch (ThreadInterruptedException e)
            {
                ThreadUnexpectedException(e);
            }
        }
        public void TestGetWaitingThreadsAE()
        {
            Mutex sync = new Mutex();

            AbstractQueuedSynchronizer.ConditionObject c = (sync.NewCondition());
            Mutex sync2 = new Mutex();

            try
            {
                sync2.GetWaitingThreads(c);
                ShouldThrow();
            }
            catch (ArgumentException)
            {
            }
            catch (Exception e)
            {
                UnexpectedException(e);
            }
        }
        private void TestGetWaitingThreadsRunnable2(object state)
        {
            Pair  data = state as Pair;
            Mutex sync = data.first as Mutex;

            AbstractQueuedSynchronizer.ConditionObject c =
                data.second as AbstractQueuedSynchronizer.ConditionObject;

            try
            {
                sync.Acquire(1);
                ThreadAssertFalse(sync.GetWaitingThreads(c).IsEmpty());
                c.Await();
                sync.Release(1);
            }
            catch (ThreadInterruptedException e)
            {
                ThreadUnexpectedException(e);
            }
        }