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

Comparing jsr166/src/test/tck/AbstractQueuedLongSynchronizerTest.java (file contents):
Revision 1.3 by dl, Wed Apr 5 11:24:55 2006 UTC vs.
Revision 1.46 by jsr166, Tue Aug 13 00:54:51 2019 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines