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.4 by dl, Thu May 18 10:29:23 2006 UTC vs.
Revision 1.43 by jsr166, Mon Nov 27 23:06:53 2017 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines