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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines