ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/AbstractQueuedLongSynchronizerTest.java
(Generate patch)

Comparing jsr166/src/test/tck/AbstractQueuedLongSynchronizerTest.java (file contents):
Revision 1.9 by jsr166, Wed Nov 18 08:22:57 2009 UTC vs.
Revision 1.41 by jsr166, Mon Jul 17 21:01:30 2017 UTC

# Line 1 | Line 1
1   /*
2   * Written by Doug Lea with assistance from members of JCP JSR-166
3   * Expert Group and released to the public domain, as explained at
4 < * http://creativecommons.org/licenses/publicdomain
4 > * http://creativecommons.org/publicdomain/zero/1.0/
5   * Other contributors include Andrew Wright, Jeffrey Hayes,
6   * Pat Fisher, Mike Judd.
7   */
8  
9 + import static java.util.concurrent.TimeUnit.MILLISECONDS;
10 + import static java.util.concurrent.TimeUnit.NANOSECONDS;
11  
12 < import junit.framework.*;
13 < import java.util.*;
14 < import java.util.concurrent.*;
15 < import java.util.concurrent.locks.*;
16 < import java.io.*;
12 > import java.util.Arrays;
13 > import java.util.Collection;
14 > import java.util.HashSet;
15 > import java.util.concurrent.locks.AbstractQueuedLongSynchronizer;
16 > import java.util.concurrent.locks.AbstractQueuedLongSynchronizer.ConditionObject;
17 >
18 > import junit.framework.AssertionFailedError;
19 > import junit.framework.Test;
20 > import junit.framework.TestSuite;
21  
22 + @SuppressWarnings("WaitNotInLoop") // we implement spurious-wakeup freedom
23   public class AbstractQueuedLongSynchronizerTest extends JSR166TestCase {
24      public static void main(String[] args) {
25 <        junit.textui.TestRunner.run (suite());
25 >        main(suite(), args);
26      }
27      public static Test suite() {
28          return new TestSuite(AbstractQueuedLongSynchronizerTest.class);
29      }
30  
31      /**
32 <     * A simple mutex class, adapted from the
33 <     * AbstractQueuedLongSynchronizer javadoc.  Exclusive acquire tests
27 <     * exercise this as a sample user extension.  Other
28 <     * methods/features of AbstractQueuedLongSynchronizerTest are tested
29 <     * via other test classes, including those for ReentrantLock,
30 <     * ReentrantReadWriteLock, and Semaphore
32 >     * A simple mutex class, adapted from the class javadoc.  Exclusive
33 >     * acquire tests exercise this as a sample user extension.
34       */
35      static class Mutex extends AbstractQueuedLongSynchronizer {
36 <        // Use value > 32 bits for locked state
37 <        static final long LOCKED = 1 << 48;
36 >        /** An eccentric value > 32 bits for locked synchronizer state. */
37 >        static final long LOCKED = (1L << 63) | (1L << 15);
38 >
39 >        static final long UNLOCKED = 0;
40 >
41          public boolean isHeldExclusively() {
42 <            return getState() == LOCKED;
42 >            long state = getState();
43 >            assertTrue(state == UNLOCKED || state == LOCKED);
44 >            return state == LOCKED;
45          }
46  
47          public boolean tryAcquire(long acquires) {
48 <            return compareAndSetState(0, LOCKED);
48 >            assertEquals(LOCKED, acquires);
49 >            return compareAndSetState(UNLOCKED, LOCKED);
50          }
51  
52          public boolean tryRelease(long releases) {
53 <            if (getState() == 0) throw new IllegalMonitorStateException();
54 <            setState(0);
53 >            if (getState() != LOCKED) throw new IllegalMonitorStateException();
54 >            setState(UNLOCKED);
55              return true;
56          }
57  
58 <        public AbstractQueuedLongSynchronizer.ConditionObject newCondition() { return new AbstractQueuedLongSynchronizer.ConditionObject(); }
58 >        public boolean tryAcquireNanos(long nanos) throws InterruptedException {
59 >            return tryAcquireNanos(LOCKED, nanos);
60 >        }
61  
62 <    }
62 >        public boolean tryAcquire() {
63 >            return tryAcquire(LOCKED);
64 >        }
65  
66 +        public boolean tryRelease() {
67 +            return tryRelease(LOCKED);
68 +        }
69 +
70 +        public void acquire() {
71 +            acquire(LOCKED);
72 +        }
73 +
74 +        public void acquireInterruptibly() throws InterruptedException {
75 +            acquireInterruptibly(LOCKED);
76 +        }
77 +
78 +        public void release() {
79 +            release(LOCKED);
80 +        }
81 +
82 +        public ConditionObject newCondition() {
83 +            return new ConditionObject();
84 +        }
85 +    }
86  
87      /**
88       * A simple latch class, to test shared mode.
# Line 58 | Line 91 | public class AbstractQueuedLongSynchroni
91          public boolean isSignalled() { return getState() != 0; }
92  
93          public long tryAcquireShared(long ignore) {
94 <            return isSignalled()? 1 : -1;
94 >            return isSignalled() ? 1 : -1;
95          }
96  
97          public boolean tryReleaseShared(long ignore) {
98 <            setState(1 << 62);
98 >            setState(1L << 62);
99              return true;
100          }
101      }
102  
103      /**
104 <     * A runnable calling acquireInterruptibly
104 >     * A runnable calling acquireInterruptibly that does not expect to
105 >     * be interrupted.
106       */
107 <    class InterruptibleSyncRunnable implements Runnable {
107 >    class InterruptibleSyncRunnable extends CheckedRunnable {
108          final Mutex sync;
109 <        InterruptibleSyncRunnable(Mutex l) { sync = l; }
110 <        public void run() {
111 <            try {
78 <                sync.acquireInterruptibly(1);
79 <            } catch (InterruptedException success) {}
109 >        InterruptibleSyncRunnable(Mutex sync) { this.sync = sync; }
110 >        public void realRun() throws InterruptedException {
111 >            sync.acquireInterruptibly();
112          }
113      }
114  
83
115      /**
116       * A runnable calling acquireInterruptibly that expects to be
117 <     * interrupted
117 >     * interrupted.
118       */
119 <    class InterruptedSyncRunnable implements Runnable {
119 >    class InterruptedSyncRunnable extends CheckedInterruptedRunnable {
120          final Mutex sync;
121 <        InterruptedSyncRunnable(Mutex l) { sync = l; }
122 <        public void run() {
123 <            try {
124 <                sync.acquireInterruptibly(1);
125 <                threadShouldThrow();
126 <            } catch (InterruptedException success) {}
121 >        InterruptedSyncRunnable(Mutex sync) { this.sync = sync; }
122 >        public void realRun() throws InterruptedException {
123 >            sync.acquireInterruptibly();
124 >        }
125 >    }
126 >
127 >    /** A constant to clarify calls to checking methods below. */
128 >    static final Thread[] NO_THREADS = new Thread[0];
129 >
130 >    /**
131 >     * Spin-waits until sync.isQueued(t) becomes true.
132 >     */
133 >    void waitForQueuedThread(AbstractQueuedLongSynchronizer sync,
134 >                             Thread t) {
135 >        long startTime = System.nanoTime();
136 >        while (!sync.isQueued(t)) {
137 >            if (millisElapsedSince(startTime) > LONG_DELAY_MS)
138 >                throw new AssertionFailedError("timed out");
139 >            Thread.yield();
140 >        }
141 >        assertTrue(t.isAlive());
142 >    }
143 >
144 >    /**
145 >     * Checks that sync has exactly the given queued threads.
146 >     */
147 >    void assertHasQueuedThreads(AbstractQueuedLongSynchronizer sync,
148 >                                Thread... expected) {
149 >        Collection<Thread> actual = sync.getQueuedThreads();
150 >        assertEquals(expected.length > 0, sync.hasQueuedThreads());
151 >        assertEquals(expected.length, sync.getQueueLength());
152 >        assertEquals(expected.length, actual.size());
153 >        assertEquals(expected.length == 0, actual.isEmpty());
154 >        assertEquals(new HashSet<Thread>(actual),
155 >                     new HashSet<Thread>(Arrays.asList(expected)));
156 >    }
157 >
158 >    /**
159 >     * Checks that sync has exactly the given (exclusive) queued threads.
160 >     */
161 >    void assertHasExclusiveQueuedThreads(AbstractQueuedLongSynchronizer sync,
162 >                                         Thread... expected) {
163 >        assertHasQueuedThreads(sync, expected);
164 >        assertEquals(new HashSet<Thread>(sync.getExclusiveQueuedThreads()),
165 >                     new HashSet<Thread>(sync.getQueuedThreads()));
166 >        assertEquals(0, sync.getSharedQueuedThreads().size());
167 >        assertTrue(sync.getSharedQueuedThreads().isEmpty());
168 >    }
169 >
170 >    /**
171 >     * Checks that sync has exactly the given (shared) queued threads.
172 >     */
173 >    void assertHasSharedQueuedThreads(AbstractQueuedLongSynchronizer sync,
174 >                                      Thread... expected) {
175 >        assertHasQueuedThreads(sync, expected);
176 >        assertEquals(new HashSet<Thread>(sync.getSharedQueuedThreads()),
177 >                     new HashSet<Thread>(sync.getQueuedThreads()));
178 >        assertEquals(0, sync.getExclusiveQueuedThreads().size());
179 >        assertTrue(sync.getExclusiveQueuedThreads().isEmpty());
180 >    }
181 >
182 >    /**
183 >     * Checks that condition c has exactly the given waiter threads,
184 >     * after acquiring mutex.
185 >     */
186 >    void assertHasWaitersUnlocked(Mutex sync, ConditionObject c,
187 >                                 Thread... threads) {
188 >        sync.acquire();
189 >        assertHasWaitersLocked(sync, c, threads);
190 >        sync.release();
191 >    }
192 >
193 >    /**
194 >     * Checks that condition c has exactly the given waiter threads.
195 >     */
196 >    void assertHasWaitersLocked(Mutex sync, ConditionObject c,
197 >                                Thread... threads) {
198 >        assertEquals(threads.length > 0, sync.hasWaiters(c));
199 >        assertEquals(threads.length, sync.getWaitQueueLength(c));
200 >        assertEquals(threads.length == 0, sync.getWaitingThreads(c).isEmpty());
201 >        assertEquals(threads.length, sync.getWaitingThreads(c).size());
202 >        assertEquals(new HashSet<Thread>(sync.getWaitingThreads(c)),
203 >                     new HashSet<Thread>(Arrays.asList(threads)));
204 >    }
205 >
206 >    enum AwaitMethod { await, awaitTimed, awaitNanos, awaitUntil }
207 >
208 >    /**
209 >     * Awaits condition using the specified AwaitMethod.
210 >     */
211 >    void await(ConditionObject c, AwaitMethod awaitMethod)
212 >            throws InterruptedException {
213 >        long timeoutMillis = 2 * LONG_DELAY_MS;
214 >        switch (awaitMethod) {
215 >        case await:
216 >            c.await();
217 >            break;
218 >        case awaitTimed:
219 >            assertTrue(c.await(timeoutMillis, MILLISECONDS));
220 >            break;
221 >        case awaitNanos:
222 >            long nanosTimeout = MILLISECONDS.toNanos(timeoutMillis);
223 >            long nanosRemaining = c.awaitNanos(nanosTimeout);
224 >            assertTrue(nanosRemaining > 0);
225 >            break;
226 >        case awaitUntil:
227 >            assertTrue(c.awaitUntil(delayedDate(timeoutMillis)));
228 >            break;
229 >        default:
230 >            throw new AssertionError();
231          }
232      }
233  
234      /**
235 +     * Checks that awaiting the given condition times out (using the
236 +     * default timeout duration).
237 +     */
238 +    void assertAwaitTimesOut(ConditionObject c, AwaitMethod awaitMethod) {
239 +        final long timeoutMillis = timeoutMillis();
240 +        final long startTime;
241 +        try {
242 +            switch (awaitMethod) {
243 +            case awaitTimed:
244 +                startTime = System.nanoTime();
245 +                assertFalse(c.await(timeoutMillis, MILLISECONDS));
246 +                assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
247 +                break;
248 +            case awaitNanos:
249 +                startTime = System.nanoTime();
250 +                long nanosTimeout = MILLISECONDS.toNanos(timeoutMillis);
251 +                long nanosRemaining = c.awaitNanos(nanosTimeout);
252 +                assertTrue(nanosRemaining <= 0);
253 +                assertTrue(nanosRemaining > -MILLISECONDS.toNanos(LONG_DELAY_MS));
254 +                assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
255 +                break;
256 +            case awaitUntil:
257 +                // We shouldn't assume that nanoTime and currentTimeMillis
258 +                // use the same time source, so don't use nanoTime here.
259 +                java.util.Date delayedDate = delayedDate(timeoutMillis);
260 +                assertFalse(c.awaitUntil(delayedDate(timeoutMillis)));
261 +                assertTrue(new java.util.Date().getTime() >= delayedDate.getTime());
262 +                break;
263 +            default:
264 +                throw new UnsupportedOperationException();
265 +            }
266 +        } catch (InterruptedException ie) { threadUnexpectedException(ie); }
267 +    }
268 +
269 +    /**
270       * isHeldExclusively is false upon construction
271       */
272      public void testIsHeldExclusively() {
273 <        Mutex rl = new Mutex();
274 <        assertFalse(rl.isHeldExclusively());
273 >        Mutex sync = new Mutex();
274 >        assertFalse(sync.isHeldExclusively());
275      }
276  
277      /**
278       * acquiring released sync succeeds
279       */
280      public void testAcquire() {
281 <        Mutex rl = new Mutex();
282 <        rl.acquire(1);
283 <        assertTrue(rl.isHeldExclusively());
284 <        rl.release(1);
285 <        assertFalse(rl.isHeldExclusively());
281 >        Mutex sync = new Mutex();
282 >        sync.acquire();
283 >        assertTrue(sync.isHeldExclusively());
284 >        sync.release();
285 >        assertFalse(sync.isHeldExclusively());
286      }
287  
288      /**
289 <     * tryAcquire on an released sync succeeds
289 >     * tryAcquire on a released sync succeeds
290       */
291      public void testTryAcquire() {
292 <        Mutex rl = new Mutex();
293 <        assertTrue(rl.tryAcquire(1));
294 <        assertTrue(rl.isHeldExclusively());
295 <        rl.release(1);
292 >        Mutex sync = new Mutex();
293 >        assertTrue(sync.tryAcquire());
294 >        assertTrue(sync.isHeldExclusively());
295 >        sync.release();
296 >        assertFalse(sync.isHeldExclusively());
297      }
298  
299      /**
300       * hasQueuedThreads reports whether there are waiting threads
301       */
302 <    public void testhasQueuedThreads() throws InterruptedException {
303 <        final Mutex sync = new Mutex();
133 <        Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
134 <        Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
302 >    public void testHasQueuedThreads() {
303 >        final Mutex sync = new Mutex();
304          assertFalse(sync.hasQueuedThreads());
305 <        sync.acquire(1);
306 <        t1.start();
307 <        Thread.sleep(SHORT_DELAY_MS);
305 >        sync.acquire();
306 >        Thread t1 = newStartedThread(new InterruptedSyncRunnable(sync));
307 >        waitForQueuedThread(sync, t1);
308          assertTrue(sync.hasQueuedThreads());
309 <        t2.start();
310 <        Thread.sleep(SHORT_DELAY_MS);
309 >        Thread t2 = newStartedThread(new InterruptibleSyncRunnable(sync));
310 >        waitForQueuedThread(sync, t2);
311          assertTrue(sync.hasQueuedThreads());
312          t1.interrupt();
313 <        Thread.sleep(SHORT_DELAY_MS);
313 >        awaitTermination(t1);
314          assertTrue(sync.hasQueuedThreads());
315 <        sync.release(1);
316 <        Thread.sleep(SHORT_DELAY_MS);
315 >        sync.release();
316 >        awaitTermination(t2);
317          assertFalse(sync.hasQueuedThreads());
149        t1.join();
150        t2.join();
318      }
319  
320      /**
321 <     * isQueued(null) throws NPE
321 >     * isQueued(null) throws NullPointerException
322       */
323      public void testIsQueuedNPE() {
324 <        final Mutex sync = new Mutex();
324 >        final Mutex sync = new Mutex();
325          try {
326              sync.isQueued(null);
327              shouldThrow();
# Line 162 | Line 329 | public class AbstractQueuedLongSynchroni
329      }
330  
331      /**
332 <     * isQueued reports whether a thread is queued.
332 >     * isQueued reports whether a thread is queued
333       */
334 <    public void testIsQueued() throws InterruptedException {
335 <        final Mutex sync = new Mutex();
334 >    public void testIsQueued() {
335 >        final Mutex sync = new Mutex();
336          Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
337          Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
338          assertFalse(sync.isQueued(t1));
339          assertFalse(sync.isQueued(t2));
340 <        sync.acquire(1);
340 >        sync.acquire();
341          t1.start();
342 <        Thread.sleep(SHORT_DELAY_MS);
342 >        waitForQueuedThread(sync, t1);
343          assertTrue(sync.isQueued(t1));
344 +        assertFalse(sync.isQueued(t2));
345          t2.start();
346 <        Thread.sleep(SHORT_DELAY_MS);
346 >        waitForQueuedThread(sync, t2);
347          assertTrue(sync.isQueued(t1));
348          assertTrue(sync.isQueued(t2));
349          t1.interrupt();
350 <        Thread.sleep(SHORT_DELAY_MS);
350 >        awaitTermination(t1);
351          assertFalse(sync.isQueued(t1));
352          assertTrue(sync.isQueued(t2));
353 <        sync.release(1);
354 <        Thread.sleep(SHORT_DELAY_MS);
353 >        sync.release();
354 >        awaitTermination(t2);
355          assertFalse(sync.isQueued(t1));
188        Thread.sleep(SHORT_DELAY_MS);
356          assertFalse(sync.isQueued(t2));
190        t1.join();
191        t2.join();
357      }
358  
359      /**
360       * getFirstQueuedThread returns first waiting thread or null if none
361       */
362 <    public void testGetFirstQueuedThread() throws InterruptedException {
363 <        final Mutex sync = new Mutex();
199 <        Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
200 <        Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
362 >    public void testGetFirstQueuedThread() {
363 >        final Mutex sync = new Mutex();
364          assertNull(sync.getFirstQueuedThread());
365 <        sync.acquire(1);
366 <        t1.start();
367 <        Thread.sleep(SHORT_DELAY_MS);
365 >        sync.acquire();
366 >        Thread t1 = newStartedThread(new InterruptedSyncRunnable(sync));
367 >        waitForQueuedThread(sync, t1);
368          assertEquals(t1, sync.getFirstQueuedThread());
369 <        t2.start();
370 <        Thread.sleep(SHORT_DELAY_MS);
369 >        Thread t2 = newStartedThread(new InterruptibleSyncRunnable(sync));
370 >        waitForQueuedThread(sync, t2);
371          assertEquals(t1, sync.getFirstQueuedThread());
372          t1.interrupt();
373 <        Thread.sleep(SHORT_DELAY_MS);
211 <        Thread.sleep(SHORT_DELAY_MS);
373 >        awaitTermination(t1);
374          assertEquals(t2, sync.getFirstQueuedThread());
375 <        sync.release(1);
376 <        Thread.sleep(SHORT_DELAY_MS);
375 >        sync.release();
376 >        awaitTermination(t2);
377          assertNull(sync.getFirstQueuedThread());
216        t1.join();
217        t2.join();
378      }
379  
220
380      /**
381       * hasContended reports false if no thread has ever blocked, else true
382       */
383 <    public void testHasContended() throws InterruptedException {
384 <        final Mutex sync = new Mutex();
226 <        Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
227 <        Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
383 >    public void testHasContended() {
384 >        final Mutex sync = new Mutex();
385          assertFalse(sync.hasContended());
386 <        sync.acquire(1);
387 <        t1.start();
388 <        Thread.sleep(SHORT_DELAY_MS);
386 >        sync.acquire();
387 >        assertFalse(sync.hasContended());
388 >        Thread t1 = newStartedThread(new InterruptedSyncRunnable(sync));
389 >        waitForQueuedThread(sync, t1);
390          assertTrue(sync.hasContended());
391 <        t2.start();
392 <        Thread.sleep(SHORT_DELAY_MS);
391 >        Thread t2 = newStartedThread(new InterruptibleSyncRunnable(sync));
392 >        waitForQueuedThread(sync, t2);
393          assertTrue(sync.hasContended());
394          t1.interrupt();
395 <        Thread.sleep(SHORT_DELAY_MS);
395 >        awaitTermination(t1);
396          assertTrue(sync.hasContended());
397 <        sync.release(1);
398 <        Thread.sleep(SHORT_DELAY_MS);
397 >        sync.release();
398 >        awaitTermination(t2);
399          assertTrue(sync.hasContended());
242        t1.join();
243        t2.join();
400      }
401  
402      /**
403 <     * getQueuedThreads includes waiting threads
403 >     * getQueuedThreads returns all waiting threads
404       */
405 <    public void testGetQueuedThreads() throws InterruptedException {
406 <        final Mutex sync = new Mutex();
405 >    public void testGetQueuedThreads() {
406 >        final Mutex sync = new Mutex();
407          Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
408          Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
409 <        assertTrue(sync.getQueuedThreads().isEmpty());
410 <        sync.acquire(1);
411 <        assertTrue(sync.getQueuedThreads().isEmpty());
409 >        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
410 >        sync.acquire();
411 >        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
412          t1.start();
413 <        Thread.sleep(SHORT_DELAY_MS);
413 >        waitForQueuedThread(sync, t1);
414 >        assertHasExclusiveQueuedThreads(sync, t1);
415          assertTrue(sync.getQueuedThreads().contains(t1));
416 +        assertFalse(sync.getQueuedThreads().contains(t2));
417          t2.start();
418 <        Thread.sleep(SHORT_DELAY_MS);
418 >        waitForQueuedThread(sync, t2);
419 >        assertHasExclusiveQueuedThreads(sync, t1, t2);
420          assertTrue(sync.getQueuedThreads().contains(t1));
421          assertTrue(sync.getQueuedThreads().contains(t2));
422          t1.interrupt();
423 <        Thread.sleep(SHORT_DELAY_MS);
424 <        assertFalse(sync.getQueuedThreads().contains(t1));
425 <        assertTrue(sync.getQueuedThreads().contains(t2));
426 <        sync.release(1);
427 <        Thread.sleep(SHORT_DELAY_MS);
269 <        assertTrue(sync.getQueuedThreads().isEmpty());
270 <        t1.join();
271 <        t2.join();
423 >        awaitTermination(t1);
424 >        assertHasExclusiveQueuedThreads(sync, t2);
425 >        sync.release();
426 >        awaitTermination(t2);
427 >        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
428      }
429  
430      /**
431 <     * getExclusiveQueuedThreads includes waiting threads
431 >     * getExclusiveQueuedThreads returns all exclusive waiting threads
432       */
433 <    public void testGetExclusiveQueuedThreads() throws InterruptedException {
434 <        final Mutex sync = new Mutex();
433 >    public void testGetExclusiveQueuedThreads() {
434 >        final Mutex sync = new Mutex();
435          Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
436          Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
437 <        assertTrue(sync.getExclusiveQueuedThreads().isEmpty());
438 <        sync.acquire(1);
439 <        assertTrue(sync.getExclusiveQueuedThreads().isEmpty());
437 >        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
438 >        sync.acquire();
439 >        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
440          t1.start();
441 <        Thread.sleep(SHORT_DELAY_MS);
441 >        waitForQueuedThread(sync, t1);
442 >        assertHasExclusiveQueuedThreads(sync, t1);
443          assertTrue(sync.getExclusiveQueuedThreads().contains(t1));
444 +        assertFalse(sync.getExclusiveQueuedThreads().contains(t2));
445          t2.start();
446 <        Thread.sleep(SHORT_DELAY_MS);
446 >        waitForQueuedThread(sync, t2);
447 >        assertHasExclusiveQueuedThreads(sync, t1, t2);
448          assertTrue(sync.getExclusiveQueuedThreads().contains(t1));
449          assertTrue(sync.getExclusiveQueuedThreads().contains(t2));
450          t1.interrupt();
451 <        Thread.sleep(SHORT_DELAY_MS);
452 <        assertFalse(sync.getExclusiveQueuedThreads().contains(t1));
453 <        assertTrue(sync.getExclusiveQueuedThreads().contains(t2));
454 <        sync.release(1);
455 <        Thread.sleep(SHORT_DELAY_MS);
297 <        assertTrue(sync.getExclusiveQueuedThreads().isEmpty());
298 <        t1.join();
299 <        t2.join();
451 >        awaitTermination(t1);
452 >        assertHasExclusiveQueuedThreads(sync, t2);
453 >        sync.release();
454 >        awaitTermination(t2);
455 >        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
456      }
457  
458      /**
459       * getSharedQueuedThreads does not include exclusively waiting threads
460       */
461 <    public void testGetSharedQueuedThreads() throws InterruptedException {
462 <        final Mutex sync = new Mutex();
307 <        Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
308 <        Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
461 >    public void testGetSharedQueuedThreads_Exclusive() {
462 >        final Mutex sync = new Mutex();
463          assertTrue(sync.getSharedQueuedThreads().isEmpty());
464 <        sync.acquire(1);
464 >        sync.acquire();
465          assertTrue(sync.getSharedQueuedThreads().isEmpty());
466 <        t1.start();
467 <        Thread.sleep(SHORT_DELAY_MS);
466 >        Thread t1 = newStartedThread(new InterruptedSyncRunnable(sync));
467 >        waitForQueuedThread(sync, t1);
468          assertTrue(sync.getSharedQueuedThreads().isEmpty());
469 <        t2.start();
470 <        Thread.sleep(SHORT_DELAY_MS);
469 >        Thread t2 = newStartedThread(new InterruptibleSyncRunnable(sync));
470 >        waitForQueuedThread(sync, t2);
471          assertTrue(sync.getSharedQueuedThreads().isEmpty());
472          t1.interrupt();
473 <        Thread.sleep(SHORT_DELAY_MS);
473 >        awaitTermination(t1);
474          assertTrue(sync.getSharedQueuedThreads().isEmpty());
475 <        sync.release(1);
476 <        Thread.sleep(SHORT_DELAY_MS);
475 >        sync.release();
476 >        awaitTermination(t2);
477          assertTrue(sync.getSharedQueuedThreads().isEmpty());
324        t1.join();
325        t2.join();
478      }
479  
480      /**
481 <     * tryAcquireNanos is interruptible.
481 >     * getSharedQueuedThreads returns all shared waiting threads
482 >     */
483 >    public void testGetSharedQueuedThreads_Shared() {
484 >        final BooleanLatch l = new BooleanLatch();
485 >        assertHasSharedQueuedThreads(l, NO_THREADS);
486 >        Thread t1 = newStartedThread(new CheckedInterruptedRunnable() {
487 >            public void realRun() throws InterruptedException {
488 >                l.acquireSharedInterruptibly(0);
489 >            }});
490 >        waitForQueuedThread(l, t1);
491 >        assertHasSharedQueuedThreads(l, t1);
492 >        Thread t2 = newStartedThread(new CheckedRunnable() {
493 >            public void realRun() throws InterruptedException {
494 >                l.acquireSharedInterruptibly(0);
495 >            }});
496 >        waitForQueuedThread(l, t2);
497 >        assertHasSharedQueuedThreads(l, t1, t2);
498 >        t1.interrupt();
499 >        awaitTermination(t1);
500 >        assertHasSharedQueuedThreads(l, t2);
501 >        assertTrue(l.releaseShared(0));
502 >        awaitTermination(t2);
503 >        assertHasSharedQueuedThreads(l, NO_THREADS);
504 >    }
505 >
506 >    /**
507 >     * tryAcquireNanos is interruptible
508       */
509 <    public void testInterruptedException2() throws InterruptedException {
510 <        final Mutex sync = new Mutex();
511 <        sync.acquire(1);
512 <        Thread t = new Thread(new Runnable() {
513 <                public void run() {
514 <                    try {
515 <                        sync.tryAcquireNanos(1, MEDIUM_DELAY_MS * 1000 * 1000);
338 <                        threadShouldThrow();
339 <                    } catch (InterruptedException success) {}
340 <                }
341 <            });
509 >    public void testTryAcquireNanos_Interruptible() {
510 >        final Mutex sync = new Mutex();
511 >        sync.acquire();
512 >        Thread t = newStartedThread(new CheckedInterruptedRunnable() {
513 >            public void realRun() throws InterruptedException {
514 >                sync.tryAcquireNanos(MILLISECONDS.toNanos(2 * LONG_DELAY_MS));
515 >            }});
516  
517 <        t.start();
517 >        waitForQueuedThread(sync, t);
518          t.interrupt();
519 <        t.join();
519 >        awaitTermination(t);
520      }
521  
348
522      /**
523 <     * TryAcquire on exclusively held sync fails
523 >     * tryAcquire on exclusively held sync fails
524       */
525 <    public void testTryAcquireWhenSynced() throws InterruptedException {
526 <        final Mutex sync = new Mutex();
527 <        sync.acquire(1);
528 <        Thread t = new Thread(new Runnable() {
529 <                public void run() {
530 <                    threadAssertFalse(sync.tryAcquire(1));
531 <                }
359 <            });
525 >    public void testTryAcquireWhenSynced() {
526 >        final Mutex sync = new Mutex();
527 >        sync.acquire();
528 >        Thread t = newStartedThread(new CheckedRunnable() {
529 >            public void realRun() {
530 >                assertFalse(sync.tryAcquire());
531 >            }});
532  
533 <        t.start();
534 <        t.join();
363 <        sync.release(1);
533 >        awaitTermination(t);
534 >        sync.release();
535      }
536  
537      /**
538       * tryAcquireNanos on an exclusively held sync times out
539       */
540 <    public void testAcquireNanos_Timeout() throws InterruptedException {
541 <        final Mutex sync = new Mutex();
542 <        sync.acquire(1);
543 <        Thread t = new Thread(new Runnable() {
544 <                public void run() {
545 <                    try {
546 <                        threadAssertFalse(sync.tryAcquireNanos(1, 1000 * 1000));
547 <                    } catch (Exception ex) {
548 <                        threadUnexpectedException(ex);
549 <                    }
379 <                }
380 <            });
381 <
382 <        t.start();
383 <        t.join();
384 <        sync.release(1);
385 <    }
540 >    public void testAcquireNanos_Timeout() {
541 >        final Mutex sync = new Mutex();
542 >        sync.acquire();
543 >        Thread t = newStartedThread(new CheckedRunnable() {
544 >            public void realRun() throws InterruptedException {
545 >                long startTime = System.nanoTime();
546 >                long nanos = MILLISECONDS.toNanos(timeoutMillis());
547 >                assertFalse(sync.tryAcquireNanos(nanos));
548 >                assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
549 >            }});
550  
551 +        awaitTermination(t);
552 +        sync.release();
553 +    }
554  
555      /**
556       * getState is true when acquired and false when not
557       */
558 <    public void testGetState() throws InterruptedException {
559 <        final Mutex sync = new Mutex();
560 <        sync.acquire(1);
394 <        assertTrue(sync.isHeldExclusively());
395 <        sync.release(1);
396 <        assertFalse(sync.isHeldExclusively());
397 <        Thread t = new Thread(new Runnable() {
398 <                public void run() {
399 <                    sync.acquire(1);
400 <                    try {
401 <                        Thread.sleep(SMALL_DELAY_MS);
402 <                    }
403 <                    catch (Exception e) {
404 <                        threadUnexpectedException(e);
405 <                    }
406 <                    sync.release(1);
407 <                }
408 <            });
409 <
410 <        t.start();
411 <        Thread.sleep(SHORT_DELAY_MS);
558 >    public void testGetState() {
559 >        final Mutex sync = new Mutex();
560 >        sync.acquire();
561          assertTrue(sync.isHeldExclusively());
562 <        t.join();
562 >        sync.release();
563          assertFalse(sync.isHeldExclusively());
415    }
564  
565 +        final BooleanLatch acquired = new BooleanLatch();
566 +        final BooleanLatch done = new BooleanLatch();
567 +        Thread t = newStartedThread(new CheckedRunnable() {
568 +            public void realRun() throws InterruptedException {
569 +                sync.acquire();
570 +                assertTrue(acquired.releaseShared(0));
571 +                done.acquireShared(0);
572 +                sync.release();
573 +            }});
574  
575 <    /**
576 <     * acquireInterruptibly is interruptible.
577 <     */
578 <    public void testAcquireInterruptibly1() throws InterruptedException {
579 <        final Mutex sync = new Mutex();
423 <        sync.acquire(1);
424 <        Thread t = new Thread(new InterruptedSyncRunnable(sync));
425 <        t.start();
426 <        Thread.sleep(SHORT_DELAY_MS);
427 <        t.interrupt();
428 <        Thread.sleep(SHORT_DELAY_MS);
429 <        sync.release(1);
430 <        t.join();
575 >        acquired.acquireShared(0);
576 >        assertTrue(sync.isHeldExclusively());
577 >        assertTrue(done.releaseShared(0));
578 >        awaitTermination(t);
579 >        assertFalse(sync.isHeldExclusively());
580      }
581  
582      /**
583       * acquireInterruptibly succeeds when released, else is interruptible
584       */
585 <    public void testAcquireInterruptibly2() throws InterruptedException {
586 <        final Mutex sync = new Mutex();
587 <        sync.acquireInterruptibly(1);
588 <        Thread t = new Thread(new InterruptedSyncRunnable(sync));
589 <        t.start();
585 >    public void testAcquireInterruptibly() throws InterruptedException {
586 >        final Mutex sync = new Mutex();
587 >        final BooleanLatch threadStarted = new BooleanLatch();
588 >        sync.acquireInterruptibly();
589 >        Thread t = newStartedThread(new CheckedInterruptedRunnable() {
590 >            public void realRun() throws InterruptedException {
591 >                assertTrue(threadStarted.releaseShared(0));
592 >                sync.acquireInterruptibly();
593 >            }});
594 >
595 >        threadStarted.acquireShared(0);
596 >        waitForQueuedThread(sync, t);
597          t.interrupt();
598 +        awaitTermination(t);
599          assertTrue(sync.isHeldExclusively());
443        t.join();
600      }
601  
602      /**
603       * owns is true for a condition created by sync else false
604       */
605      public void testOwns() {
606 <        final Mutex sync = new Mutex();
607 <        final AbstractQueuedLongSynchronizer.ConditionObject c = sync.newCondition();
606 >        final Mutex sync = new Mutex();
607 >        final ConditionObject c = sync.newCondition();
608          final Mutex sync2 = new Mutex();
609          assertTrue(sync.owns(c));
610          assertFalse(sync2.owns(c));
# Line 457 | Line 613 | public class AbstractQueuedLongSynchroni
613      /**
614       * Calling await without holding sync throws IllegalMonitorStateException
615       */
616 <    public void testAwait_IllegalMonitor() throws InterruptedException {
617 <        final Mutex sync = new Mutex();
618 <        final AbstractQueuedLongSynchronizer.ConditionObject c = sync.newCondition();
619 <        try {
620 <            c.await();
621 <            shouldThrow();
622 <        }
623 <        catch (IllegalMonitorStateException success) {
616 >    public void testAwait_IMSE() {
617 >        final Mutex sync = new Mutex();
618 >        final ConditionObject c = sync.newCondition();
619 >        for (AwaitMethod awaitMethod : AwaitMethod.values()) {
620 >            long startTime = System.nanoTime();
621 >            try {
622 >                await(c, awaitMethod);
623 >                shouldThrow();
624 >            } catch (IllegalMonitorStateException success) {
625 >            } catch (InterruptedException e) { threadUnexpectedException(e); }
626 >            assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
627          }
628      }
629  
630      /**
631       * Calling signal without holding sync throws IllegalMonitorStateException
632       */
633 <    public void testSignal_IllegalMonitor() throws InterruptedException {
634 <        final Mutex sync = new Mutex();
635 <        final AbstractQueuedLongSynchronizer.ConditionObject c = sync.newCondition();
633 >    public void testSignal_IMSE() {
634 >        final Mutex sync = new Mutex();
635 >        final ConditionObject c = sync.newCondition();
636          try {
637              c.signal();
638              shouldThrow();
639 <        }
640 <        catch (IllegalMonitorStateException success) {}
482 <    }
483 <
484 <    /**
485 <     * awaitNanos without a signal times out
486 <     */
487 <    public void testAwaitNanos_Timeout() throws InterruptedException {
488 <        final Mutex sync = new Mutex();
489 <        final AbstractQueuedLongSynchronizer.ConditionObject c = sync.newCondition();
490 <        sync.acquire(1);
491 <        long t = c.awaitNanos(100);
492 <        assertTrue(t <= 0);
493 <        sync.release(1);
639 >        } catch (IllegalMonitorStateException success) {}
640 >        assertHasWaitersUnlocked(sync, c, NO_THREADS);
641      }
642  
643      /**
644 <     *  Timed await without a signal times out
644 >     * Calling signalAll without holding sync throws IllegalMonitorStateException
645       */
646 <    public void testAwait_Timeout() throws InterruptedException {
647 <        final Mutex sync = new Mutex();
648 <        final AbstractQueuedLongSynchronizer.ConditionObject c = sync.newCondition();
649 <        sync.acquire(1);
650 <        assertFalse(c.await(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
651 <        sync.release(1);
646 >    public void testSignalAll_IMSE() {
647 >        final Mutex sync = new Mutex();
648 >        final ConditionObject c = sync.newCondition();
649 >        try {
650 >            c.signalAll();
651 >            shouldThrow();
652 >        } catch (IllegalMonitorStateException success) {}
653      }
654  
655      /**
656 <     * awaitUntil without a signal times out
656 >     * await/awaitNanos/awaitUntil without a signal times out
657       */
658 <    public void testAwaitUntil_Timeout() throws InterruptedException {
659 <        final Mutex sync = new Mutex();
660 <        final AbstractQueuedLongSynchronizer.ConditionObject c = sync.newCondition();
661 <        sync.acquire(1);
662 <        java.util.Date d = new java.util.Date();
663 <        assertFalse(c.awaitUntil(new java.util.Date(d.getTime() + 10)));
664 <        sync.release(1);
658 >    public void testAwaitTimed_Timeout() { testAwait_Timeout(AwaitMethod.awaitTimed); }
659 >    public void testAwaitNanos_Timeout() { testAwait_Timeout(AwaitMethod.awaitNanos); }
660 >    public void testAwaitUntil_Timeout() { testAwait_Timeout(AwaitMethod.awaitUntil); }
661 >    public void testAwait_Timeout(AwaitMethod awaitMethod) {
662 >        final Mutex sync = new Mutex();
663 >        final ConditionObject c = sync.newCondition();
664 >        sync.acquire();
665 >        assertAwaitTimesOut(c, awaitMethod);
666 >        sync.release();
667      }
668  
669      /**
670 <     * await returns when signalled
671 <     */
672 <    public void testAwait() throws InterruptedException {
673 <        final Mutex sync = new Mutex();
674 <        final AbstractQueuedLongSynchronizer.ConditionObject c = sync.newCondition();
675 <        Thread t = new Thread(new Runnable() {
676 <                public void run() {
677 <                    try {
678 <                        sync.acquire(1);
679 <                        c.await();
680 <                        sync.release(1);
681 <                    }
682 <                    catch (InterruptedException e) {
683 <                        threadUnexpectedException(e);
684 <                    }
685 <                }
686 <            });
687 <
688 <        t.start();
689 <        Thread.sleep(SHORT_DELAY_MS);
690 <        sync.acquire(1);
670 >     * await/awaitNanos/awaitUntil returns when signalled
671 >     */
672 >    public void testSignal_await()      { testSignal(AwaitMethod.await); }
673 >    public void testSignal_awaitTimed() { testSignal(AwaitMethod.awaitTimed); }
674 >    public void testSignal_awaitNanos() { testSignal(AwaitMethod.awaitNanos); }
675 >    public void testSignal_awaitUntil() { testSignal(AwaitMethod.awaitUntil); }
676 >    public void testSignal(final AwaitMethod awaitMethod) {
677 >        final Mutex sync = new Mutex();
678 >        final ConditionObject c = sync.newCondition();
679 >        final BooleanLatch acquired = new BooleanLatch();
680 >        Thread t = newStartedThread(new CheckedRunnable() {
681 >            public void realRun() throws InterruptedException {
682 >                sync.acquire();
683 >                assertTrue(acquired.releaseShared(0));
684 >                await(c, awaitMethod);
685 >                sync.release();
686 >            }});
687 >
688 >        acquired.acquireShared(0);
689 >        sync.acquire();
690 >        assertHasWaitersLocked(sync, c, t);
691 >        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
692          c.signal();
693 <        sync.release(1);
694 <        t.join(SHORT_DELAY_MS);
695 <        assertFalse(t.isAlive());
693 >        assertHasWaitersLocked(sync, c, NO_THREADS);
694 >        assertHasExclusiveQueuedThreads(sync, t);
695 >        sync.release();
696 >        awaitTermination(t);
697      }
698  
547
548
699      /**
700 <     * hasWaiters throws NPE if null
700 >     * hasWaiters(null) throws NullPointerException
701       */
702      public void testHasWaitersNPE() {
703 <        final Mutex sync = new Mutex();
703 >        final Mutex sync = new Mutex();
704          try {
705              sync.hasWaiters(null);
706              shouldThrow();
# Line 558 | Line 708 | public class AbstractQueuedLongSynchroni
708      }
709  
710      /**
711 <     * getWaitQueueLength throws NPE if null
711 >     * getWaitQueueLength(null) throws NullPointerException
712       */
713      public void testGetWaitQueueLengthNPE() {
714 <        final Mutex sync = new Mutex();
714 >        final Mutex sync = new Mutex();
715          try {
716              sync.getWaitQueueLength(null);
717              shouldThrow();
718          } catch (NullPointerException success) {}
719      }
720  
571
721      /**
722       * getWaitingThreads throws NPE if null
723       */
724      public void testGetWaitingThreadsNPE() {
725 <        final Mutex sync = new Mutex();
725 >        final Mutex sync = new Mutex();
726          try {
727              sync.getWaitingThreads(null);
728              shouldThrow();
729          } catch (NullPointerException success) {}
730      }
731  
583
732      /**
733 <     * hasWaiters throws IAE if not owned
733 >     * hasWaiters throws IllegalArgumentException if not owned
734       */
735      public void testHasWaitersIAE() {
736 <        final Mutex sync = new Mutex();
737 <        final AbstractQueuedLongSynchronizer.ConditionObject c = sync.newCondition();
738 <        final Mutex sync2 = new Mutex();
736 >        final Mutex sync = new Mutex();
737 >        final ConditionObject c = sync.newCondition();
738 >        final Mutex sync2 = new Mutex();
739          try {
740              sync2.hasWaiters(c);
741              shouldThrow();
742          } catch (IllegalArgumentException success) {}
743 +        assertHasWaitersUnlocked(sync, c, NO_THREADS);
744      }
745  
746      /**
747 <     * hasWaiters throws IMSE if not synced
747 >     * hasWaiters throws IllegalMonitorStateException if not synced
748       */
749      public void testHasWaitersIMSE() {
750 <        final Mutex sync = new Mutex();
751 <        final AbstractQueuedLongSynchronizer.ConditionObject c = sync.newCondition();
750 >        final Mutex sync = new Mutex();
751 >        final ConditionObject c = sync.newCondition();
752          try {
753              sync.hasWaiters(c);
754              shouldThrow();
755          } catch (IllegalMonitorStateException success) {}
756 +        assertHasWaitersUnlocked(sync, c, NO_THREADS);
757      }
758  
609
759      /**
760 <     * getWaitQueueLength throws IAE if not owned
760 >     * getWaitQueueLength throws IllegalArgumentException if not owned
761       */
762      public void testGetWaitQueueLengthIAE() {
763 <        final Mutex sync = new Mutex();
764 <        final AbstractQueuedLongSynchronizer.ConditionObject c = sync.newCondition();
765 <        final Mutex sync2 = new Mutex();
763 >        final Mutex sync = new Mutex();
764 >        final ConditionObject c = sync.newCondition();
765 >        final Mutex sync2 = new Mutex();
766          try {
767              sync2.getWaitQueueLength(c);
768              shouldThrow();
769          } catch (IllegalArgumentException success) {}
770 +        assertHasWaitersUnlocked(sync, c, NO_THREADS);
771      }
772  
773      /**
774 <     * getWaitQueueLength throws IMSE if not synced
774 >     * getWaitQueueLength throws IllegalMonitorStateException if not synced
775       */
776      public void testGetWaitQueueLengthIMSE() {
777 <        final Mutex sync = new Mutex();
778 <        final AbstractQueuedLongSynchronizer.ConditionObject c = sync.newCondition();
777 >        final Mutex sync = new Mutex();
778 >        final ConditionObject c = sync.newCondition();
779          try {
780              sync.getWaitQueueLength(c);
781              shouldThrow();
782          } catch (IllegalMonitorStateException success) {}
783 +        assertHasWaitersUnlocked(sync, c, NO_THREADS);
784      }
785  
635
786      /**
787 <     * getWaitingThreads throws IAE if not owned
787 >     * getWaitingThreads throws IllegalArgumentException if not owned
788       */
789      public void testGetWaitingThreadsIAE() {
790 <        final Mutex sync = new Mutex();
791 <        final AbstractQueuedLongSynchronizer.ConditionObject c = sync.newCondition();
792 <        final Mutex sync2 = new Mutex();
790 >        final Mutex sync = new Mutex();
791 >        final ConditionObject c = sync.newCondition();
792 >        final Mutex sync2 = new Mutex();
793          try {
794              sync2.getWaitingThreads(c);
795              shouldThrow();
796          } catch (IllegalArgumentException success) {}
797 +        assertHasWaitersUnlocked(sync, c, NO_THREADS);
798      }
799  
800      /**
801 <     * getWaitingThreads throws IMSE if not synced
801 >     * getWaitingThreads throws IllegalMonitorStateException if not synced
802       */
803      public void testGetWaitingThreadsIMSE() {
804 <        final Mutex sync = new Mutex();
805 <        final AbstractQueuedLongSynchronizer.ConditionObject c = sync.newCondition();
804 >        final Mutex sync = new Mutex();
805 >        final ConditionObject c = sync.newCondition();
806          try {
807              sync.getWaitingThreads(c);
808              shouldThrow();
809          } catch (IllegalMonitorStateException success) {}
810 +        assertHasWaitersUnlocked(sync, c, NO_THREADS);
811      }
812  
661
662
813      /**
814       * hasWaiters returns true when a thread is waiting, else false
815       */
816 <    public void testHasWaiters() throws InterruptedException {
817 <        final Mutex sync = new Mutex();
818 <        final AbstractQueuedLongSynchronizer.ConditionObject c = sync.newCondition();
819 <        Thread t = new Thread(new Runnable() {
820 <                public void run() {
821 <                    try {
822 <                        sync.acquire(1);
823 <                        threadAssertFalse(sync.hasWaiters(c));
824 <                        threadAssertEquals(0, sync.getWaitQueueLength(c));
825 <                        c.await();
826 <                        sync.release(1);
827 <                    }
828 <                    catch (InterruptedException e) {
829 <                        threadUnexpectedException(e);
830 <                    }
831 <                }
832 <            });
833 <
684 <        t.start();
685 <        Thread.sleep(SHORT_DELAY_MS);
686 <        sync.acquire(1);
816 >    public void testHasWaiters() {
817 >        final Mutex sync = new Mutex();
818 >        final ConditionObject c = sync.newCondition();
819 >        final BooleanLatch acquired = new BooleanLatch();
820 >        Thread t = newStartedThread(new CheckedRunnable() {
821 >            public void realRun() throws InterruptedException {
822 >                sync.acquire();
823 >                assertHasWaitersLocked(sync, c, NO_THREADS);
824 >                assertFalse(sync.hasWaiters(c));
825 >                assertTrue(acquired.releaseShared(0));
826 >                c.await();
827 >                sync.release();
828 >            }});
829 >
830 >        acquired.acquireShared(0);
831 >        sync.acquire();
832 >        assertHasWaitersLocked(sync, c, t);
833 >        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
834          assertTrue(sync.hasWaiters(c));
688        assertEquals(1, sync.getWaitQueueLength(c));
835          c.signal();
836 <        sync.release(1);
837 <        Thread.sleep(SHORT_DELAY_MS);
692 <        sync.acquire(1);
836 >        assertHasWaitersLocked(sync, c, NO_THREADS);
837 >        assertHasExclusiveQueuedThreads(sync, t);
838          assertFalse(sync.hasWaiters(c));
839 <        assertEquals(0, sync.getWaitQueueLength(c));
840 <        sync.release(1);
841 <        t.join(SHORT_DELAY_MS);
842 <        assertFalse(t.isAlive());
839 >        sync.release();
840 >
841 >        awaitTermination(t);
842 >        assertHasWaitersUnlocked(sync, c, NO_THREADS);
843      }
844  
845      /**
846       * getWaitQueueLength returns number of waiting threads
847       */
848 <    public void testGetWaitQueueLength() throws InterruptedException {
849 <        final Mutex sync = new Mutex();
850 <        final AbstractQueuedLongSynchronizer.ConditionObject c = sync.newCondition();
851 <        Thread t1 = new Thread(new Runnable() {
852 <                public void run() {
853 <                    try {
854 <                        sync.acquire(1);
855 <                        threadAssertFalse(sync.hasWaiters(c));
856 <                        threadAssertEquals(0, sync.getWaitQueueLength(c));
857 <                        c.await();
858 <                        sync.release(1);
859 <                    }
860 <                    catch (InterruptedException e) {
861 <                        threadUnexpectedException(e);
862 <                    }
863 <                }
864 <            });
865 <
866 <        Thread t2 = new Thread(new Runnable() {
722 <                public void run() {
723 <                    try {
724 <                        sync.acquire(1);
725 <                        threadAssertTrue(sync.hasWaiters(c));
726 <                        threadAssertEquals(1, sync.getWaitQueueLength(c));
727 <                        c.await();
728 <                        sync.release(1);
729 <                    }
730 <                    catch (InterruptedException e) {
731 <                        threadUnexpectedException(e);
732 <                    }
733 <                }
734 <            });
848 >    public void testGetWaitQueueLength() {
849 >        final Mutex sync = new Mutex();
850 >        final ConditionObject c = sync.newCondition();
851 >        final BooleanLatch acquired1 = new BooleanLatch();
852 >        final BooleanLatch acquired2 = new BooleanLatch();
853 >        final Thread t1 = newStartedThread(new CheckedRunnable() {
854 >            public void realRun() throws InterruptedException {
855 >                sync.acquire();
856 >                assertHasWaitersLocked(sync, c, NO_THREADS);
857 >                assertEquals(0, sync.getWaitQueueLength(c));
858 >                assertTrue(acquired1.releaseShared(0));
859 >                c.await();
860 >                sync.release();
861 >            }});
862 >        acquired1.acquireShared(0);
863 >        sync.acquire();
864 >        assertHasWaitersLocked(sync, c, t1);
865 >        assertEquals(1, sync.getWaitQueueLength(c));
866 >        sync.release();
867  
868 <        t1.start();
869 <        Thread.sleep(SHORT_DELAY_MS);
870 <        t2.start();
871 <        Thread.sleep(SHORT_DELAY_MS);
872 <        sync.acquire(1);
873 <        assertTrue(sync.hasWaiters(c));
868 >        final Thread t2 = newStartedThread(new CheckedRunnable() {
869 >            public void realRun() throws InterruptedException {
870 >                sync.acquire();
871 >                assertHasWaitersLocked(sync, c, t1);
872 >                assertEquals(1, sync.getWaitQueueLength(c));
873 >                assertTrue(acquired2.releaseShared(0));
874 >                c.await();
875 >                sync.release();
876 >            }});
877 >        acquired2.acquireShared(0);
878 >        sync.acquire();
879 >        assertHasWaitersLocked(sync, c, t1, t2);
880 >        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
881          assertEquals(2, sync.getWaitQueueLength(c));
882          c.signalAll();
883 <        sync.release(1);
884 <        Thread.sleep(SHORT_DELAY_MS);
746 <        sync.acquire(1);
747 <        assertFalse(sync.hasWaiters(c));
883 >        assertHasWaitersLocked(sync, c, NO_THREADS);
884 >        assertHasExclusiveQueuedThreads(sync, t1, t2);
885          assertEquals(0, sync.getWaitQueueLength(c));
886 <        sync.release(1);
887 <        t1.join(SHORT_DELAY_MS);
888 <        t2.join(SHORT_DELAY_MS);
889 <        assertFalse(t1.isAlive());
890 <        assertFalse(t2.isAlive());
886 >        sync.release();
887 >
888 >        awaitTermination(t1);
889 >        awaitTermination(t2);
890 >        assertHasWaitersUnlocked(sync, c, NO_THREADS);
891      }
892  
893      /**
894       * getWaitingThreads returns only and all waiting threads
895       */
896 <    public void testGetWaitingThreads() throws InterruptedException {
897 <        final Mutex sync = new Mutex();
898 <        final AbstractQueuedLongSynchronizer.ConditionObject c = sync.newCondition();
899 <        Thread t1 = new Thread(new Runnable() {
900 <                public void run() {
901 <                    try {
902 <                        sync.acquire(1);
903 <                        threadAssertTrue(sync.getWaitingThreads(c).isEmpty());
904 <                        c.await();
905 <                        sync.release(1);
906 <                    }
907 <                    catch (InterruptedException e) {
908 <                        threadUnexpectedException(e);
909 <                    }
910 <                }
911 <            });
912 <
913 <        Thread t2 = new Thread(new Runnable() {
914 <                public void run() {
915 <                    try {
916 <                        sync.acquire(1);
917 <                        threadAssertFalse(sync.getWaitingThreads(c).isEmpty());
918 <                        c.await();
919 <                        sync.release(1);
920 <                    }
921 <                    catch (InterruptedException e) {
922 <                        threadUnexpectedException(e);
923 <                    }
924 <                }
925 <            });
926 <
927 <            sync.acquire(1);
928 <            assertTrue(sync.getWaitingThreads(c).isEmpty());
929 <            sync.release(1);
793 <            t1.start();
794 <            Thread.sleep(SHORT_DELAY_MS);
795 <            t2.start();
796 <            Thread.sleep(SHORT_DELAY_MS);
797 <            sync.acquire(1);
798 <            assertTrue(sync.hasWaiters(c));
799 <            assertTrue(sync.getWaitingThreads(c).contains(t1));
800 <            assertTrue(sync.getWaitingThreads(c).contains(t2));
801 <            c.signalAll();
802 <            sync.release(1);
803 <            Thread.sleep(SHORT_DELAY_MS);
804 <            sync.acquire(1);
805 <            assertFalse(sync.hasWaiters(c));
806 <            assertTrue(sync.getWaitingThreads(c).isEmpty());
807 <            sync.release(1);
808 <            t1.join(SHORT_DELAY_MS);
809 <            t2.join(SHORT_DELAY_MS);
810 <            assertFalse(t1.isAlive());
811 <            assertFalse(t2.isAlive());
812 <    }
813 <
896 >    public void testGetWaitingThreads() {
897 >        final Mutex sync = new Mutex();
898 >        final ConditionObject c = sync.newCondition();
899 >        final BooleanLatch acquired1 = new BooleanLatch();
900 >        final BooleanLatch acquired2 = new BooleanLatch();
901 >        final Thread t1 = new Thread(new CheckedRunnable() {
902 >            public void realRun() throws InterruptedException {
903 >                sync.acquire();
904 >                assertHasWaitersLocked(sync, c, NO_THREADS);
905 >                assertTrue(sync.getWaitingThreads(c).isEmpty());
906 >                assertTrue(acquired1.releaseShared(0));
907 >                c.await();
908 >                sync.release();
909 >            }});
910 >
911 >        final Thread t2 = new Thread(new CheckedRunnable() {
912 >            public void realRun() throws InterruptedException {
913 >                sync.acquire();
914 >                assertHasWaitersLocked(sync, c, t1);
915 >                assertTrue(sync.getWaitingThreads(c).contains(t1));
916 >                assertFalse(sync.getWaitingThreads(c).isEmpty());
917 >                assertEquals(1, sync.getWaitingThreads(c).size());
918 >                assertTrue(acquired2.releaseShared(0));
919 >                c.await();
920 >                sync.release();
921 >            }});
922 >
923 >        sync.acquire();
924 >        assertHasWaitersLocked(sync, c, NO_THREADS);
925 >        assertFalse(sync.getWaitingThreads(c).contains(t1));
926 >        assertFalse(sync.getWaitingThreads(c).contains(t2));
927 >        assertTrue(sync.getWaitingThreads(c).isEmpty());
928 >        assertEquals(0, sync.getWaitingThreads(c).size());
929 >        sync.release();
930  
931 +        t1.start();
932 +        acquired1.acquireShared(0);
933 +        sync.acquire();
934 +        assertHasWaitersLocked(sync, c, t1);
935 +        assertTrue(sync.getWaitingThreads(c).contains(t1));
936 +        assertFalse(sync.getWaitingThreads(c).contains(t2));
937 +        assertFalse(sync.getWaitingThreads(c).isEmpty());
938 +        assertEquals(1, sync.getWaitingThreads(c).size());
939 +        sync.release();
940  
941 <    /**
942 <     * awaitUninterruptibly doesn't abort on interrupt
943 <     */
944 <    public void testAwaitUninterruptibly() throws InterruptedException {
945 <        final Mutex sync = new Mutex();
946 <        final AbstractQueuedLongSynchronizer.ConditionObject c = sync.newCondition();
947 <        Thread t = new Thread(new Runnable() {
948 <                public void run() {
949 <                    sync.acquire(1);
950 <                    c.awaitUninterruptibly();
951 <                    sync.release(1);
952 <                }
953 <            });
954 <
955 <        t.start();
956 <        Thread.sleep(SHORT_DELAY_MS);
957 <        t.interrupt();
958 <        sync.acquire(1);
959 <        c.signal();
960 <        sync.release(1);
961 <        t.join(SHORT_DELAY_MS);
837 <        assertFalse(t.isAlive());
838 <    }
839 <
840 <    /**
841 <     * await is interruptible
842 <     */
843 <    public void testAwait_Interrupt() throws InterruptedException {
844 <        final Mutex sync = new Mutex();
845 <        final AbstractQueuedLongSynchronizer.ConditionObject c = sync.newCondition();
846 <        Thread t = new Thread(new Runnable() {
847 <                public void run() {
848 <                    try {
849 <                        sync.acquire(1);
850 <                        c.await();
851 <                        sync.release(1);
852 <                        threadShouldThrow();
853 <                    }
854 <                    catch (InterruptedException success) {
855 <                    }
856 <                }
857 <            });
858 <
859 <        t.start();
860 <        Thread.sleep(SHORT_DELAY_MS);
861 <        t.interrupt();
862 <        t.join(SHORT_DELAY_MS);
863 <        assertFalse(t.isAlive());
941 >        t2.start();
942 >        acquired2.acquireShared(0);
943 >        sync.acquire();
944 >        assertHasWaitersLocked(sync, c, t1, t2);
945 >        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
946 >        assertTrue(sync.getWaitingThreads(c).contains(t1));
947 >        assertTrue(sync.getWaitingThreads(c).contains(t2));
948 >        assertFalse(sync.getWaitingThreads(c).isEmpty());
949 >        assertEquals(2, sync.getWaitingThreads(c).size());
950 >        c.signalAll();
951 >        assertHasWaitersLocked(sync, c, NO_THREADS);
952 >        assertHasExclusiveQueuedThreads(sync, t1, t2);
953 >        assertFalse(sync.getWaitingThreads(c).contains(t1));
954 >        assertFalse(sync.getWaitingThreads(c).contains(t2));
955 >        assertTrue(sync.getWaitingThreads(c).isEmpty());
956 >        assertEquals(0, sync.getWaitingThreads(c).size());
957 >        sync.release();
958 >
959 >        awaitTermination(t1);
960 >        awaitTermination(t2);
961 >        assertHasWaitersUnlocked(sync, c, NO_THREADS);
962      }
963  
964      /**
965 <     * awaitNanos is interruptible
966 <     */
967 <    public void testAwaitNanos_Interrupt() throws InterruptedException {
968 <        final Mutex sync = new Mutex();
969 <        final AbstractQueuedLongSynchronizer.ConditionObject c = sync.newCondition();
970 <        Thread t = new Thread(new Runnable() {
971 <                public void run() {
972 <                    try {
973 <                        sync.acquire(1);
974 <                        c.awaitNanos(1000 * 1000 * 1000); // 1 sec
975 <                        sync.release(1);
976 <                        threadShouldThrow();
977 <                    }
978 <                    catch (InterruptedException success) {
979 <                    }
980 <                }
981 <            });
982 <
983 <        t.start();
984 <        Thread.sleep(SHORT_DELAY_MS);
965 >     * awaitUninterruptibly is uninterruptible
966 >     */
967 >    public void testAwaitUninterruptibly() {
968 >        final Mutex sync = new Mutex();
969 >        final ConditionObject condition = sync.newCondition();
970 >        final BooleanLatch pleaseInterrupt = new BooleanLatch();
971 >        Thread t = newStartedThread(new CheckedRunnable() {
972 >            public void realRun() {
973 >                sync.acquire();
974 >                assertTrue(pleaseInterrupt.releaseShared(0));
975 >                condition.awaitUninterruptibly();
976 >                assertTrue(Thread.interrupted());
977 >                assertHasWaitersLocked(sync, condition, NO_THREADS);
978 >                sync.release();
979 >            }});
980 >
981 >        pleaseInterrupt.acquireShared(0);
982 >        sync.acquire();
983 >        assertHasWaitersLocked(sync, condition, t);
984 >        sync.release();
985          t.interrupt();
986 <        t.join(SHORT_DELAY_MS);
987 <        assertFalse(t.isAlive());
986 >        assertHasWaitersUnlocked(sync, condition, t);
987 >        assertThreadBlocks(t, Thread.State.WAITING);
988 >        sync.acquire();
989 >        assertHasWaitersLocked(sync, condition, t);
990 >        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
991 >        condition.signal();
992 >        assertHasWaitersLocked(sync, condition, NO_THREADS);
993 >        assertHasExclusiveQueuedThreads(sync, t);
994 >        sync.release();
995 >        awaitTermination(t);
996      }
997  
998      /**
999 <     * awaitUntil is interruptible
1000 <     */
1001 <    public void testAwaitUntil_Interrupt() throws InterruptedException {
1002 <        final Mutex sync = new Mutex();
1003 <        final AbstractQueuedLongSynchronizer.ConditionObject c = sync.newCondition();
1004 <        Thread t = new Thread(new Runnable() {
1005 <                public void run() {
1006 <                    try {
1007 <                        sync.acquire(1);
1008 <                        java.util.Date d = new java.util.Date();
1009 <                        c.awaitUntil(new java.util.Date(d.getTime() + 10000));
1010 <                        sync.release(1);
1011 <                        threadShouldThrow();
1012 <                    }
1013 <                    catch (InterruptedException success) {
1014 <                    }
909 <                }
910 <            });
999 >     * await/awaitNanos/awaitUntil is interruptible
1000 >     */
1001 >    public void testInterruptible_await()      { testInterruptible(AwaitMethod.await); }
1002 >    public void testInterruptible_awaitTimed() { testInterruptible(AwaitMethod.awaitTimed); }
1003 >    public void testInterruptible_awaitNanos() { testInterruptible(AwaitMethod.awaitNanos); }
1004 >    public void testInterruptible_awaitUntil() { testInterruptible(AwaitMethod.awaitUntil); }
1005 >    public void testInterruptible(final AwaitMethod awaitMethod) {
1006 >        final Mutex sync = new Mutex();
1007 >        final ConditionObject c = sync.newCondition();
1008 >        final BooleanLatch pleaseInterrupt = new BooleanLatch();
1009 >        Thread t = newStartedThread(new CheckedInterruptedRunnable() {
1010 >            public void realRun() throws InterruptedException {
1011 >                sync.acquire();
1012 >                assertTrue(pleaseInterrupt.releaseShared(0));
1013 >                await(c, awaitMethod);
1014 >            }});
1015  
1016 <        t.start();
913 <        Thread.sleep(SHORT_DELAY_MS);
1016 >        pleaseInterrupt.acquireShared(0);
1017          t.interrupt();
1018 <        t.join(SHORT_DELAY_MS);
916 <        assertFalse(t.isAlive());
1018 >        awaitTermination(t);
1019      }
1020  
1021      /**
1022       * signalAll wakes up all threads
1023       */
1024 <    public void testSignalAll() throws InterruptedException {
1025 <        final Mutex sync = new Mutex();
1026 <        final AbstractQueuedLongSynchronizer.ConditionObject c = sync.newCondition();
1027 <        Thread t1 = new Thread(new Runnable() {
1028 <                public void run() {
1029 <                    try {
1030 <                        sync.acquire(1);
1031 <                        c.await();
1032 <                        sync.release(1);
1033 <                    }
1034 <                    catch (InterruptedException e) {
1035 <                        threadUnexpectedException();
1036 <                    }
1037 <                }
1038 <            });
1039 <
1040 <        Thread t2 = new Thread(new Runnable() {
1041 <                public void run() {
1042 <                    try {
1043 <                        sync.acquire(1);
1044 <                        c.await();
1045 <                        sync.release(1);
1046 <                    }
1047 <                    catch (InterruptedException e) {
1048 <                        threadUnexpectedException();
1049 <                    }
1050 <                }
1051 <            });
1052 <
1053 <        t1.start();
952 <        t2.start();
953 <        Thread.sleep(SHORT_DELAY_MS);
954 <        sync.acquire(1);
1024 >    public void testSignalAll_await()      { testSignalAll(AwaitMethod.await); }
1025 >    public void testSignalAll_awaitTimed() { testSignalAll(AwaitMethod.awaitTimed); }
1026 >    public void testSignalAll_awaitNanos() { testSignalAll(AwaitMethod.awaitNanos); }
1027 >    public void testSignalAll_awaitUntil() { testSignalAll(AwaitMethod.awaitUntil); }
1028 >    public void testSignalAll(final AwaitMethod awaitMethod) {
1029 >        final Mutex sync = new Mutex();
1030 >        final ConditionObject c = sync.newCondition();
1031 >        final BooleanLatch acquired1 = new BooleanLatch();
1032 >        final BooleanLatch acquired2 = new BooleanLatch();
1033 >        Thread t1 = newStartedThread(new CheckedRunnable() {
1034 >            public void realRun() throws InterruptedException {
1035 >                sync.acquire();
1036 >                acquired1.releaseShared(0);
1037 >                await(c, awaitMethod);
1038 >                sync.release();
1039 >            }});
1040 >
1041 >        Thread t2 = newStartedThread(new CheckedRunnable() {
1042 >            public void realRun() throws InterruptedException {
1043 >                sync.acquire();
1044 >                acquired2.releaseShared(0);
1045 >                await(c, awaitMethod);
1046 >                sync.release();
1047 >            }});
1048 >
1049 >        acquired1.acquireShared(0);
1050 >        acquired2.acquireShared(0);
1051 >        sync.acquire();
1052 >        assertHasWaitersLocked(sync, c, t1, t2);
1053 >        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
1054          c.signalAll();
1055 <        sync.release(1);
1056 <        t1.join(SHORT_DELAY_MS);
1057 <        t2.join(SHORT_DELAY_MS);
1058 <        assertFalse(t1.isAlive());
1059 <        assertFalse(t2.isAlive());
1055 >        assertHasWaitersLocked(sync, c, NO_THREADS);
1056 >        assertHasExclusiveQueuedThreads(sync, t1, t2);
1057 >        sync.release();
1058 >        awaitTermination(t1);
1059 >        awaitTermination(t2);
1060      }
1061  
963
1062      /**
1063       * toString indicates current state
1064       */
1065      public void testToString() {
1066          Mutex sync = new Mutex();
1067 <        String us = sync.toString();
1068 <        assertTrue(us.indexOf("State = 0") >= 0);
1069 <        sync.acquire(1);
972 <        String ls = sync.toString();
973 <        assertTrue(ls.indexOf("State = " + Mutex.LOCKED) >= 0);
1067 >        assertTrue(sync.toString().contains("State = " + Mutex.UNLOCKED));
1068 >        sync.acquire();
1069 >        assertTrue(sync.toString().contains("State = " + Mutex.LOCKED));
1070      }
1071  
1072      /**
1073 <     * A serialized AQS deserializes with current state
1074 <     */
1075 <    public void testSerialization() throws Exception {
1076 <        Mutex l = new Mutex();
1077 <        l.acquire(1);
1078 <        assertTrue(l.isHeldExclusively());
1079 <
1080 <        ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
1081 <        ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
986 <        out.writeObject(l);
987 <        out.close();
988 <
989 <        ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
990 <        ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
991 <        Mutex r = (Mutex) in.readObject();
992 <        assertTrue(r.isHeldExclusively());
993 <    }
1073 >     * A serialized AQS deserializes with current state, but no queued threads
1074 >     */
1075 >    public void testSerialization() {
1076 >        Mutex sync = new Mutex();
1077 >        assertFalse(serialClone(sync).isHeldExclusively());
1078 >        sync.acquire();
1079 >        Thread t = newStartedThread(new InterruptedSyncRunnable(sync));
1080 >        waitForQueuedThread(sync, t);
1081 >        assertTrue(sync.isHeldExclusively());
1082  
1083 +        Mutex clone = serialClone(sync);
1084 +        assertTrue(clone.isHeldExclusively());
1085 +        assertHasExclusiveQueuedThreads(sync, t);
1086 +        assertHasExclusiveQueuedThreads(clone, NO_THREADS);
1087 +        t.interrupt();
1088 +        awaitTermination(t);
1089 +        sync.release();
1090 +        assertFalse(sync.isHeldExclusively());
1091 +        assertTrue(clone.isHeldExclusively());
1092 +        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
1093 +        assertHasExclusiveQueuedThreads(clone, NO_THREADS);
1094 +    }
1095  
1096      /**
1097       * tryReleaseShared setting state changes getState
1098       */
1099      public void testGetStateWithReleaseShared() {
1100 <        final BooleanLatch l = new BooleanLatch();
1101 <        assertFalse(l.isSignalled());
1102 <        l.releaseShared(0);
1103 <        assertTrue(l.isSignalled());
1100 >        final BooleanLatch l = new BooleanLatch();
1101 >        assertFalse(l.isSignalled());
1102 >        assertTrue(l.releaseShared(0));
1103 >        assertTrue(l.isSignalled());
1104      }
1105  
1106      /**
1107       * releaseShared has no effect when already signalled
1108       */
1109      public void testReleaseShared() {
1110 <        final BooleanLatch l = new BooleanLatch();
1111 <        assertFalse(l.isSignalled());
1112 <        l.releaseShared(0);
1113 <        assertTrue(l.isSignalled());
1114 <        l.releaseShared(0);
1115 <        assertTrue(l.isSignalled());
1110 >        final BooleanLatch l = new BooleanLatch();
1111 >        assertFalse(l.isSignalled());
1112 >        assertTrue(l.releaseShared(0));
1113 >        assertTrue(l.isSignalled());
1114 >        assertTrue(l.releaseShared(0));
1115 >        assertTrue(l.isSignalled());
1116      }
1117  
1118      /**
1119       * acquireSharedInterruptibly returns after release, but not before
1120       */
1121 <    public void testAcquireSharedInterruptibly() throws InterruptedException {
1122 <        final BooleanLatch l = new BooleanLatch();
1121 >    public void testAcquireSharedInterruptibly() {
1122 >        final BooleanLatch l = new BooleanLatch();
1123  
1124 <        Thread t = new Thread(new Runnable() {
1125 <                public void run() {
1126 <                    try {
1127 <                        threadAssertFalse(l.isSignalled());
1128 <                        l.acquireSharedInterruptibly(0);
1129 <                        threadAssertTrue(l.isSignalled());
1130 <                    } catch (InterruptedException e) {
1131 <                        threadUnexpectedException();
1032 <                    }
1033 <                }
1034 <            });
1124 >        Thread t = newStartedThread(new CheckedRunnable() {
1125 >            public void realRun() throws InterruptedException {
1126 >                assertFalse(l.isSignalled());
1127 >                l.acquireSharedInterruptibly(0);
1128 >                assertTrue(l.isSignalled());
1129 >                l.acquireSharedInterruptibly(0);
1130 >                assertTrue(l.isSignalled());
1131 >            }});
1132  
1133 <        t.start();
1133 >        waitForQueuedThread(l, t);
1134          assertFalse(l.isSignalled());
1135 <        Thread.sleep(SHORT_DELAY_MS);
1136 <        l.releaseShared(0);
1135 >        assertThreadBlocks(t, Thread.State.WAITING);
1136 >        assertHasSharedQueuedThreads(l, t);
1137 >        assertTrue(l.releaseShared(0));
1138          assertTrue(l.isSignalled());
1139 <        t.join();
1139 >        awaitTermination(t);
1140      }
1141  
1044
1142      /**
1143 <     * acquireSharedTimed returns after release
1143 >     * tryAcquireSharedNanos returns after release, but not before
1144       */
1145 <    public void testAsquireSharedTimed() throws InterruptedException {
1146 <        final BooleanLatch l = new BooleanLatch();
1050 <
1051 <        Thread t = new Thread(new Runnable() {
1052 <                public void run() {
1053 <                    try {
1054 <                        threadAssertFalse(l.isSignalled());
1055 <                        threadAssertTrue(l.tryAcquireSharedNanos(0, MEDIUM_DELAY_MS* 1000 * 1000));
1056 <                        threadAssertTrue(l.isSignalled());
1145 >    public void testTryAcquireSharedNanos() {
1146 >        final BooleanLatch l = new BooleanLatch();
1147  
1148 <                    } catch (InterruptedException e) {
1149 <                        threadUnexpectedException();
1150 <                    }
1151 <                }
1152 <            });
1148 >        Thread t = newStartedThread(new CheckedRunnable() {
1149 >            public void realRun() throws InterruptedException {
1150 >                assertFalse(l.isSignalled());
1151 >                long nanos = MILLISECONDS.toNanos(2 * LONG_DELAY_MS);
1152 >                assertTrue(l.tryAcquireSharedNanos(0, nanos));
1153 >                assertTrue(l.isSignalled());
1154 >                assertTrue(l.tryAcquireSharedNanos(0, nanos));
1155 >                assertTrue(l.isSignalled());
1156 >            }});
1157  
1158 <        t.start();
1158 >        waitForQueuedThread(l, t);
1159          assertFalse(l.isSignalled());
1160 <        Thread.sleep(SHORT_DELAY_MS);
1161 <        l.releaseShared(0);
1160 >        assertThreadBlocks(t, Thread.State.TIMED_WAITING);
1161 >        assertTrue(l.releaseShared(0));
1162          assertTrue(l.isSignalled());
1163 <        t.join();
1163 >        awaitTermination(t);
1164      }
1165  
1166      /**
1167 <     * acquireSharedInterruptibly throws IE if interrupted before released
1167 >     * acquireSharedInterruptibly is interruptible
1168       */
1169 <    public void testAcquireSharedInterruptibly_InterruptedException() throws InterruptedException {
1169 >    public void testAcquireSharedInterruptibly_Interruptible() {
1170          final BooleanLatch l = new BooleanLatch();
1171 <        Thread t = new Thread(new Runnable() {
1172 <                public void run() {
1173 <                    try {
1174 <                        threadAssertFalse(l.isSignalled());
1175 <                        l.acquireSharedInterruptibly(0);
1082 <                        threadShouldThrow();
1083 <                    } catch (InterruptedException success) {}
1084 <                }
1085 <            });
1171 >        Thread t = newStartedThread(new CheckedInterruptedRunnable() {
1172 >            public void realRun() throws InterruptedException {
1173 >                assertFalse(l.isSignalled());
1174 >                l.acquireSharedInterruptibly(0);
1175 >            }});
1176  
1177 <        t.start();
1177 >        waitForQueuedThread(l, t);
1178          assertFalse(l.isSignalled());
1179          t.interrupt();
1180 <        t.join();
1180 >        awaitTermination(t);
1181 >        assertFalse(l.isSignalled());
1182      }
1183  
1184      /**
1185 <     * acquireSharedTimed throws IE if interrupted before released
1185 >     * tryAcquireSharedNanos is interruptible
1186       */
1187 <    public void testAcquireSharedNanos_InterruptedException() throws InterruptedException {
1187 >    public void testTryAcquireSharedNanos_Interruptible() {
1188          final BooleanLatch l = new BooleanLatch();
1189 <        Thread t = new Thread(new Runnable() {
1190 <                public void run() {
1191 <                    try {
1192 <                        threadAssertFalse(l.isSignalled());
1193 <                        l.tryAcquireSharedNanos(0, SMALL_DELAY_MS* 1000 * 1000);
1194 <                        threadShouldThrow();
1104 <                    } catch (InterruptedException success) {}
1105 <                }
1106 <            });
1189 >        Thread t = newStartedThread(new CheckedInterruptedRunnable() {
1190 >            public void realRun() throws InterruptedException {
1191 >                assertFalse(l.isSignalled());
1192 >                long nanos = MILLISECONDS.toNanos(2 * LONG_DELAY_MS);
1193 >                l.tryAcquireSharedNanos(0, nanos);
1194 >            }});
1195  
1196 <        t.start();
1109 <        Thread.sleep(SHORT_DELAY_MS);
1196 >        waitForQueuedThread(l, t);
1197          assertFalse(l.isSignalled());
1198          t.interrupt();
1199 <        t.join();
1199 >        awaitTermination(t);
1200 >        assertFalse(l.isSignalled());
1201      }
1202  
1203      /**
1204 <     * acquireSharedTimed times out if not released before timeout
1204 >     * tryAcquireSharedNanos times out if not released before timeout
1205       */
1206 <    public void testAcquireSharedNanos_Timeout() throws InterruptedException {
1206 >    public void testTryAcquireSharedNanos_Timeout() {
1207          final BooleanLatch l = new BooleanLatch();
1208 <        Thread t = new Thread(new Runnable() {
1209 <                public void run() {
1210 <                    try {
1211 <                        threadAssertFalse(l.isSignalled());
1212 <                        threadAssertFalse(l.tryAcquireSharedNanos(0, SMALL_DELAY_MS* 1000 * 1000));
1213 <                    } catch (InterruptedException ie) {
1214 <                        threadUnexpectedException();
1215 <                    }
1208 >        final BooleanLatch observedQueued = new BooleanLatch();
1209 >        Thread t = newStartedThread(new CheckedRunnable() {
1210 >            public void realRun() throws InterruptedException {
1211 >                assertFalse(l.isSignalled());
1212 >                for (long millis = timeoutMillis();
1213 >                     !observedQueued.isSignalled();
1214 >                     millis *= 2) {
1215 >                    long nanos = MILLISECONDS.toNanos(millis);
1216 >                    long startTime = System.nanoTime();
1217 >                    assertFalse(l.tryAcquireSharedNanos(0, nanos));
1218 >                    assertTrue(millisElapsedSince(startTime) >= millis);
1219                  }
1220 <            });
1220 >                assertFalse(l.isSignalled());
1221 >            }});
1222  
1223 <        t.start();
1224 <        Thread.sleep(SHORT_DELAY_MS);
1223 >        waitForQueuedThread(l, t);
1224 >        observedQueued.releaseShared(0);
1225 >        assertFalse(l.isSignalled());
1226 >        awaitTermination(t);
1227          assertFalse(l.isSignalled());
1134        t.join();
1228      }
1229  
1230 +    /**
1231 +     * awaitNanos/timed await with 0 wait times out immediately
1232 +     */
1233 +    public void testAwait_Zero() throws InterruptedException {
1234 +        final Mutex sync = new Mutex();
1235 +        final ConditionObject c = sync.newCondition();
1236 +        sync.acquire();
1237 +        assertTrue(c.awaitNanos(0L) <= 0);
1238 +        assertFalse(c.await(0L, NANOSECONDS));
1239 +        sync.release();
1240 +    }
1241 +
1242 +    /**
1243 +     * awaitNanos/timed await with maximum negative wait times does not underflow
1244 +     */
1245 +    public void testAwait_NegativeInfinity() throws InterruptedException {
1246 +        final Mutex sync = new Mutex();
1247 +        final ConditionObject c = sync.newCondition();
1248 +        sync.acquire();
1249 +        assertTrue(c.awaitNanos(Long.MIN_VALUE) <= 0);
1250 +        assertFalse(c.await(Long.MIN_VALUE, NANOSECONDS));
1251 +        sync.release();
1252 +    }
1253  
1254   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines