/** getSharedQueuedThreads returns all shared waiting threads */
 public void testGetSharedQueuedThreads_Shared() {
   final BooleanLatch l = new BooleanLatch();
   assertHasSharedQueuedThreads(l, NO_THREADS);
   Thread t1 =
       newStartedThread(
           new CheckedInterruptedRunnable() {
             public void realRun() throws InterruptedException {
               l.acquireSharedInterruptibly(0);
             }
           });
   waitForQueuedThread(l, t1);
   assertHasSharedQueuedThreads(l, t1);
   Thread t2 =
       newStartedThread(
           new CheckedRunnable() {
             public void realRun() throws InterruptedException {
               l.acquireSharedInterruptibly(0);
             }
           });
   waitForQueuedThread(l, t2);
   assertHasSharedQueuedThreads(l, t1, t2);
   t1.interrupt();
   awaitTermination(t1);
   assertHasSharedQueuedThreads(l, t2);
   assertTrue(l.releaseShared(0));
   awaitTermination(t2);
   assertHasSharedQueuedThreads(l, NO_THREADS);
 }
  /** awaitUninterruptibly is uninterruptible */
  public void testAwaitUninterruptibly() {
    final Mutex sync = new Mutex();
    final ConditionObject c = sync.newCondition();
    final BooleanLatch pleaseInterrupt = new BooleanLatch();
    Thread t =
        newStartedThread(
            new CheckedRunnable() {
              public void realRun() {
                sync.acquire();
                assertTrue(pleaseInterrupt.releaseShared(0));
                c.awaitUninterruptibly();
                assertTrue(Thread.interrupted());
                assertHasWaitersLocked(sync, c, NO_THREADS);
                sync.release();
              }
            });

    pleaseInterrupt.acquireShared(0);
    sync.acquire();
    assertHasWaitersLocked(sync, c, t);
    sync.release();
    t.interrupt();
    assertHasWaitersUnlocked(sync, c, t);
    assertThreadStaysAlive(t);
    sync.acquire();
    assertHasWaitersLocked(sync, c, t);
    assertHasExclusiveQueuedThreads(sync, NO_THREADS);
    c.signal();
    assertHasWaitersLocked(sync, c, NO_THREADS);
    assertHasExclusiveQueuedThreads(sync, t);
    sync.release();
    awaitTermination(t);
  }
  /** hasWaiters returns true when a thread is waiting, else false */
  public void testHasWaiters() {
    final Mutex sync = new Mutex();
    final ConditionObject c = sync.newCondition();
    final BooleanLatch acquired = new BooleanLatch();
    Thread t =
        newStartedThread(
            new CheckedRunnable() {
              public void realRun() throws InterruptedException {
                sync.acquire();
                assertHasWaitersLocked(sync, c, NO_THREADS);
                assertFalse(sync.hasWaiters(c));
                assertTrue(acquired.releaseShared(0));
                c.await();
                sync.release();
              }
            });

    acquired.acquireShared(0);
    sync.acquire();
    assertHasWaitersLocked(sync, c, t);
    assertHasExclusiveQueuedThreads(sync, NO_THREADS);
    assertTrue(sync.hasWaiters(c));
    c.signal();
    assertHasWaitersLocked(sync, c, NO_THREADS);
    assertHasExclusiveQueuedThreads(sync, t);
    assertFalse(sync.hasWaiters(c));
    sync.release();

    awaitTermination(t);
    assertHasWaitersUnlocked(sync, c, NO_THREADS);
  }
  /** getState is true when acquired and false when not */
  public void testGetState() {
    final Mutex sync = new Mutex();
    sync.acquire();
    assertTrue(sync.isHeldExclusively());
    sync.release();
    assertFalse(sync.isHeldExclusively());

    final BooleanLatch acquired = new BooleanLatch();
    final BooleanLatch done = new BooleanLatch();
    Thread t =
        newStartedThread(
            new CheckedRunnable() {
              public void realRun() throws InterruptedException {
                sync.acquire();
                assertTrue(acquired.releaseShared(0));
                done.acquireShared(0);
                sync.release();
              }
            });

    acquired.acquireShared(0);
    assertTrue(sync.isHeldExclusively());
    assertTrue(done.releaseShared(0));
    awaitTermination(t);
    assertFalse(sync.isHeldExclusively());
  }
  /** tryAcquireSharedNanos times out if not released before timeout */
  public void testTryAcquireSharedNanos_Timeout() {
    final BooleanLatch l = new BooleanLatch();
    final BooleanLatch observedQueued = new BooleanLatch();
    final long timeoutMillis = timeoutMillis();
    Thread t =
        newStartedThread(
            new CheckedRunnable() {
              public void realRun() throws InterruptedException {
                assertFalse(l.isSignalled());
                for (long millis = timeoutMillis(); !observedQueued.isSignalled(); millis *= 2) {
                  long nanos = MILLISECONDS.toNanos(millis);
                  long startTime = System.nanoTime();
                  assertFalse(l.tryAcquireSharedNanos(0, nanos));
                  assertTrue(millisElapsedSince(startTime) >= millis);
                }
                assertFalse(l.isSignalled());
              }
            });

    waitForQueuedThread(l, t);
    observedQueued.releaseShared(0);
    assertFalse(l.isSignalled());
    awaitTermination(t);
    assertFalse(l.isSignalled());
  }
 public void thread1() {
   try {
     assertFalse(l.isSignalled());
     l.tryAcquireSharedNanos(0, SMALL_DELAY_MS * 1000 * 1000);
     fail("should throw exception");
   } catch (InterruptedException success) {
     assertTick(1);
   }
 }
 public void thread1() {
   try {
     assertFalse(l.isSignalled());
     l.acquireSharedInterruptibly(0);
     fail("should throw exception");
   } catch (InterruptedException success) {
     assertTick(1);
   }
 }
  /** getWaitQueueLength returns number of waiting threads */
  public void testGetWaitQueueLength() {
    final Mutex sync = new Mutex();
    final ConditionObject c = sync.newCondition();
    final BooleanLatch acquired1 = new BooleanLatch();
    final BooleanLatch acquired2 = new BooleanLatch();
    final Thread t1 =
        newStartedThread(
            new CheckedRunnable() {
              public void realRun() throws InterruptedException {
                sync.acquire();
                assertHasWaitersLocked(sync, c, NO_THREADS);
                assertEquals(0, sync.getWaitQueueLength(c));
                assertTrue(acquired1.releaseShared(0));
                c.await();
                sync.release();
              }
            });
    acquired1.acquireShared(0);
    sync.acquire();
    assertHasWaitersLocked(sync, c, t1);
    assertEquals(1, sync.getWaitQueueLength(c));
    sync.release();

    final Thread t2 =
        newStartedThread(
            new CheckedRunnable() {
              public void realRun() throws InterruptedException {
                sync.acquire();
                assertHasWaitersLocked(sync, c, t1);
                assertEquals(1, sync.getWaitQueueLength(c));
                assertTrue(acquired2.releaseShared(0));
                c.await();
                sync.release();
              }
            });
    acquired2.acquireShared(0);
    sync.acquire();
    assertHasWaitersLocked(sync, c, t1, t2);
    assertHasExclusiveQueuedThreads(sync, NO_THREADS);
    assertEquals(2, sync.getWaitQueueLength(c));
    c.signalAll();
    assertHasWaitersLocked(sync, c, NO_THREADS);
    assertHasExclusiveQueuedThreads(sync, t1, t2);
    assertEquals(0, sync.getWaitQueueLength(c));
    sync.release();

    awaitTermination(t1);
    awaitTermination(t2);
    assertHasWaitersUnlocked(sync, c, NO_THREADS);
  }
  /** acquireSharedInterruptibly is interruptible */
  public void testAcquireSharedInterruptibly_Interruptible() {
    final BooleanLatch l = new BooleanLatch();
    Thread t =
        newStartedThread(
            new CheckedInterruptedRunnable() {
              public void realRun() throws InterruptedException {
                assertFalse(l.isSignalled());
                l.acquireSharedInterruptibly(0);
              }
            });

    waitForQueuedThread(l, t);
    assertFalse(l.isSignalled());
    t.interrupt();
    awaitTermination(t);
    assertFalse(l.isSignalled());
  }
  public void testInterruptible(final AwaitMethod awaitMethod) {
    final Mutex sync = new Mutex();
    final ConditionObject c = sync.newCondition();
    final BooleanLatch pleaseInterrupt = new BooleanLatch();
    Thread t =
        newStartedThread(
            new CheckedInterruptedRunnable() {
              public void realRun() throws InterruptedException {
                sync.acquire();
                assertTrue(pleaseInterrupt.releaseShared(0));
                await(c, awaitMethod);
              }
            });

    pleaseInterrupt.acquireShared(0);
    t.interrupt();
    awaitTermination(t);
  }
  /** tryAcquireSharedNanos is interruptible */
  public void testTryAcquireSharedNanos_Interruptible() {
    final BooleanLatch l = new BooleanLatch();
    Thread t =
        newStartedThread(
            new CheckedInterruptedRunnable() {
              public void realRun() throws InterruptedException {
                assertFalse(l.isSignalled());
                long nanos = MILLISECONDS.toNanos(2 * LONG_DELAY_MS);
                l.tryAcquireSharedNanos(0, nanos);
              }
            });

    waitForQueuedThread(l, t);
    assertFalse(l.isSignalled());
    t.interrupt();
    awaitTermination(t);
    assertFalse(l.isSignalled());
  }
  /** acquireInterruptibly succeeds when released, else is interruptible */
  public void testAcquireInterruptibly() throws InterruptedException {
    final Mutex sync = new Mutex();
    final BooleanLatch threadStarted = new BooleanLatch();
    sync.acquireInterruptibly();
    Thread t =
        newStartedThread(
            new CheckedInterruptedRunnable() {
              public void realRun() throws InterruptedException {
                assertTrue(threadStarted.releaseShared(0));
                sync.acquireInterruptibly();
              }
            });

    threadStarted.acquireShared(0);
    waitForQueuedThread(sync, t);
    t.interrupt();
    awaitTermination(t);
    assertTrue(sync.isHeldExclusively());
  }
  public void testSignalAll(final AwaitMethod awaitMethod) {
    final Mutex sync = new Mutex();
    final ConditionObject c = sync.newCondition();
    final BooleanLatch acquired1 = new BooleanLatch();
    final BooleanLatch acquired2 = new BooleanLatch();
    Thread t1 =
        newStartedThread(
            new CheckedRunnable() {
              public void realRun() throws InterruptedException {
                sync.acquire();
                acquired1.releaseShared(0);
                await(c, awaitMethod);
                sync.release();
              }
            });

    Thread t2 =
        newStartedThread(
            new CheckedRunnable() {
              public void realRun() throws InterruptedException {
                sync.acquire();
                acquired2.releaseShared(0);
                await(c, awaitMethod);
                sync.release();
              }
            });

    acquired1.acquireShared(0);
    acquired2.acquireShared(0);
    sync.acquire();
    assertHasWaitersLocked(sync, c, t1, t2);
    assertHasExclusiveQueuedThreads(sync, NO_THREADS);
    c.signalAll();
    assertHasWaitersLocked(sync, c, NO_THREADS);
    assertHasExclusiveQueuedThreads(sync, t1, t2);
    sync.release();
    awaitTermination(t1);
    awaitTermination(t2);
  }
 /** releaseShared has no effect when already signalled */
 public void testReleaseShared() {
   final BooleanLatch l = new BooleanLatch();
   assertFalse(l.isSignalled());
   assertTrue(l.releaseShared(0));
   assertTrue(l.isSignalled());
   assertTrue(l.releaseShared(0));
   assertTrue(l.isSignalled());
 }
 public void thread2() {
   waitForTick(1);
   assertFalse(l.isSignalled());
 }
 public void thread1() throws InterruptedException {
   assertFalse(l.isSignalled());
   assertFalse(l.tryAcquireSharedNanos(0, SMALL_DELAY_MS * 1000 * 1000));
   assertTick(1);
 }
 public void thread2() {
   waitForTick(1);
   assertFalse(l.isSignalled());
   getThread(1).interrupt();
 }
 public void thread1() throws InterruptedException {
   assertFalse(l.isSignalled());
   l.acquireSharedInterruptibly(0);
   assertTick(1);
   assertTrue(l.isSignalled());
 }
 public void thread2() {
   assertFalse(l.isSignalled());
   waitForTick(1);
   l.releaseShared(0);
   assertTrue(l.isSignalled());
 }