/** Calling signalAll without holding sync throws IllegalMonitorStateException */
 public void testSignalAll_IMSE() {
   final Mutex sync = new Mutex();
   final ConditionObject c = sync.newCondition();
   try {
     c.signalAll();
     shouldThrow();
   } catch (IllegalMonitorStateException success) {
   }
 }
  /** 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);
  }
  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);
  }