ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/AbstractQueuedLongSynchronizerTest.java
Revision: 1.43
Committed: Mon Nov 27 23:06:53 2017 UTC (6 years, 5 months ago) by jsr166
Branch: MAIN
Changes since 1.42: +54 -0 lines
Log Message:
JDK-8191937: Lost interrupt in AbstractQueuedSynchronizer when tryAcquire methods throw

File Contents

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