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