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.5 by jsr166, Mon Nov 2 20:28:31 2009 UTC vs.
Revision 1.45 by jsr166, Wed Jun 13 18:36:31 2018 UTC

# Line 1 | Line 1
1   /*
2   * Written by Doug Lea with assistance from members of JCP JSR-166
3   * Expert Group and released to the public domain, as explained at
4 < * http://creativecommons.org/licenses/publicdomain
4 > * http://creativecommons.org/publicdomain/zero/1.0/
5   * Other contributors include Andrew Wright, Jeffrey Hayes,
6   * Pat Fisher, Mike Judd.
7   */
8  
9 + import static java.util.concurrent.TimeUnit.MILLISECONDS;
10 + import static java.util.concurrent.TimeUnit.NANOSECONDS;
11  
12 < import junit.framework.*;
13 < import java.util.*;
14 < import java.util.concurrent.*;
15 < import java.util.concurrent.locks.*;
16 < import java.io.*;
12 > import java.util.Arrays;
13 > import java.util.Collection;
14 > import java.util.HashSet;
15 > import java.util.concurrent.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);
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);
56 >        @Override protected boolean tryRelease(long releases) {
57 >            if (getState() != LOCKED) throw new IllegalMonitorStateException();
58 >            setState(UNLOCKED);
59              return true;
60          }
61  
62 <        public AbstractQueuedLongSynchronizer.ConditionObject newCondition() { return new AbstractQueuedLongSynchronizer.ConditionObject(); }
62 >        public boolean tryAcquireNanos(long nanos) throws InterruptedException {
63 >            return tryAcquireNanos(LOCKED, nanos);
64 >        }
65  
66 <    }
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  
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 {
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  
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());
278 >        Mutex sync = new Mutex();
279 >        assertFalse(sync.isHeldExclusively());
280      }
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());
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
294 >     * tryAcquire on a 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);
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());
147 <            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 <        }
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();
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();
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);
195 <            assertFalse(sync.isQueued(t2));
196 <            t1.join();
197 <            t2.join();
198 <        } catch(Exception e){
199 <            unexpectedException();
200 <        }
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);
222 <            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 <        }
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  
233
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);
254 <            Thread.sleep(SHORT_DELAY_MS);
255 <            assertTrue(sync.hasContended());
256 <            t1.join();
257 <            t2.join();
258 <        } catch(Exception e){
259 <            unexpectedException();
260 <        }
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();
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();
289 <            t2.join();
290 <        } catch(Exception e){
291 <            unexpectedException();
292 <        }
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();
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();
321 <            t2.join();
322 <        } catch(Exception e){
323 <            unexpectedException();
324 <        }
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());
347 <            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 <        }
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
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();
393 <            t.join();
394 <            sync.release(1);
395 <        } catch(Exception e){
396 <            unexpectedException();
397 <        }
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 <                    }
413 <                }
414 <            });
415 <        try {
416 <            t.start();
417 <            t.join();
418 <            sync.release(1);
419 <        } catch(Exception e){
420 <            unexpectedException();
421 <        }
422 <    }
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 <        }
455 <    }
456 <
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 <            Thread.sleep(SHORT_DELAY_MS);
470 <            sync.release(1);
471 <            t.join();
472 <        } catch(Exception e){
473 <            unexpectedException();
474 <        }
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  
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();
495 <        }
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 509 | 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) {
537 <        }
538 <        catch (Exception ex) {
539 <            unexpectedException();
540 <        }
644 >        } catch (IllegalMonitorStateException success) {}
645 >        assertHasWaitersUnlocked(sync, c, NO_THREADS);
646      }
647  
648      /**
649 <     * awaitNanos without a signal times out
649 >     * Calling signalAll without holding sync throws IllegalMonitorStateException
650       */
651 <    public void testAwaitNanos_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 <            long t = c.awaitNanos(100);
657 <            assertTrue(t <= 0);
553 <            sync.release(1);
554 <        }
555 <        catch (Exception ex) {
556 <            unexpectedException();
557 <        }
655 >            c.signalAll();
656 >            shouldThrow();
657 >        } catch (IllegalMonitorStateException success) {}
658      }
659  
660      /**
661 <     *  Timed await without a signal times out
661 >     * await/awaitNanos/awaitUntil without a signal times out
662       */
663 <    public void testAwait_Timeout() {
664 <        final Mutex sync = new Mutex();
665 <        final AbstractQueuedLongSynchronizer.ConditionObject c = sync.newCondition();
666 <        try {
667 <            sync.acquire(1);
668 <            assertFalse(c.await(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
669 <            sync.release(1);
670 <        }
671 <        catch (Exception ex) {
572 <            unexpectedException();
573 <        }
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 <     * awaitUntil without a signal times out
676 <     */
677 <    public void testAwaitUntil_Timeout() {
678 <        final Mutex sync = new Mutex();
679 <        final AbstractQueuedLongSynchronizer.ConditionObject c = sync.newCondition();
680 <        try {
681 <            sync.acquire(1);
682 <            java.util.Date d = new java.util.Date();
683 <            assertFalse(c.awaitUntil(new java.util.Date(d.getTime() + 10)));
684 <            sync.release(1);
685 <        }
686 <        catch (Exception ex) {
687 <            unexpectedException();
688 <        }
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  
704      /**
705 <     * await returns when signalled
595 <     */
596 <    public void testAwait() {
597 <        final Mutex sync = new Mutex();
598 <        final AbstractQueuedLongSynchronizer.ConditionObject c = sync.newCondition();
599 <        Thread t = new Thread(new Runnable() {
600 <                public void run() {
601 <                    try {
602 <                        sync.acquire(1);
603 <                        c.await();
604 <                        sync.release(1);
605 <                    }
606 <                    catch(InterruptedException e) {
607 <                        threadUnexpectedException();
608 <                    }
609 <                }
610 <            });
611 <
612 <        try {
613 <            t.start();
614 <            Thread.sleep(SHORT_DELAY_MS);
615 <            sync.acquire(1);
616 <            c.signal();
617 <            sync.release(1);
618 <            t.join(SHORT_DELAY_MS);
619 <            assertFalse(t.isAlive());
620 <        }
621 <        catch (Exception ex) {
622 <            unexpectedException();
623 <        }
624 <    }
625 <
626 <
627 <
628 <    /**
629 <     * 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) {
637 <        } catch (Exception ex) {
638 <            unexpectedException();
639 <        }
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) {
651 <        } catch (Exception ex) {
652 <            unexpectedException();
653 <        }
723 >        } catch (NullPointerException success) {}
724      }
725  
656
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) {
666 <        } catch (Exception ex) {
667 <            unexpectedException();
668 <        }
734 >        } catch (NullPointerException success) {}
735      }
736  
671
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) {
684 <            unexpectedException();
685 <        }
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) {
699 <            unexpectedException();
700 <        }
760 >        } catch (IllegalMonitorStateException success) {}
761 >        assertHasWaitersUnlocked(sync, c, NO_THREADS);
762      }
763  
703
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) {
716 <            unexpectedException();
717 <        }
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) {
731 <            unexpectedException();
732 <        }
787 >        } catch (IllegalMonitorStateException success) {}
788 >        assertHasWaitersUnlocked(sync, c, NO_THREADS);
789      }
790  
735
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) {
748 <            unexpectedException();
749 <        }
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) {
763 <            unexpectedException();
764 <        }
814 >        } catch (IllegalMonitorStateException success) {}
815 >        assertHasWaitersUnlocked(sync, c, NO_THREADS);
816      }
817  
767
768
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();
792 <            Thread.sleep(SHORT_DELAY_MS);
793 <            sync.acquire(1);
794 <            assertTrue(sync.hasWaiters(c));
795 <            assertEquals(1, sync.getWaitQueueLength(c));
796 <            c.signal();
797 <            sync.release(1);
798 <            Thread.sleep(SHORT_DELAY_MS);
799 <            sync.acquire(1);
800 <            assertFalse(sync.hasWaiters(c));
801 <            assertEquals(0, sync.getWaitQueueLength(c));
802 <            sync.release(1);
803 <            t.join(SHORT_DELAY_MS);
804 <            assertFalse(t.isAlive());
805 <        }
806 <        catch (Exception ex) {
807 <            unexpectedException();
808 <        }
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);
857 <            Thread.sleep(SHORT_DELAY_MS);
858 <            sync.acquire(1);
859 <            assertFalse(sync.hasWaiters(c));
860 <            assertEquals(0, sync.getWaitQueueLength(c));
861 <            sync.release(1);
862 <            t1.join(SHORT_DELAY_MS);
863 <            t2.join(SHORT_DELAY_MS);
864 <            assertFalse(t1.isAlive());
865 <            assertFalse(t2.isAlive());
866 <        }
867 <        catch (Exception ex) {
868 <            unexpectedException();
869 <        }
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  
935
936
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 <     */
969 <    public void testAwait_Interrupt() {
970 <        final Mutex sync = new Mutex();
971 <        final AbstractQueuedLongSynchronizer.ConditionObject c = sync.newCondition();
972 <        Thread t = new Thread(new Runnable() {
973 <                public void run() {
974 <                    try {
975 <                        sync.acquire(1);
976 <                        c.await();
977 <                        sync.release(1);
978 <                        threadShouldThrow();
979 <                    }
980 <                    catch(InterruptedException success) {
981 <                    }
982 <                }
983 <            });
984 <
985 <        try {
986 <            t.start();
987 <            Thread.sleep(SHORT_DELAY_MS);
988 <            t.interrupt();
989 <            t.join(SHORT_DELAY_MS);
990 <            assertFalse(t.isAlive());
991 <        }
992 <        catch (Exception ex) {
993 <            unexpectedException();
994 <        }
995 <    }
996 <
997 <    /**
998 <     * awaitNanos is interruptible
999 <     */
1000 <    public void testAwaitNanos_Interrupt() {
1001 <        final Mutex sync = new Mutex();
1002 <        final AbstractQueuedLongSynchronizer.ConditionObject c = sync.newCondition();
1003 <        Thread t = new Thread(new Runnable() {
1004 <                public void run() {
1005 <                    try {
1006 <                        sync.acquire(1);
1007 <                        c.awaitNanos(1000 * 1000 * 1000); // 1 sec
1008 <                        sync.release(1);
1009 <                        threadShouldThrow();
1010 <                    }
1011 <                    catch(InterruptedException success) {
1012 <                    }
1013 <                }
1014 <            });
1015 <
1016 <        try {
1017 <            t.start();
1018 <            Thread.sleep(SHORT_DELAY_MS);
1019 <            t.interrupt();
1020 <            t.join(SHORT_DELAY_MS);
1021 <            assertFalse(t.isAlive());
1022 <        }
1023 <        catch (Exception ex) {
1024 <            unexpectedException();
1025 <        }
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 <     * awaitUntil is interruptible
1005 <     */
1006 <    public void testAwaitUntil_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 <                        java.util.Date d = new java.util.Date();
1014 <                        c.awaitUntil(new java.util.Date(d.getTime() + 10000));
1015 <                        sync.release(1);
1016 <                        threadShouldThrow();
1017 <                    }
1018 <                    catch(InterruptedException success) {
1019 <                    }
1020 <                }
1021 <            });
1022 <
1023 <        try {
1049 <            t.start();
1050 <            Thread.sleep(SHORT_DELAY_MS);
1051 <            t.interrupt();
1052 <            t.join(SHORT_DELAY_MS);
1053 <            assertFalse(t.isAlive());
1054 <        }
1055 <        catch (Exception ex) {
1056 <            unexpectedException();
1057 <        }
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);
1099 <            t1.join(SHORT_DELAY_MS);
1100 <            t2.join(SHORT_DELAY_MS);
1101 <            assertFalse(t1.isAlive());
1102 <            assertFalse(t2.isAlive());
1103 <        }
1104 <        catch (Exception ex) {
1105 <            unexpectedException();
1106 <        }
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  
1109
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);
1118 <        String ls = sync.toString();
1119 <        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  
1146
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);
1191 <            assertTrue(l.isSignalled());
1192 <            t.join();
1193 <        } catch (InterruptedException e){
1194 <            unexpectedException();
1195 <        }
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      }
1146  
1198
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);
1221 <            l.releaseShared(0);
1222 <            assertTrue(l.isSignalled());
1223 <            t.join();
1224 <        } catch (InterruptedException e){
1225 <            unexpectedException();
1226 <        }
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  
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 {
1245 <            assertFalse(l.isSignalled());
1246 <            t.interrupt();
1247 <            t.join();
1248 <        } catch (InterruptedException e){
1249 <            unexpectedException();
1250 <        }
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);
1270 <            assertFalse(l.isSignalled());
1271 <            t.interrupt();
1272 <            t.join();
1273 <        } catch (InterruptedException e){
1274 <            unexpectedException();
1275 <        }
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();
1294 <        try {
1295 <            Thread.sleep(SHORT_DELAY_MS);
1296 <            assertFalse(l.isSignalled());
1297 <            t.join();
1298 <        } catch (InterruptedException e){
1299 <            unexpectedException();
1300 <        }
1301 <    }
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 (ThreadLocalRandom.current().nextBoolean())
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  
1312   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines