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.2 by dl, Tue May 3 16:02:00 2005 UTC vs.
Revision 1.50 by jsr166, Thu Aug 15 14:56:32 2019 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines