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

Comparing jsr166/src/test/tck/PhaserTest.java (file contents):
Revision 1.1 by dl, Fri Jul 31 23:02:50 2009 UTC vs.
Revision 1.35 by dl, Wed Sep 21 12:33:56 2011 UTC

# Line 1 | Line 1
1   /*
2   * Written by Doug Lea with assistance from members of JCP JSR-166
3   * Expert Group and released to the public domain, as explained at
4 < * http://creativecommons.org/licenses/publicdomain
4 > * http://creativecommons.org/publicdomain/zero/1.0/
5   * Other contributors include John Vint
6   */
7  
8 + import junit.framework.*;
9   import java.util.ArrayList;
10   import java.util.List;
11 + import java.util.concurrent.Phaser;
12 + import java.util.concurrent.CountDownLatch;
13 + import java.util.concurrent.TimeoutException;
14 + import static java.util.concurrent.TimeUnit.MILLISECONDS;
15 + import static java.util.concurrent.TimeUnit.NANOSECONDS;
16 + import java.util.concurrent.atomic.AtomicBoolean;
17   import java.util.concurrent.atomic.AtomicInteger;
11 import java.util.concurrent.*;
12 import junit.framework.Test;
13 import junit.framework.TestSuite;
18  
19   public class PhaserTest extends JSR166TestCase {
20  
# Line 22 | Line 26 | public class PhaserTest extends JSR166Te
26          return new TestSuite(PhaserTest.class);
27      }
28  
29 +    private static final int maxParties = 65535;
30 +
31 +    /** Checks state of unterminated phaser. */
32 +    protected void assertState(Phaser phaser,
33 +                               int phase, int parties, int unarrived) {
34 +        assertEquals(phase, phaser.getPhase());
35 +        assertEquals(parties, phaser.getRegisteredParties());
36 +        assertEquals(unarrived, phaser.getUnarrivedParties());
37 +        assertEquals(parties - unarrived, phaser.getArrivedParties());
38 +        assertFalse(phaser.isTerminated());
39 +    }
40 +
41 +    /** Checks state of terminated phaser. */
42 +    protected void assertTerminated(Phaser phaser, int maxPhase, int parties) {
43 +        assertTrue(phaser.isTerminated());
44 +        int expectedPhase = maxPhase + Integer.MIN_VALUE;
45 +        assertEquals(expectedPhase, phaser.getPhase());
46 +        assertEquals(parties, phaser.getRegisteredParties());
47 +        assertEquals(expectedPhase, phaser.register());
48 +        assertEquals(expectedPhase, phaser.arrive());
49 +        assertEquals(expectedPhase, phaser.arriveAndDeregister());
50 +    }
51 +
52 +    protected void assertTerminated(Phaser phaser, int maxPhase) {
53 +        assertTerminated(phaser, maxPhase, 0);
54 +    }
55 +
56      /**
57       * Empty constructor builds a new Phaser with no parent, no registered
58       * parties and initial phase number of 0
59       */
60 <    public void testConstructor1() {
60 >    public void testConstructorDefaultValues() {
61          Phaser phaser = new Phaser();
62          assertNull(phaser.getParent());
63 +        assertEquals(0, phaser.getRegisteredParties());
64          assertEquals(0, phaser.getArrivedParties());
65 +        assertEquals(0, phaser.getUnarrivedParties());
66          assertEquals(0, phaser.getPhase());
67      }
68  
69      /**
70 <     * A negative party number for the constructor throws illegal argument
71 <     * exception
70 >     * Constructing with a negative number of parties throws
71 >     * IllegalArgumentException
72       */
73 <    public void testConstructor2() {
73 >    public void testConstructorNegativeParties() {
74          try {
75              new Phaser(-1);
76 <            this.shouldThrow();
77 <        } catch (IllegalArgumentException success) {
45 <        }
76 >            shouldThrow();
77 >        } catch (IllegalArgumentException success) {}
78      }
79  
80      /**
81 <     * The parent being input into the constructor should equal the original
82 <     * parent when being returned
81 >     * Constructing with a negative number of parties throws
82 >     * IllegalArgumentException
83       */
84 <    public void testConstructor3() {
85 <        Phaser parent = new Phaser();
86 <        assertEquals(parent, new Phaser(parent).getParent());
84 >    public void testConstructorNegativeParties2() {
85 >        try {
86 >            new Phaser(new Phaser(), -1);
87 >            shouldThrow();
88 >        } catch (IllegalArgumentException success) {}
89      }
90  
91      /**
92 <     * A negative party number for the constructor throws illegal argument
93 <     * exception
92 >     * Constructing with a number of parties > 65535 throws
93 >     * IllegalArgumentException
94       */
95 <    public void testConstructor4() {
95 >    public void testConstructorPartiesExceedsLimit() {
96 >        new Phaser(maxParties);
97          try {
98 <            new Phaser(new Phaser(), -1);
98 >            new Phaser(maxParties + 1);
99              shouldThrow();
100 <        } catch (IllegalArgumentException success) {
101 <        }
100 >        } catch (IllegalArgumentException success) {}
101 >
102 >        new Phaser(new Phaser(), maxParties);
103 >        try {
104 >            new Phaser(new Phaser(), maxParties + 1);
105 >            shouldThrow();
106 >        } catch (IllegalArgumentException success) {}
107 >    }
108 >
109 >    /**
110 >     * The parent provided to the constructor should be returned from
111 >     * a later call to getParent
112 >     */
113 >    public void testConstructor3() {
114 >        Phaser parent = new Phaser();
115 >        assertSame(parent, new Phaser(parent).getParent());
116 >        assertNull(new Phaser(null).getParent());
117      }
118  
119      /**
# Line 72 | Line 122 | public class PhaserTest extends JSR166Te
122       */
123      public void testConstructor5() {
124          Phaser parent = new Phaser();
125 <        assertEquals(parent, new Phaser(parent, 0).getParent());
125 >        assertSame(parent, new Phaser(parent, 0).getParent());
126 >        assertNull(new Phaser(null, 0).getParent());
127      }
128  
129      /**
130 <     * register() will increment the number of unarrived parties by one and not
131 <     * affect its arrived parties
130 >     * register() will increment the number of unarrived parties by
131 >     * one and not affect its arrived parties
132       */
133      public void testRegister1() {
134          Phaser phaser = new Phaser();
135 <        assertEquals(0, phaser.getUnarrivedParties());
136 <        phaser.register();
137 <        assertEquals(1, phaser.getUnarrivedParties());
87 <        assertEquals(0, phaser.getArrivedParties());
135 >        assertState(phaser, 0, 0, 0);
136 >        assertEquals(0, phaser.register());
137 >        assertState(phaser, 0, 1, 1);
138      }
139  
140      /**
141 <     * Registering any more then 65536 parties causes IllegalStateExceptiom
141 >     * Registering more than 65536 parties causes IllegalStateException
142       */
143      public void testRegister2() {
144          Phaser phaser = new Phaser(0);
145 <        int expectedUnnarivedParties = (1 << 16) - 1;
146 <        for (int i = 0; i < expectedUnnarivedParties; i++) {
147 <            phaser.register();
148 <            assertEquals(i + 1, phaser.getUnarrivedParties());
145 >        assertState(phaser, 0, 0, 0);
146 >        assertEquals(0, phaser.bulkRegister(maxParties - 10));
147 >        assertState(phaser, 0, maxParties - 10, maxParties - 10);
148 >        for (int i = 0; i < 10; i++) {
149 >            assertState(phaser, 0, maxParties - 10 + i, maxParties - 10 + i);
150 >            assertEquals(0, phaser.register());
151          }
152 +        assertState(phaser, 0, maxParties, maxParties);
153          try {
154              phaser.register();
155              shouldThrow();
156 <        } catch (IllegalStateException success) {
157 <        } catch (Exception ex) {
158 <            threadUnexpectedException(ex);
159 <        }
156 >        } catch (IllegalStateException success) {}
157 >
158 >        try {
159 >            phaser.bulkRegister(Integer.MAX_VALUE);
160 >            shouldThrow();
161 >        } catch (IllegalStateException success) {}
162 >
163 >        assertEquals(0, phaser.bulkRegister(0));
164 >        assertState(phaser, 0, maxParties, maxParties);
165      }
166  
167      /**
168 <     * register() correctly returns the current barrier phase number when
169 <     * invoked
168 >     * register() correctly returns the current barrier phase number
169 >     * when invoked
170       */
171      public void testRegister3() {
172          Phaser phaser = new Phaser();
173          assertEquals(0, phaser.register());
174 <        phaser.arrive();
174 >        assertEquals(0, phaser.arrive());
175          assertEquals(1, phaser.register());
176 +        assertState(phaser, 1, 2, 2);
177      }
178  
179      /**
180 <     * register causes the next arrive to not increment the phase rather retain
181 <     * the phase number
180 >     * register causes the next arrive to not increment the phase
181 >     * rather retain the phase number
182       */
183      public void testRegister4() {
184          Phaser phaser = new Phaser(1);
185 <        phaser.arrive();
186 <        int expectedPhase = phaser.register();
187 <        phaser.arrive();
188 <        assertEquals(expectedPhase, phaser.getPhase());
185 >        assertEquals(0, phaser.arrive());
186 >        assertEquals(1, phaser.register());
187 >        assertEquals(1, phaser.arrive());
188 >        assertState(phaser, 1, 2, 1);
189      }
190  
191 <    public void testRegister5() {
192 <        Phaser phaser = new Phaser();
193 <        phaser.register();
194 <        assertEquals(1, phaser.getUnarrivedParties());
191 >    /**
192 >     * register on a subphaser that is currently empty succeeds, even
193 >     * in the presence of another non-empty subphaser
194 >     */
195 >    public void testRegisterEmptySubPhaser() {
196 >        Phaser root = new Phaser();
197 >        Phaser child1 = new Phaser(root, 1);
198 >        Phaser child2 = new Phaser(root, 0);
199 >        assertEquals(0, child2.register());
200 >        assertEquals(0, child2.arriveAndDeregister());
201 >        assertEquals(0, child2.register());
202 >        assertEquals(0, child2.arriveAndDeregister());
203 >        assertState(child2, 0, 0, 0);
204      }
205  
206      /**
207       * Invoking bulkRegister with a negative parameter throws an
208 <     * IllegalArgumentExceptiom
208 >     * IllegalArgumentException
209       */
210      public void testBulkRegister1() {
211          try {
212              new Phaser().bulkRegister(-1);
213              shouldThrow();
214 <        } catch (IllegalArgumentException success) {
147 <        }
214 >        } catch (IllegalArgumentException success) {}
215      }
216  
217      /**
218 <     * bulkRegister should correctly record the number of unarrived parties with
219 <     * the number of parties being registered
218 >     * bulkRegister should correctly record the number of unarrived
219 >     * parties with the number of parties being registered
220       */
221      public void testBulkRegister2() {
222          Phaser phaser = new Phaser();
223 <        phaser.bulkRegister(20);
224 <        assertEquals(20, phaser.getUnarrivedParties());
223 >        assertEquals(0, phaser.bulkRegister(0));
224 >        assertState(phaser, 0, 0, 0);
225 >        assertEquals(0, phaser.bulkRegister(20));
226 >        assertState(phaser, 0, 20, 20);
227      }
228  
229      /**
230 <     * Registering with a number of parties greater then or equal to 1<<16
231 <     * throws IllegalStateExceptiom.
230 >     * Registering with a number of parties greater than or equal to 1<<16
231 >     * throws IllegalStateException.
232       */
233      public void testBulkRegister3() {
234 +        assertEquals(0, new Phaser().bulkRegister((1 << 16) - 1));
235 +
236          try {
237              new Phaser().bulkRegister(1 << 16);
238              shouldThrow();
239 <        } catch (IllegalStateException success) {
240 <        }
239 >        } catch (IllegalStateException success) {}
240 >
241 >        try {
242 >            new Phaser(2).bulkRegister((1 << 16) - 2);
243 >            shouldThrow();
244 >        } catch (IllegalStateException success) {}
245      }
246  
247      /**
# Line 183 | Line 258 | public class PhaserTest extends JSR166Te
258      }
259  
260      /**
261 <     *  Arrive() on a registered phaser increments phase.
261 >     * arrive() on a registered phaser increments phase.
262       */
263      public void testArrive1() {
264          Phaser phaser = new Phaser(1);
265 <        phaser.arrive();
266 <        assertEquals(1, phaser.getPhase());
265 >        assertState(phaser, 0, 1, 1);
266 >        assertEquals(0, phaser.arrive());
267 >        assertState(phaser, 1, 1, 1);
268      }
269  
270      /**
271 <     * arrive does not wait for others to arrive at barrier
271 >     * arriveAndDeregister does not wait for others to arrive at barrier
272       */
273 <    public void testArrive2() {
273 >    public void testArriveAndDeregister() {
274          final Phaser phaser = new Phaser(1);
275 <        phaser.register();
276 <        Thread thread = null;
277 <        for (final Runnable r : getRunnables(10, SHORT_DELAY_MS)) {
278 <            phaser.register();
279 <            thread = new Thread() {
275 >        for (int i = 0; i < 10; i++) {
276 >            assertState(phaser, 0, 1, 1);
277 >            assertEquals(0, phaser.register());
278 >            assertState(phaser, 0, 2, 2);
279 >            assertEquals(0, phaser.arriveAndDeregister());
280 >            assertState(phaser, 0, 1, 1);
281 >        }
282 >        assertEquals(0, phaser.arriveAndDeregister());
283 >        assertTerminated(phaser, 1);
284 >    }
285  
286 <                public void run() {
287 <                    r.run();
288 <                    phaser.arriveAndDeregister();
289 <                }
290 <            };
291 <            thread.start();
286 >    /**
287 >     * arriveAndDeregister does not wait for others to arrive at barrier
288 >     */
289 >    public void testArrive2() {
290 >        final Phaser phaser = new Phaser();
291 >        assertEquals(0, phaser.register());
292 >        List<Thread> threads = new ArrayList<Thread>();
293 >        for (int i = 0; i < 10; i++) {
294 >            assertEquals(0, phaser.register());
295 >            threads.add(newStartedThread(new CheckedRunnable() {
296 >                public void realRun() {
297 >                    assertEquals(0, phaser.arriveAndDeregister());
298 >                }}));
299          }
300  
301 <        phaser.arrive();
302 <        assertTrue(thread.isAlive());
303 <        assertFalse(phaser.isTerminated());
301 >        for (Thread thread : threads)
302 >            awaitTermination(thread);
303 >        assertState(phaser, 0, 1, 1);
304 >        assertEquals(0, phaser.arrive());
305 >        assertState(phaser, 1, 1, 1);
306      }
307  
308      /**
309 <     * arrive() returns a negative number if the Phaser is termindated
309 >     * arrive() returns a negative number if the Phaser is terminated
310       */
311      public void testArrive3() {
312          Phaser phaser = new Phaser(1);
313          phaser.forceTermination();
314 +        assertTerminated(phaser, 0, 1);
315 +        assertEquals(0, phaser.getPhase() + Integer.MIN_VALUE);
316          assertTrue(phaser.arrive() < 0);
317 <
317 >        assertTrue(phaser.register() < 0);
318 >        assertTrue(phaser.arriveAndDeregister() < 0);
319 >        assertTrue(phaser.awaitAdvance(1) < 0);
320 >        assertTrue(phaser.getPhase() < 0);
321      }
322  
323      /**
324       * arriveAndDeregister() throws IllegalStateException if number of
325 <     * registered or unnarived parties would become negative
325 >     * registered or unarrived parties would become negative
326       */
327      public void testArriveAndDeregister1() {
328          try {
329              Phaser phaser = new Phaser();
330              phaser.arriveAndDeregister();
331              shouldThrow();
332 <
238 <        } catch (IllegalStateException success) {
239 <        }
332 >        } catch (IllegalStateException success) {}
333      }
334  
335      /**
336 <     * arriveAndDeregister derigisters reduces the number of arrived parties
336 >     * arriveAndDeregister reduces the number of arrived parties
337       */
338 <    public void testArriveAndDergeister2() {
338 >    public void testArriveAndDeregister2() {
339          final Phaser phaser = new Phaser(1);
340 <        phaser.register();
341 <        phaser.arrive();
342 <        int p = phaser.getArrivedParties();
343 <        assertTrue(p == 1);
344 <        phaser.arriveAndDeregister();
252 <        assertTrue(phaser.getArrivedParties() < p);
340 >        assertEquals(0, phaser.register());
341 >        assertEquals(0, phaser.arrive());
342 >        assertState(phaser, 0, 2, 1);
343 >        assertEquals(0, phaser.arriveAndDeregister());
344 >        assertState(phaser, 1, 1, 1);
345      }
346  
347      /**
348 <     * arriveAndDeregister arrives to the barrier on a phaser with a parent and
348 >     * arriveAndDeregister arrives at the barrier on a phaser with a parent and
349       * when a deregistration occurs and causes the phaser to have zero parties
350       * its parent will be deregistered as well
351       */
352 <    public void testArriveAndDeregsiter3() {
352 >    public void testArriveAndDeregister3() {
353          Phaser parent = new Phaser();
354 <        Phaser root = new Phaser(parent);
355 <        root.register();
356 <        assertTrue(parent.getUnarrivedParties() > 0);
357 <        assertTrue(root.getUnarrivedParties() > 0);
358 <        root.arriveAndDeregister();
359 <        assertTrue(parent.getUnarrivedParties() == 0);
360 <        assertTrue(root.getUnarrivedParties() == 0);
361 <        assertTrue(root.isTerminated() && parent.isTerminated());
354 >        Phaser child = new Phaser(parent);
355 >        assertState(child, 0, 0, 0);
356 >        assertState(parent, 0, 0, 0);
357 >        assertEquals(0, child.register());
358 >        assertState(child, 0, 1, 1);
359 >        assertState(parent, 0, 1, 1);
360 >        assertEquals(0, child.arriveAndDeregister());
361 >        assertTerminated(child, 1);
362 >        assertTerminated(parent, 1);
363      }
364  
365      /**
366       * arriveAndDeregister deregisters one party from its parent when
367 <     * the number of parties of root is zero after deregistration
367 >     * the number of parties of child is zero after deregistration
368       */
369 <    public void testArriveAndDeregsiter4() {
369 >    public void testArriveAndDeregister4() {
370          Phaser parent = new Phaser();
371 <        Phaser root = new Phaser(parent);
372 <        parent.register();
373 <        root.register();
374 <        int parentParties = parent.getUnarrivedParties();
375 <        root.arriveAndDeregister();
376 <        assertEquals(parentParties - 1, parent.getUnarrivedParties());
371 >        Phaser child = new Phaser(parent);
372 >        assertEquals(0, parent.register());
373 >        assertEquals(0, child.register());
374 >        assertState(child, 0, 1, 1);
375 >        assertState(parent, 0, 2, 2);
376 >        assertEquals(0, child.arriveAndDeregister());
377 >        assertState(child, 0, 0, 0);
378 >        assertState(parent, 0, 1, 1);
379      }
380  
381      /**
# Line 288 | Line 383 | public class PhaserTest extends JSR166Te
383       * the number of parties of root is nonzero after deregistration.
384       */
385      public void testArriveAndDeregister5() {
386 <        Phaser parent = new Phaser();
386 >        Phaser root = new Phaser();
387 >        Phaser parent = new Phaser(root);
388          Phaser child = new Phaser(parent);
389 <        Phaser root = new Phaser(child);
390 <        assertTrue(parent.getUnarrivedParties() > 0);
391 <        assertTrue(child.getUnarrivedParties() > 0);
392 <        root.register();
393 <        root.arriveAndDeregister();
394 <        assertTrue(parent.getUnarrivedParties() == 0);
395 <        assertTrue(child.getUnarrivedParties() == 0);
396 <        assertTrue(root.isTerminated());
389 >        assertState(root, 0, 0, 0);
390 >        assertState(parent, 0, 0, 0);
391 >        assertState(child, 0, 0, 0);
392 >        assertEquals(0, child.register());
393 >        assertState(root, 0, 1, 1);
394 >        assertState(parent, 0, 1, 1);
395 >        assertState(child, 0, 1, 1);
396 >        assertEquals(0, child.arriveAndDeregister());
397 >        assertTerminated(child, 1);
398 >        assertTerminated(parent, 1);
399 >        assertTerminated(root, 1);
400      }
401  
402      /**
# Line 306 | Line 405 | public class PhaserTest extends JSR166Te
405       */
406      public void testArriveAndDeregister6() {
407          final Phaser phaser = new Phaser(2);
408 <        new Thread() {
409 <
410 <            public void run() {
411 <                getRunnable(SHORT_DELAY_MS).run();
412 <                phaser.arrive();
413 <            }
414 <        }.start();
415 <        phaser.arriveAndAwaitAdvance();
416 <        int phase = phaser.arriveAndDeregister();
417 <        assertEquals(phase, phaser.getPhase());
408 >        Thread t = newStartedThread(new CheckedRunnable() {
409 >            public void realRun() {
410 >                assertEquals(0, phaser.arrive());
411 >            }});
412 >        assertEquals(1, phaser.arriveAndAwaitAdvance());
413 >        assertState(phaser, 1, 2, 2);
414 >        assertEquals(1, phaser.arriveAndDeregister());
415 >        assertState(phaser, 1, 1, 1);
416 >        assertEquals(1, phaser.arriveAndDeregister());
417 >        assertTerminated(phaser, 2);
418 >        awaitTermination(t);
419      }
420  
421      /**
# Line 323 | Line 423 | public class PhaserTest extends JSR166Te
423       */
424      public void testAwaitAdvance1() {
425          final Phaser phaser = new Phaser(1);
426 <        phaser.awaitAdvance(phaser.arrive());
426 >        assertEquals(0, phaser.arrive());
427 >        assertEquals(1, phaser.awaitAdvance(0));
428      }
429  
430      /**
# Line 331 | Line 432 | public class PhaserTest extends JSR166Te
432       * phaser
433       */
434      public void testAwaitAdvance2() {
435 <        try {
436 <            Phaser phaser = new Phaser();
437 <            phaser.awaitAdvance(-1);
337 <        } catch (Exception failure) {
338 <            this.unexpectedException();
339 <        }
435 >        Phaser phaser = new Phaser();
436 >        assertTrue(phaser.awaitAdvance(-1) < 0);
437 >        assertState(phaser, 0, 0, 0);
438      }
439  
440      /**
441 <     * awaitAdvance while waiting does not abort on interrupt.
441 >     * awaitAdvanceInterruptibly blocks interruptibly
442       */
443 <    public void testAwaitAdvance3() {
444 <        final Phaser phaser = new Phaser();
445 <        Thread th1 = new Thread() {
443 >    public void testAwaitAdvanceInterruptibly_interruptible() throws InterruptedException {
444 >        final Phaser phaser = new Phaser(1);
445 >        final CountDownLatch pleaseInterrupt = new CountDownLatch(2);
446  
447 <            public void run() {
447 >        Thread t1 = newStartedThread(new CheckedRunnable() {
448 >            public void realRun() {
449 >                Thread.currentThread().interrupt();
450                  try {
451 <                    phaser.register();
452 <                    getRunnable(LONG_DELAY_MS).run();
453 <                    phaser.awaitAdvance(phaser.arrive());
454 <                } catch (Exception failure) {
355 <                    threadUnexpectedException(failure);
356 <                }
451 >                    phaser.awaitAdvanceInterruptibly(0);
452 >                    shouldThrow();
453 >                } catch (InterruptedException success) {}
454 >                assertFalse(Thread.interrupted());
455  
456 <            }
457 <        };
458 <        phaser.register();
459 <        th1.start();
460 <        try {
461 <            Thread.sleep(SHORT_DELAY_MS);
462 <            th1.interrupt();
463 <            Thread.sleep(LONG_DELAY_MS);
464 <            phaser.arrive();
465 <        } catch (Exception failure) {
466 <            unexpectedException();
467 <        }
468 <        assertFalse(th1.isInterrupted());
456 >                pleaseInterrupt.countDown();
457 >                try {
458 >                    phaser.awaitAdvanceInterruptibly(0);
459 >                    shouldThrow();
460 >                } catch (InterruptedException success) {}
461 >                assertFalse(Thread.interrupted());
462 >            }});
463 >
464 >        Thread t2 = newStartedThread(new CheckedRunnable() {
465 >            public void realRun() throws TimeoutException {
466 >                Thread.currentThread().interrupt();
467 >                try {
468 >                    phaser.awaitAdvanceInterruptibly(0, 2*LONG_DELAY_MS, MILLISECONDS);
469 >                    shouldThrow();
470 >                } catch (InterruptedException success) {}
471 >                assertFalse(Thread.interrupted());
472 >
473 >                pleaseInterrupt.countDown();
474 >                try {
475 >                    phaser.awaitAdvanceInterruptibly(0, 2*LONG_DELAY_MS, MILLISECONDS);
476 >                    shouldThrow();
477 >                } catch (InterruptedException success) {}
478 >                assertFalse(Thread.interrupted());
479 >            }});
480 >
481 >        await(pleaseInterrupt);
482 >        assertState(phaser, 0, 1, 1);
483 >        assertThreadsStayAlive(t1, t2);
484 >        t1.interrupt();
485 >        t2.interrupt();
486 >        awaitTermination(t1);
487 >        awaitTermination(t2);
488 >        assertState(phaser, 0, 1, 1);
489 >        assertEquals(0, phaser.arrive());
490 >        assertState(phaser, 1, 1, 1);
491 >    }
492 >
493 >    /**
494 >     * awaitAdvance continues waiting if interrupted before waiting
495 >     */
496 >    public void testAwaitAdvanceAfterInterrupt() {
497 >        final Phaser phaser = new Phaser();
498 >        assertEquals(0, phaser.register());
499 >        final CountDownLatch pleaseArrive = new CountDownLatch(1);
500 >
501 >        Thread t = newStartedThread(new CheckedRunnable() {
502 >            public void realRun() {
503 >                Thread.currentThread().interrupt();
504 >                assertEquals(0, phaser.register());
505 >                assertEquals(0, phaser.arrive());
506 >                pleaseArrive.countDown();
507 >                assertTrue(Thread.currentThread().isInterrupted());
508 >                assertEquals(1, phaser.awaitAdvance(0));
509 >                assertTrue(Thread.interrupted());
510 >            }});
511 >
512 >        await(pleaseArrive);
513 >        waitForThreadToEnterWaitState(t, SHORT_DELAY_MS);
514 >        assertEquals(0, phaser.arrive());
515 >        awaitTermination(t);
516 >
517 >        Thread.currentThread().interrupt();
518 >        assertEquals(1, phaser.awaitAdvance(0));
519 >        assertTrue(Thread.interrupted());
520 >    }
521 >
522 >    /**
523 >     *  awaitAdvance continues waiting if interrupted while waiting
524 >     */
525 >    public void testAwaitAdvanceBeforeInterrupt() {
526 >        final Phaser phaser = new Phaser();
527 >        assertEquals(0, phaser.register());
528 >        final CountDownLatch pleaseArrive = new CountDownLatch(1);
529 >
530 >        Thread t = newStartedThread(new CheckedRunnable() {
531 >            public void realRun() {
532 >                assertEquals(0, phaser.register());
533 >                assertEquals(0, phaser.arrive());
534 >                assertFalse(Thread.currentThread().isInterrupted());
535 >                pleaseArrive.countDown();
536 >                assertEquals(1, phaser.awaitAdvance(0));
537 >                assertTrue(Thread.interrupted());
538 >            }});
539 >
540 >        await(pleaseArrive);
541 >        waitForThreadToEnterWaitState(t, SHORT_DELAY_MS);
542 >        t.interrupt();
543 >        assertEquals(0, phaser.arrive());
544 >        awaitTermination(t);
545 >
546 >        Thread.currentThread().interrupt();
547 >        assertEquals(1, phaser.awaitAdvance(0));
548 >        assertTrue(Thread.interrupted());
549 >    }
550 >
551 >    /**
552 >     * arriveAndAwaitAdvance continues waiting if interrupted before waiting
553 >     */
554 >    public void testArriveAndAwaitAdvanceAfterInterrupt() {
555 >        final Phaser phaser = new Phaser();
556 >        assertEquals(0, phaser.register());
557 >        final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
558 >
559 >        Thread t = newStartedThread(new CheckedRunnable() {
560 >            public void realRun() {
561 >                Thread.currentThread().interrupt();
562 >                assertEquals(0, phaser.register());
563 >                pleaseInterrupt.countDown();
564 >                assertTrue(Thread.currentThread().isInterrupted());
565 >                assertEquals(1, phaser.arriveAndAwaitAdvance());
566 >                assertTrue(Thread.currentThread().isInterrupted());
567 >            }});
568 >
569 >        await(pleaseInterrupt);
570 >        waitForThreadToEnterWaitState(t, SHORT_DELAY_MS);
571 >        Thread.currentThread().interrupt();
572 >        assertEquals(1, phaser.arriveAndAwaitAdvance());
573 >        assertTrue(Thread.interrupted());
574 >        awaitTermination(t);
575 >    }
576 >
577 >    /**
578 >     * arriveAndAwaitAdvance continues waiting if interrupted while waiting
579 >     */
580 >    public void testArriveAndAwaitAdvanceBeforeInterrupt() {
581 >        final Phaser phaser = new Phaser();
582 >        assertEquals(0, phaser.register());
583 >        final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
584 >
585 >        Thread t = newStartedThread(new CheckedRunnable() {
586 >            public void realRun() {
587 >                assertEquals(0, phaser.register());
588 >                assertFalse(Thread.currentThread().isInterrupted());
589 >                pleaseInterrupt.countDown();
590 >                assertEquals(1, phaser.arriveAndAwaitAdvance());
591 >                assertTrue(Thread.currentThread().isInterrupted());
592 >            }});
593 >
594 >        await(pleaseInterrupt);
595 >        waitForThreadToEnterWaitState(t, SHORT_DELAY_MS);
596 >        t.interrupt();
597 >        Thread.currentThread().interrupt();
598 >        assertEquals(1, phaser.arriveAndAwaitAdvance());
599 >        assertTrue(Thread.interrupted());
600 >        awaitTermination(t);
601      }
602  
603      /**
# Line 375 | Line 605 | public class PhaserTest extends JSR166Te
605       * complete before continuing
606       */
607      public void testAwaitAdvance4() {
608 <        final Phaser phaser = new Phaser(four);
609 <        final AtomicInteger phaseCount = new AtomicInteger(0);
610 <        for (int i = 0; i < four; i++) {
611 <            new Thread() {
612 <
613 <                public void run() {
614 <                    int phase = phaser.arrive();
615 <                    phaseCount.incrementAndGet();
616 <                    getRunnable(LONG_DELAY_MS).run();
617 <                    phaser.awaitAdvance(phase);
618 <                    assertTrue(phaseCount.get() == four);
619 <                }
620 <            }.start();
621 <        }
608 >        final Phaser phaser = new Phaser(4);
609 >        final AtomicInteger count = new AtomicInteger(0);
610 >        List<Thread> threads = new ArrayList<Thread>();
611 >        for (int i = 0; i < 4; i++)
612 >            threads.add(newStartedThread(new CheckedRunnable() {
613 >                public void realRun() {
614 >                    for (int k = 0; k < 3; k++) {
615 >                        assertEquals(2*k+1, phaser.arriveAndAwaitAdvance());
616 >                        count.incrementAndGet();
617 >                        assertEquals(2*k+1, phaser.arrive());
618 >                        assertEquals(2*k+2, phaser.awaitAdvance(2*k+1));
619 >                        assertEquals(count.get(), 4*(k+1));
620 >                    }}}));
621 >
622 >        for (Thread thread : threads)
623 >            awaitTermination(thread);
624      }
625  
626      /**
# Line 396 | Line 628 | public class PhaserTest extends JSR166Te
628       */
629      public void testAwaitAdvance5() {
630          final Phaser phaser = new Phaser(1);
631 <        int phase = phaser.awaitAdvance(phaser.arrive());
632 <        assertEquals(phase, phaser.getPhase());
633 <        phaser.register();
634 <        for (int i = 0; i < eight; i++) {
635 <            new Thread() {
636 <
637 <                public void run() {
638 <                    getRunnable(SHORT_DELAY_MS).run();
631 >        assertEquals(1, phaser.awaitAdvance(phaser.arrive()));
632 >        assertEquals(1, phaser.getPhase());
633 >        assertEquals(1, phaser.register());
634 >        List<Thread> threads = new ArrayList<Thread>();
635 >        for (int i = 0; i < 8; i++) {
636 >            final CountDownLatch latch = new CountDownLatch(1);
637 >            final boolean goesFirst = ((i & 1) == 0);
638 >            threads.add(newStartedThread(new CheckedRunnable() {
639 >                public void realRun() {
640 >                    if (goesFirst)
641 >                        latch.countDown();
642 >                    else
643 >                        await(latch);
644                      phaser.arrive();
645 <                }
646 <            }.start();
647 <            phase = phaser.awaitAdvance(phaser.arrive());
648 <            assertEquals(phase, phaser.getPhase());
645 >                }}));
646 >            if (goesFirst)
647 >                await(latch);
648 >            else
649 >                latch.countDown();
650 >            assertEquals(i + 2, phaser.awaitAdvance(phaser.arrive()));
651 >            assertEquals(i + 2, phaser.getPhase());
652 >        }
653 >        for (Thread thread : threads)
654 >            awaitTermination(thread);
655 >    }
656 >
657 >    /**
658 >     * awaitAdvance returns the current phase in child phasers
659 >     */
660 >    public void testAwaitAdvanceTieredPhaser() throws Exception {
661 >        final Phaser parent = new Phaser();
662 >        final List<Phaser> zeroPartyChildren = new ArrayList<Phaser>(3);
663 >        final List<Phaser> onePartyChildren = new ArrayList<Phaser>(3);
664 >        for (int i = 0; i < 3; i++) {
665 >            zeroPartyChildren.add(new Phaser(parent, 0));
666 >            onePartyChildren.add(new Phaser(parent, 1));
667 >        }
668 >        final List<Phaser> phasers = new ArrayList<Phaser>();
669 >        phasers.addAll(zeroPartyChildren);
670 >        phasers.addAll(onePartyChildren);
671 >        phasers.add(parent);
672 >        for (Phaser phaser : phasers) {
673 >            assertEquals(-42, phaser.awaitAdvance(-42));
674 >            assertEquals(-42, phaser.awaitAdvanceInterruptibly(-42));
675 >            assertEquals(-42, phaser.awaitAdvanceInterruptibly(-42, SMALL_DELAY_MS, MILLISECONDS));
676 >        }
677 >
678 >        for (Phaser child : onePartyChildren)
679 >            assertEquals(0, child.arrive());
680 >        for (Phaser phaser : phasers) {
681 >            assertEquals(-42, phaser.awaitAdvance(-42));
682 >            assertEquals(-42, phaser.awaitAdvanceInterruptibly(-42));
683 >            assertEquals(-42, phaser.awaitAdvanceInterruptibly(-42, SMALL_DELAY_MS, MILLISECONDS));
684 >            assertEquals(1, phaser.awaitAdvance(0));
685 >            assertEquals(1, phaser.awaitAdvanceInterruptibly(0));
686 >            assertEquals(1, phaser.awaitAdvanceInterruptibly(0, SMALL_DELAY_MS, MILLISECONDS));
687 >        }
688 >
689 >        for (Phaser child : onePartyChildren)
690 >            assertEquals(1, child.arrive());
691 >        for (Phaser phaser : phasers) {
692 >            assertEquals(-42, phaser.awaitAdvance(-42));
693 >            assertEquals(-42, phaser.awaitAdvanceInterruptibly(-42));
694 >            assertEquals(-42, phaser.awaitAdvanceInterruptibly(-42, SMALL_DELAY_MS, MILLISECONDS));
695 >            assertEquals(2, phaser.awaitAdvance(0));
696 >            assertEquals(2, phaser.awaitAdvanceInterruptibly(0));
697 >            assertEquals(2, phaser.awaitAdvanceInterruptibly(0, SMALL_DELAY_MS, MILLISECONDS));
698 >            assertEquals(2, phaser.awaitAdvance(1));
699 >            assertEquals(2, phaser.awaitAdvanceInterruptibly(1));
700 >            assertEquals(2, phaser.awaitAdvanceInterruptibly(1, SMALL_DELAY_MS, MILLISECONDS));
701          }
702      }
703  
# Line 417 | Line 706 | public class PhaserTest extends JSR166Te
706       */
707      public void testAwaitAdvance6() {
708          final Phaser phaser = new Phaser(3);
709 <        /*
710 <         * Start new thread. This thread waits a small amount of time
711 <         * and waits for the other two parties to arrive.  The party
712 <         * in the main thread arrives quickly so at best this thread
713 <         * waits for the second thread's party to arrive
714 <         */
715 <        new Thread() {
716 <            
717 <            public void run() {
718 <                getRunnable(SMALL_DELAY_MS).run();
719 <                int phase = phaser.awaitAdvance(phaser.arrive());
720 <                /*
721 <                 * This point is reached when force termination is called in which phase = -1
722 <                 */
723 <                threadAssertTrue(phase < 0);
724 <                threadAssertTrue(phaser.isTerminated());
436 <            }
437 <        }.start();
438 <        /*
439 <         * This thread will cause the first thread run to wait, in doing so
440 <         * the main thread will force termination in which the first thread
441 <         * should exit peacefully as this one
442 <         */
443 <        new Thread() {
444 <
445 <            public void run() {
446 <                getRunnable(LONG_DELAY_MS).run();
447 <                int p1 = phaser.arrive();
448 <                int phase = phaser.awaitAdvance(p1);
449 <                threadAssertTrue(phase < 0);
450 <                threadAssertTrue(phaser.isTerminated());
451 <            }
452 <        }.start();
453 <
454 <        phaser.arrive();
709 >        final CountDownLatch pleaseForceTermination = new CountDownLatch(2);
710 >        final List<Thread> threads = new ArrayList<Thread>();
711 >        for (int i = 0; i < 2; i++) {
712 >            Runnable r = new CheckedRunnable() {
713 >                public void realRun() {
714 >                    assertEquals(0, phaser.arrive());
715 >                    pleaseForceTermination.countDown();
716 >                    assertTrue(phaser.awaitAdvance(0) < 0);
717 >                    assertTrue(phaser.isTerminated());
718 >                    assertTrue(phaser.getPhase() < 0);
719 >                    assertEquals(0, phaser.getPhase() + Integer.MIN_VALUE);
720 >                    assertEquals(3, phaser.getRegisteredParties());
721 >                }};
722 >            threads.add(newStartedThread(r));
723 >        }
724 >        await(pleaseForceTermination);
725          phaser.forceTermination();
726 +        assertTrue(phaser.isTerminated());
727 +        assertEquals(0, phaser.getPhase() + Integer.MIN_VALUE);
728 +        for (Thread thread : threads)
729 +            awaitTermination(thread);
730 +        assertEquals(3, phaser.getRegisteredParties());
731      }
732  
733      /**
# Line 464 | Line 739 | public class PhaserTest extends JSR166Te
739              Phaser phaser = new Phaser();
740              phaser.arriveAndAwaitAdvance();
741              shouldThrow();
742 <        } catch (IllegalStateException success) {
468 <        }
469 <    }
470 <
471 <    /**
472 <     * Interrupted arriveAndAwaitAdvance does not throw InterruptedException
473 <     */
474 <    public void testArriveAndAwaitAdvance2() {
475 <        final Phaser phaser = new Phaser(2);
476 <        Thread th = new Thread() {
477 <            public void run() {
478 <                try {
479 <                    phaser.arriveAndAwaitAdvance();
480 <                } catch (Exception failure) {
481 <                    threadUnexpectedException(failure);
482 <                }
483 <            }
484 <        };
485 <
486 <        try {
487 <            th.start();
488 <            Thread.sleep(LONG_DELAY_MS);
489 <            th.interrupt();
490 <            Thread.sleep(LONG_DELAY_MS);
491 <            phaser.arrive();
492 <        } catch (InterruptedException failure) {
493 <            this.unexpectedException();
494 <        }
495 <        assertFalse(th.isInterrupted());
742 >        } catch (IllegalStateException success) {}
743      }
744  
745      /**
# Line 502 | Line 749 | public class PhaserTest extends JSR166Te
749       */
750      public void testArriveAndAwaitAdvance3() {
751          final Phaser phaser = new Phaser(1);
752 <        final AtomicInteger arrivingCount = new AtomicInteger(0);
753 <        for (final Runnable run : getRunnables(six, SHORT_DELAY_MS)) {
754 <            new Thread() {
755 <
756 <                public void run() {
757 <                    phaser.register();
758 <                    run.run();
759 <                    arrivingCount.getAndIncrement();
760 <                    phaser.arrive();
761 <                }
762 <            }.start();
763 <        }
764 <        int phaseNumber = phaser.arriveAndAwaitAdvance();
765 <        arrivingCount.incrementAndGet();
766 <        //the + 1 adds to expectedArrive to account for the main threads arrival
767 <        int expectedArrived = phaseNumber > 0 ? phaseNumber * six + 1 : phaser.getArrivedParties() + 1;
768 <        threadAssertEquals(expectedArrived, arrivingCount.get());
769 <    }
770 <    // .. initially called, for n tasks via
771 <    private List<Runnable> getRunnables(int size, long wait) {
772 <        List<Runnable> list = new ArrayList<Runnable>();
773 <        for (int i = 0; i < size; i++) {
774 <            list.add(getRunnable(wait));
775 <        }
776 <        return list;
777 <    }
531 <
532 <    private Runnable getRunnable(final long wait) {
533 <        return new Runnable() {
534 <
535 <            public void run() {
536 <                try {
537 <                    Thread.sleep(wait);
538 <                } catch (InterruptedException noop) {
539 <                // sleep interruption isn't a problem case for these example
540 <                } catch (Exception ex) {
541 <                    threadUnexpectedException(ex);
542 <                }
543 <
544 <            }
545 <        };
752 >        final int THREADS = 3;
753 >        final CountDownLatch pleaseArrive = new CountDownLatch(THREADS);
754 >        final List<Thread> threads = new ArrayList<Thread>();
755 >        for (int i = 0; i < THREADS; i++)
756 >            threads.add(newStartedThread(new CheckedRunnable() {
757 >                public void realRun() {
758 >                    assertEquals(0, phaser.register());
759 >                    pleaseArrive.countDown();
760 >                    assertEquals(1, phaser.arriveAndAwaitAdvance());
761 >                }}));
762 >
763 >        await(pleaseArrive);
764 >        long startTime = System.nanoTime();
765 >        while (phaser.getArrivedParties() < THREADS)
766 >            Thread.yield();
767 >        assertEquals(THREADS, phaser.getArrivedParties());
768 >        assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
769 >        for (Thread thread : threads)
770 >            waitForThreadToEnterWaitState(thread, SHORT_DELAY_MS);
771 >        for (Thread thread : threads)
772 >            assertTrue(thread.isAlive());
773 >        assertState(phaser, 0, THREADS + 1, 1);
774 >        phaser.arriveAndAwaitAdvance();
775 >        for (Thread thread : threads)
776 >            awaitTermination(thread);
777 >        assertState(phaser, 1, THREADS + 1, THREADS + 1);
778      }
779  
780   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines