/** 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);
  }
  /** 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 testAwait_Timeout(AwaitMethod awaitMethod) {
   final Mutex sync = new Mutex();
   final ConditionObject c = sync.newCondition();
   sync.acquire();
   assertAwaitTimesOut(c, awaitMethod);
   sync.release();
 }
  /** 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);
  }
 /** tryAcquire on a released sync succeeds */
 public void testTryAcquire() {
   Mutex sync = new Mutex();
   assertTrue(sync.tryAcquire());
   assertTrue(sync.isHeldExclusively());
   sync.release();
   assertFalse(sync.isHeldExclusively());
 }
  /** 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());
  }
  /** tryAcquire on exclusively held sync fails */
  public void testTryAcquireWhenSynced() {
    final Mutex sync = new Mutex();
    sync.acquire();
    Thread t =
        newStartedThread(
            new CheckedRunnable() {
              public void realRun() {
                assertFalse(sync.tryAcquire());
              }
            });

    awaitTermination(t);
    sync.release();
  }
  /** tryAcquireNanos on an exclusively held sync times out */
  public void testAcquireNanos_Timeout() {
    final Mutex sync = new Mutex();
    sync.acquire();
    Thread t =
        newStartedThread(
            new CheckedRunnable() {
              public void realRun() throws InterruptedException {
                long startTime = System.nanoTime();
                long nanos = MILLISECONDS.toNanos(timeoutMillis());
                assertFalse(sync.tryAcquireNanos(nanos));
                assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
              }
            });

    awaitTermination(t);
    sync.release();
  }
 /** getFirstQueuedThread returns first waiting thread or null if none */
 public void testGetFirstQueuedThread() {
   final Mutex sync = new Mutex();
   assertNull(sync.getFirstQueuedThread());
   sync.acquire();
   Thread t1 = newStartedThread(new InterruptedSyncRunnable(sync));
   waitForQueuedThread(sync, t1);
   assertEquals(t1, sync.getFirstQueuedThread());
   Thread t2 = newStartedThread(new InterruptibleSyncRunnable(sync));
   waitForQueuedThread(sync, t2);
   assertEquals(t1, sync.getFirstQueuedThread());
   t1.interrupt();
   awaitTermination(t1);
   assertEquals(t2, sync.getFirstQueuedThread());
   sync.release();
   awaitTermination(t2);
   assertNull(sync.getFirstQueuedThread());
 }
 /** hasQueuedThreads reports whether there are waiting threads */
 public void testHasQueuedThreads() {
   final Mutex sync = new Mutex();
   assertFalse(sync.hasQueuedThreads());
   sync.acquire();
   Thread t1 = newStartedThread(new InterruptedSyncRunnable(sync));
   waitForQueuedThread(sync, t1);
   assertTrue(sync.hasQueuedThreads());
   Thread t2 = newStartedThread(new InterruptibleSyncRunnable(sync));
   waitForQueuedThread(sync, t2);
   assertTrue(sync.hasQueuedThreads());
   t1.interrupt();
   awaitTermination(t1);
   assertTrue(sync.hasQueuedThreads());
   sync.release();
   awaitTermination(t2);
   assertFalse(sync.hasQueuedThreads());
 }
 /** getSharedQueuedThreads does not include exclusively waiting threads */
 public void testGetSharedQueuedThreads_Exclusive() {
   final Mutex sync = new Mutex();
   assertTrue(sync.getSharedQueuedThreads().isEmpty());
   sync.acquire();
   assertTrue(sync.getSharedQueuedThreads().isEmpty());
   Thread t1 = newStartedThread(new InterruptedSyncRunnable(sync));
   waitForQueuedThread(sync, t1);
   assertTrue(sync.getSharedQueuedThreads().isEmpty());
   Thread t2 = newStartedThread(new InterruptibleSyncRunnable(sync));
   waitForQueuedThread(sync, t2);
   assertTrue(sync.getSharedQueuedThreads().isEmpty());
   t1.interrupt();
   awaitTermination(t1);
   assertTrue(sync.getSharedQueuedThreads().isEmpty());
   sync.release();
   awaitTermination(t2);
   assertTrue(sync.getSharedQueuedThreads().isEmpty());
 }
  /** A serialized AQS deserializes with current state, but no queued threads */
  public void testSerialization() {
    Mutex sync = new Mutex();
    assertFalse(serialClone(sync).isHeldExclusively());
    sync.acquire();
    Thread t = newStartedThread(new InterruptedSyncRunnable(sync));
    waitForQueuedThread(sync, t);
    assertTrue(sync.isHeldExclusively());

    Mutex clone = serialClone(sync);
    assertTrue(clone.isHeldExclusively());
    assertHasExclusiveQueuedThreads(sync, t);
    assertHasExclusiveQueuedThreads(clone, NO_THREADS);
    t.interrupt();
    awaitTermination(t);
    sync.release();
    assertFalse(sync.isHeldExclusively());
    assertTrue(clone.isHeldExclusively());
    assertHasExclusiveQueuedThreads(sync, NO_THREADS);
    assertHasExclusiveQueuedThreads(clone, 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);
  }
 /** getExclusiveQueuedThreads returns all exclusive waiting threads */
 public void testGetExclusiveQueuedThreads() {
   final Mutex sync = new Mutex();
   Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
   Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
   assertHasExclusiveQueuedThreads(sync, NO_THREADS);
   sync.acquire();
   assertHasExclusiveQueuedThreads(sync, NO_THREADS);
   t1.start();
   waitForQueuedThread(sync, t1);
   assertHasExclusiveQueuedThreads(sync, t1);
   assertTrue(sync.getExclusiveQueuedThreads().contains(t1));
   assertFalse(sync.getExclusiveQueuedThreads().contains(t2));
   t2.start();
   waitForQueuedThread(sync, t2);
   assertHasExclusiveQueuedThreads(sync, t1, t2);
   assertTrue(sync.getExclusiveQueuedThreads().contains(t1));
   assertTrue(sync.getExclusiveQueuedThreads().contains(t2));
   t1.interrupt();
   awaitTermination(t1);
   assertHasExclusiveQueuedThreads(sync, t2);
   sync.release();
   awaitTermination(t2);
   assertHasExclusiveQueuedThreads(sync, NO_THREADS);
 }
 /** Checks that condition c has exactly the given waiter threads, after acquiring mutex. */
 void assertHasWaitersUnlocked(Mutex sync, ConditionObject c, Thread... threads) {
   sync.acquire();
   assertHasWaitersLocked(sync, c, threads);
   sync.release();
 }