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.10 by jsr166, Tue Dec 1 10:03:59 2009 UTC vs.
Revision 1.34 by jsr166, Mon Jun 27 04:07:51 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              shouldThrow();
# Line 45 | Line 78 | public class PhaserTest extends JSR166Te
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 >
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 +    /**
120       * The parent being input into the parameter should equal the original
121       * parent when being returned
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());
85 <        assertEquals(0, phaser.getArrivedParties());
135 >        assertState(phaser, 0, 0, 0);
136 >        assertEquals(0, phaser.register());
137 >        assertState(phaser, 0, 1, 1);
138      }
139  
140      /**
# Line 90 | Line 142 | public class PhaserTest extends JSR166Te
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 +
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 >     * XXXX broken (hangs) as of 2011-06-26
195 >     */
196 >    public void XXXXtestRegisterEmptySubPhaser() {
197 >        Phaser root = new Phaser();
198 >        Phaser child1 = new Phaser(root, 1);
199 >        Phaser child2 = new Phaser(root, 0);
200 >        assertEquals(0, child2.register());
201 >        assertEquals(0, child2.arriveAndDeregister());
202 >        assertEquals(0, child2.register());
203 >        assertEquals(0, child2.arriveAndDeregister());
204 >        assertState(child2, 0, 0, 0);
205      }
206  
207      /**
# Line 142 | Line 216 | public class PhaserTest extends JSR166Te
216      }
217  
218      /**
219 <     * bulkRegister should correctly record the number of unarrived parties with
220 <     * the number of parties being registered
219 >     * bulkRegister should correctly record the number of unarrived
220 >     * parties with the number of parties being registered
221       */
222      public void testBulkRegister2() {
223          Phaser phaser = new Phaser();
224 <        phaser.bulkRegister(20);
225 <        assertEquals(20, phaser.getUnarrivedParties());
224 >        assertEquals(0, phaser.bulkRegister(0));
225 >        assertState(phaser, 0, 0, 0);
226 >        assertEquals(0, phaser.bulkRegister(20));
227 >        assertState(phaser, 0, 20, 20);
228      }
229  
230      /**
# Line 156 | Line 232 | public class PhaserTest extends JSR166Te
232       * throws IllegalStateException.
233       */
234      public void testBulkRegister3() {
235 +        assertEquals(0, new Phaser().bulkRegister((1 << 16) - 1));
236 +
237          try {
238              new Phaser().bulkRegister(1 << 16);
239              shouldThrow();
240          } catch (IllegalStateException success) {}
241 +
242 +        try {
243 +            new Phaser(2).bulkRegister((1 << 16) - 2);
244 +            shouldThrow();
245 +        } catch (IllegalStateException success) {}
246      }
247  
248      /**
# Line 176 | Line 259 | public class PhaserTest extends JSR166Te
259      }
260  
261      /**
262 <     *  Arrive() on a registered phaser increments phase.
262 >     * arrive() on a registered phaser increments phase.
263       */
264      public void testArrive1() {
265          Phaser phaser = new Phaser(1);
266 <        phaser.arrive();
267 <        assertEquals(1, phaser.getPhase());
266 >        assertState(phaser, 0, 1, 1);
267 >        assertEquals(0, phaser.arrive());
268 >        assertState(phaser, 1, 1, 1);
269      }
270  
271      /**
272       * arriveAndDeregister does not wait for others to arrive at barrier
273       */
274 <    public void testArrive2() throws InterruptedException {
274 >    public void testArriveAndDeregister() {
275          final Phaser phaser = new Phaser(1);
276 <        phaser.register();
276 >        for (int i = 0; i < 10; i++) {
277 >            assertState(phaser, 0, 1, 1);
278 >            assertEquals(0, phaser.register());
279 >            assertState(phaser, 0, 2, 2);
280 >            assertEquals(0, phaser.arriveAndDeregister());
281 >            assertState(phaser, 0, 1, 1);
282 >        }
283 >        assertEquals(0, phaser.arriveAndDeregister());
284 >        assertTerminated(phaser, 1);
285 >    }
286 >
287 >    /**
288 >     * arriveAndDeregister does not wait for others to arrive at barrier
289 >     */
290 >    public void testArrive2() {
291 >        final Phaser phaser = new Phaser();
292 >        assertEquals(0, phaser.register());
293          List<Thread> threads = new ArrayList<Thread>();
294 <        for (int i = 0; i < 10; i++)
295 <            phaser.register();
294 >        for (int i = 0; i < 10; i++) {
295 >            assertEquals(0, phaser.register());
296              threads.add(newStartedThread(new CheckedRunnable() {
297 <                public void realRun() throws InterruptedException {
298 <                    Thread.sleep(SMALL_DELAY_MS);
199 <                    phaser.arriveAndDeregister();
297 >                public void realRun() {
298 >                    assertEquals(0, phaser.arriveAndDeregister());
299                  }}));
300 +        }
301  
202        phaser.arrive();
203        assertTrue(threads.get(0).isAlive());
204        assertFalse(phaser.isTerminated());
302          for (Thread thread : threads)
303 <            thread.join();
303 >            awaitTermination(thread);
304 >        assertState(phaser, 0, 1, 1);
305 >        assertEquals(0, phaser.arrive());
306 >        assertState(phaser, 1, 1, 1);
307      }
308  
309      /**
# Line 212 | Line 312 | public class PhaserTest extends JSR166Te
312      public void testArrive3() {
313          Phaser phaser = new Phaser(1);
314          phaser.forceTermination();
315 +        assertTerminated(phaser, 0, 1);
316 +        assertEquals(0, phaser.getPhase() + Integer.MIN_VALUE);
317          assertTrue(phaser.arrive() < 0);
318 +        assertTrue(phaser.register() < 0);
319 +        assertTrue(phaser.arriveAndDeregister() < 0);
320 +        assertTrue(phaser.awaitAdvance(1) < 0);
321 +        assertTrue(phaser.getPhase() < 0);
322      }
323  
324      /**
# Line 228 | Line 334 | public class PhaserTest extends JSR166Te
334      }
335  
336      /**
337 <     * arriveAndDeregister deregisters reduces the number of arrived parties
337 >     * arriveAndDeregister reduces the number of arrived parties
338       */
339 <    public void testArriveAndDergeister2() {
339 >    public void testArriveAndDeregister2() {
340          final Phaser phaser = new Phaser(1);
341 <        phaser.register();
342 <        phaser.arrive();
343 <        int p = phaser.getArrivedParties();
344 <        assertTrue(p == 1);
345 <        phaser.arriveAndDeregister();
240 <        assertTrue(phaser.getArrivedParties() < p);
341 >        assertEquals(0, phaser.register());
342 >        assertEquals(0, phaser.arrive());
343 >        assertState(phaser, 0, 2, 1);
344 >        assertEquals(0, phaser.arriveAndDeregister());
345 >        assertState(phaser, 1, 1, 1);
346      }
347  
348      /**
349 <     * arriveAndDeregister arrives to the barrier on a phaser with a parent and
349 >     * arriveAndDeregister arrives at the barrier on a phaser with a parent and
350       * when a deregistration occurs and causes the phaser to have zero parties
351       * its parent will be deregistered as well
352       */
353 <    public void testArriveAndDeregsiter3() {
353 >    public void testArriveAndDeregister3() {
354          Phaser parent = new Phaser();
355 <        Phaser root = new Phaser(parent);
356 <        root.register();
357 <        assertTrue(parent.getUnarrivedParties() > 0);
358 <        assertTrue(root.getUnarrivedParties() > 0);
359 <        root.arriveAndDeregister();
360 <        assertTrue(parent.getUnarrivedParties() == 0);
361 <        assertTrue(root.getUnarrivedParties() == 0);
362 <        assertTrue(root.isTerminated() && parent.isTerminated());
355 >        Phaser child = new Phaser(parent);
356 >        assertState(child, 0, 0, 0);
357 >        assertState(parent, 0, 0, 0);
358 >        assertEquals(0, child.register());
359 >        assertState(child, 0, 1, 1);
360 >        assertState(parent, 0, 1, 1);
361 >        assertEquals(0, child.arriveAndDeregister());
362 >        assertTerminated(child, 1);
363 >        assertTerminated(parent, 1);
364      }
365  
366      /**
367       * arriveAndDeregister deregisters one party from its parent when
368 <     * the number of parties of root is zero after deregistration
368 >     * the number of parties of child is zero after deregistration
369       */
370 <    public void testArriveAndDeregsiter4() {
370 >    public void testArriveAndDeregister4() {
371          Phaser parent = new Phaser();
372 <        Phaser root = new Phaser(parent);
373 <        parent.register();
374 <        root.register();
375 <        int parentParties = parent.getUnarrivedParties();
376 <        root.arriveAndDeregister();
377 <        assertEquals(parentParties - 1, parent.getUnarrivedParties());
372 >        Phaser child = new Phaser(parent);
373 >        assertEquals(0, parent.register());
374 >        assertEquals(0, child.register());
375 >        assertState(child, 0, 1, 1);
376 >        assertState(parent, 0, 2, 2);
377 >        assertEquals(0, child.arriveAndDeregister());
378 >        assertState(child, 0, 0, 0);
379 >        assertState(parent, 0, 1, 1);
380      }
381  
382      /**
# Line 276 | Line 384 | public class PhaserTest extends JSR166Te
384       * the number of parties of root is nonzero after deregistration.
385       */
386      public void testArriveAndDeregister5() {
387 <        Phaser parent = new Phaser();
387 >        Phaser root = new Phaser();
388 >        Phaser parent = new Phaser(root);
389          Phaser child = new Phaser(parent);
390 <        Phaser root = new Phaser(child);
391 <        assertTrue(parent.getUnarrivedParties() > 0);
392 <        assertTrue(child.getUnarrivedParties() > 0);
393 <        root.register();
394 <        root.arriveAndDeregister();
395 <        assertTrue(parent.getUnarrivedParties() == 0);
396 <        assertTrue(child.getUnarrivedParties() == 0);
397 <        assertTrue(root.isTerminated());
390 >        assertState(root, 0, 0, 0);
391 >        assertState(parent, 0, 0, 0);
392 >        assertState(child, 0, 0, 0);
393 >        assertEquals(0, child.register());
394 >        assertState(root, 0, 1, 1);
395 >        assertState(parent, 0, 1, 1);
396 >        assertState(child, 0, 1, 1);
397 >        assertEquals(0, child.arriveAndDeregister());
398 >        assertTerminated(child, 1);
399 >        assertTerminated(parent, 1);
400 >        assertTerminated(root, 1);
401      }
402  
403      /**
404       * arriveAndDeregister returns the phase in which it leaves the
405       * phaser in after deregistration
406       */
407 <    public void testArriveAndDeregister6() throws InterruptedException {
407 >    public void testArriveAndDeregister6() {
408          final Phaser phaser = new Phaser(2);
409          Thread t = newStartedThread(new CheckedRunnable() {
410              public void realRun() {
411 <                sleepTillInterrupted(SHORT_DELAY_MS);
300 <                phaser.arrive();
411 >                assertEquals(0, phaser.arrive());
412              }});
413 <        phaser.arriveAndAwaitAdvance();
414 <        int phase = phaser.arriveAndDeregister();
415 <        assertEquals(phase, phaser.getPhase());
416 <        t.join();
413 >        assertEquals(1, phaser.arriveAndAwaitAdvance());
414 >        assertState(phaser, 1, 2, 2);
415 >        assertEquals(1, phaser.arriveAndDeregister());
416 >        assertState(phaser, 1, 1, 1);
417 >        assertEquals(1, phaser.arriveAndDeregister());
418 >        assertTerminated(phaser, 2);
419 >        awaitTermination(t);
420      }
421  
422      /**
# Line 310 | Line 424 | public class PhaserTest extends JSR166Te
424       */
425      public void testAwaitAdvance1() {
426          final Phaser phaser = new Phaser(1);
427 <        phaser.awaitAdvance(phaser.arrive());
427 >        assertEquals(0, phaser.arrive());
428 >        assertEquals(1, phaser.awaitAdvance(0));
429      }
430  
431      /**
# Line 319 | Line 434 | public class PhaserTest extends JSR166Te
434       */
435      public void testAwaitAdvance2() {
436          Phaser phaser = new Phaser();
437 <        phaser.awaitAdvance(-1);
437 >        assertTrue(phaser.awaitAdvance(-1) < 0);
438 >        assertState(phaser, 0, 0, 0);
439 >    }
440 >
441 >    /**
442 >     * awaitAdvanceInterruptibly blocks interruptibly
443 >     */
444 >    public void testAwaitAdvanceInterruptibly_interruptible() throws InterruptedException {
445 >        final Phaser phaser = new Phaser(1);
446 >        final CountDownLatch pleaseInterrupt = new CountDownLatch(2);
447 >
448 >        Thread t1 = newStartedThread(new CheckedRunnable() {
449 >            public void realRun() {
450 >                Thread.currentThread().interrupt();
451 >                try {
452 >                    phaser.awaitAdvanceInterruptibly(0);
453 >                    shouldThrow();
454 >                } catch (InterruptedException success) {}
455 >                assertFalse(Thread.interrupted());
456 >
457 >                pleaseInterrupt.countDown();
458 >                try {
459 >                    phaser.awaitAdvanceInterruptibly(0);
460 >                    shouldThrow();
461 >                } catch (InterruptedException success) {}
462 >                assertFalse(Thread.interrupted());
463 >            }});
464 >
465 >        Thread t2 = newStartedThread(new CheckedRunnable() {
466 >            public void realRun() throws TimeoutException {
467 >                Thread.currentThread().interrupt();
468 >                try {
469 >                    phaser.awaitAdvanceInterruptibly(0, 2*LONG_DELAY_MS, MILLISECONDS);
470 >                    shouldThrow();
471 >                } catch (InterruptedException success) {}
472 >                assertFalse(Thread.interrupted());
473 >
474 >                pleaseInterrupt.countDown();
475 >                try {
476 >                    phaser.awaitAdvanceInterruptibly(0, 2*LONG_DELAY_MS, MILLISECONDS);
477 >                    shouldThrow();
478 >                } catch (InterruptedException success) {}
479 >                assertFalse(Thread.interrupted());
480 >            }});
481 >
482 >        await(pleaseInterrupt);
483 >        assertState(phaser, 0, 1, 1);
484 >        assertThreadsStayAlive(t1, t2);
485 >        t1.interrupt();
486 >        t2.interrupt();
487 >        awaitTermination(t1);
488 >        awaitTermination(t2);
489 >        assertState(phaser, 0, 1, 1);
490 >        assertEquals(0, phaser.arrive());
491 >        assertState(phaser, 1, 1, 1);
492      }
493  
494      /**
495 <     * awaitAdvance while waiting does not abort on interrupt.
495 >     * awaitAdvance continues waiting if interrupted before waiting
496       */
497 <    public void testAwaitAdvance3() throws InterruptedException {
497 >    public void testAwaitAdvanceAfterInterrupt() {
498          final Phaser phaser = new Phaser();
499 <        phaser.register();
499 >        assertEquals(0, phaser.register());
500 >        final CountDownLatch pleaseArrive = new CountDownLatch(1);
501  
502          Thread t = newStartedThread(new CheckedRunnable() {
503 <            public void realRun() throws InterruptedException {
504 <                phaser.register();
505 <                sleepTillInterrupted(LONG_DELAY_MS);
506 <                phaser.awaitAdvance(phaser.arrive());
503 >            public void realRun() {
504 >                Thread.currentThread().interrupt();
505 >                assertEquals(0, phaser.register());
506 >                assertEquals(0, phaser.arrive());
507 >                pleaseArrive.countDown();
508 >                assertTrue(Thread.currentThread().isInterrupted());
509 >                assertEquals(1, phaser.awaitAdvance(0));
510 >                assertTrue(Thread.interrupted());
511              }});
512 <        Thread.sleep(SMALL_DELAY_MS);
512 >
513 >        await(pleaseArrive);
514 >        waitForThreadToEnterWaitState(t, SHORT_DELAY_MS);
515 >        assertEquals(0, phaser.arrive());
516 >        awaitTermination(t);
517 >
518 >        Thread.currentThread().interrupt();
519 >        assertEquals(1, phaser.awaitAdvance(0));
520 >        assertTrue(Thread.interrupted());
521 >    }
522 >
523 >    /**
524 >     *  awaitAdvance continues waiting if interrupted while waiting
525 >     */
526 >    public void testAwaitAdvanceBeforeInterrupt() {
527 >        final Phaser phaser = new Phaser();
528 >        assertEquals(0, phaser.register());
529 >        final CountDownLatch pleaseArrive = new CountDownLatch(1);
530 >
531 >        Thread t = newStartedThread(new CheckedRunnable() {
532 >            public void realRun() {
533 >                assertEquals(0, phaser.register());
534 >                assertEquals(0, phaser.arrive());
535 >                assertFalse(Thread.currentThread().isInterrupted());
536 >                pleaseArrive.countDown();
537 >                assertEquals(1, phaser.awaitAdvance(0));
538 >                assertTrue(Thread.interrupted());
539 >            }});
540 >
541 >        await(pleaseArrive);
542 >        waitForThreadToEnterWaitState(t, SHORT_DELAY_MS);
543          t.interrupt();
544 <        Thread.sleep(SMALL_DELAY_MS);
545 <        phaser.arrive();
546 <        assertFalse(t.isInterrupted());
547 <        t.join();
544 >        assertEquals(0, phaser.arrive());
545 >        awaitTermination(t);
546 >
547 >        Thread.currentThread().interrupt();
548 >        assertEquals(1, phaser.awaitAdvance(0));
549 >        assertTrue(Thread.interrupted());
550 >    }
551 >
552 >    /**
553 >     * arriveAndAwaitAdvance continues waiting if interrupted before waiting
554 >     */
555 >    public void testArriveAndAwaitAdvanceAfterInterrupt() {
556 >        final Phaser phaser = new Phaser();
557 >        assertEquals(0, phaser.register());
558 >        final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
559 >
560 >        Thread t = newStartedThread(new CheckedRunnable() {
561 >            public void realRun() {
562 >                Thread.currentThread().interrupt();
563 >                assertEquals(0, phaser.register());
564 >                pleaseInterrupt.countDown();
565 >                assertTrue(Thread.currentThread().isInterrupted());
566 >                assertEquals(1, phaser.arriveAndAwaitAdvance());
567 >                assertTrue(Thread.currentThread().isInterrupted());
568 >            }});
569 >
570 >        await(pleaseInterrupt);
571 >        waitForThreadToEnterWaitState(t, SHORT_DELAY_MS);
572 >        Thread.currentThread().interrupt();
573 >        assertEquals(1, phaser.arriveAndAwaitAdvance());
574 >        assertTrue(Thread.interrupted());
575 >        awaitTermination(t);
576 >    }
577 >
578 >    /**
579 >     * arriveAndAwaitAdvance continues waiting if interrupted while waiting
580 >     */
581 >    public void testArriveAndAwaitAdvanceBeforeInterrupt() {
582 >        final Phaser phaser = new Phaser();
583 >        assertEquals(0, phaser.register());
584 >        final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
585 >
586 >        Thread t = newStartedThread(new CheckedRunnable() {
587 >            public void realRun() {
588 >                assertEquals(0, phaser.register());
589 >                assertFalse(Thread.currentThread().isInterrupted());
590 >                pleaseInterrupt.countDown();
591 >                assertEquals(1, phaser.arriveAndAwaitAdvance());
592 >                assertTrue(Thread.currentThread().isInterrupted());
593 >            }});
594 >
595 >        await(pleaseInterrupt);
596 >        waitForThreadToEnterWaitState(t, SHORT_DELAY_MS);
597 >        t.interrupt();
598 >        Thread.currentThread().interrupt();
599 >        assertEquals(1, phaser.arriveAndAwaitAdvance());
600 >        assertTrue(Thread.interrupted());
601 >        awaitTermination(t);
602      }
603  
604      /**
605       * awaitAdvance atomically waits for all parties within the same phase to
606       * complete before continuing
607       */
608 <    public void testAwaitAdvance4() throws InterruptedException {
608 >    public void testAwaitAdvance4() {
609          final Phaser phaser = new Phaser(4);
610 <        final AtomicInteger phaseCount = new AtomicInteger(0);
610 >        final AtomicInteger count = new AtomicInteger(0);
611          List<Thread> threads = new ArrayList<Thread>();
612 <        for (int i = 0; i < 4; i++) {
612 >        for (int i = 0; i < 4; i++)
613              threads.add(newStartedThread(new CheckedRunnable() {
614                  public void realRun() {
615 <                    int phase = phaser.arrive();
616 <                    phaseCount.incrementAndGet();
617 <                    sleepTillInterrupted(SMALL_DELAY_MS);
618 <                    phaser.awaitAdvance(phase);
619 <                    assertEquals(phaseCount.get(), 4);
620 <                }}));
621 <        }
615 >                    for (int k = 0; k < 3; k++) {
616 >                        assertEquals(2*k+1, phaser.arriveAndAwaitAdvance());
617 >                        count.incrementAndGet();
618 >                        assertEquals(2*k+1, phaser.arrive());
619 >                        assertEquals(2*k+2, phaser.awaitAdvance(2*k+1));
620 >                        assertEquals(count.get(), 4*(k+1));
621 >                    }}}));
622 >
623          for (Thread thread : threads)
624 <            thread.join();
624 >            awaitTermination(thread);
625      }
626  
627      /**
628       * awaitAdvance returns the current phase
629       */
630 <    public void testAwaitAdvance5() throws InterruptedException {
630 >    public void testAwaitAdvance5() {
631          final Phaser phaser = new Phaser(1);
632 <        int phase = phaser.awaitAdvance(phaser.arrive());
633 <        assertEquals(phase, phaser.getPhase());
634 <        phaser.register();
632 >        assertEquals(1, phaser.awaitAdvance(phaser.arrive()));
633 >        assertEquals(1, phaser.getPhase());
634 >        assertEquals(1, phaser.register());
635          List<Thread> threads = new ArrayList<Thread>();
636          for (int i = 0; i < 8; i++) {
637 +            final CountDownLatch latch = new CountDownLatch(1);
638 +            final boolean goesFirst = ((i & 1) == 0);
639              threads.add(newStartedThread(new CheckedRunnable() {
640                  public void realRun() {
641 <                    sleepTillInterrupted(SHORT_DELAY_MS);
641 >                    if (goesFirst)
642 >                        latch.countDown();
643 >                    else
644 >                        await(latch);
645                      phaser.arrive();
646                  }}));
647 <            phase = phaser.awaitAdvance(phaser.arrive());
648 <            assertEquals(phase, phaser.getPhase());
647 >            if (goesFirst)
648 >                await(latch);
649 >            else
650 >                latch.countDown();
651 >            assertEquals(i + 2, phaser.awaitAdvance(phaser.arrive()));
652 >            assertEquals(i + 2, phaser.getPhase());
653          }
654          for (Thread thread : threads)
655 <            thread.join();
655 >            awaitTermination(thread);
656 >    }
657 >
658 >    /**
659 >     * awaitAdvance returns the current phase in child phasers
660 >     */
661 >    public void testAwaitAdvanceTieredPhaser() throws Exception {
662 >        final Phaser parent = new Phaser();
663 >        final List<Phaser> zeroPartyChildren = new ArrayList<Phaser>(3);
664 >        final List<Phaser> onePartyChildren = new ArrayList<Phaser>(3);
665 >        for (int i = 0; i < 3; i++) {
666 >            zeroPartyChildren.add(new Phaser(parent, 0));
667 >            onePartyChildren.add(new Phaser(parent, 1));
668 >        }
669 >        final List<Phaser> phasers = new ArrayList<Phaser>();
670 >        phasers.addAll(zeroPartyChildren);
671 >        phasers.addAll(onePartyChildren);
672 >        phasers.add(parent);
673 >        for (Phaser phaser : phasers) {
674 >            assertEquals(-42, phaser.awaitAdvance(-42));
675 >            assertEquals(-42, phaser.awaitAdvanceInterruptibly(-42));
676 >            assertEquals(-42, phaser.awaitAdvanceInterruptibly(-42, SMALL_DELAY_MS, MILLISECONDS));
677 >        }
678 >
679 >        for (Phaser child : onePartyChildren)
680 >            assertEquals(0, child.arrive());
681 >        for (Phaser phaser : phasers) {
682 >            assertEquals(-42, phaser.awaitAdvance(-42));
683 >            assertEquals(-42, phaser.awaitAdvanceInterruptibly(-42));
684 >            assertEquals(-42, phaser.awaitAdvanceInterruptibly(-42, SMALL_DELAY_MS, MILLISECONDS));
685 >            assertEquals(1, phaser.awaitAdvance(0));
686 >            assertEquals(1, phaser.awaitAdvanceInterruptibly(0));
687 >            assertEquals(1, phaser.awaitAdvanceInterruptibly(0, SMALL_DELAY_MS, MILLISECONDS));
688 >        }
689 >
690 >        for (Phaser child : onePartyChildren)
691 >            assertEquals(1, child.arrive());
692 >        for (Phaser phaser : phasers) {
693 >            assertEquals(-42, phaser.awaitAdvance(-42));
694 >            assertEquals(-42, phaser.awaitAdvanceInterruptibly(-42));
695 >            assertEquals(-42, phaser.awaitAdvanceInterruptibly(-42, SMALL_DELAY_MS, MILLISECONDS));
696 >            assertEquals(2, phaser.awaitAdvance(0));
697 >            assertEquals(2, phaser.awaitAdvanceInterruptibly(0));
698 >            assertEquals(2, phaser.awaitAdvanceInterruptibly(0, SMALL_DELAY_MS, MILLISECONDS));
699 >            assertEquals(2, phaser.awaitAdvance(1));
700 >            assertEquals(2, phaser.awaitAdvanceInterruptibly(1));
701 >            assertEquals(2, phaser.awaitAdvanceInterruptibly(1, SMALL_DELAY_MS, MILLISECONDS));
702 >        }
703      }
704  
705      /**
706       * awaitAdvance returns when the phaser is externally terminated
707       */
708 <    public void testAwaitAdvance6() throws InterruptedException {
708 >    public void testAwaitAdvance6() {
709          final Phaser phaser = new Phaser(3);
710 <        /*
711 <         * Start new thread. This thread waits a small amount of time
712 <         * and waits for the other two parties to arrive.  The party
713 <         * in the main thread arrives quickly so at best this thread
714 <         * waits for the second thread's party to arrive
715 <         */
716 <        Thread t1 = newStartedThread(new CheckedRunnable() {
717 <            public void realRun() {
718 <                sleepTillInterrupted(SMALL_DELAY_MS);
719 <                int phase = phaser.awaitAdvance(phaser.arrive());
720 <                /*
721 <                 * This point is reached when force termination is called in which phase = -1
722 <                 */
723 <                assertTrue(phase < 0);
724 <                assertTrue(phaser.isTerminated());
725 <            }});
411 <        /*
412 <         * This thread will cause the first thread run to wait, in doing so
413 <         * the main thread will force termination in which the first thread
414 <         * should exit peacefully as this one
415 <         */
416 <        Thread t2 = newStartedThread(new CheckedRunnable() {
417 <            public void realRun() {
418 <                sleepTillInterrupted(MEDIUM_DELAY_MS);
419 <                int p1 = phaser.arrive();
420 <                int phase = phaser.awaitAdvance(p1);
421 <                assertTrue(phase < 0);
422 <                assertTrue(phaser.isTerminated());
423 <            }});
424 <
425 <        phaser.arrive();
710 >        final CountDownLatch pleaseForceTermination = new CountDownLatch(2);
711 >        final List<Thread> threads = new ArrayList<Thread>();
712 >        for (int i = 0; i < 2; i++) {
713 >            Runnable r = new CheckedRunnable() {
714 >                public void realRun() {
715 >                    assertEquals(0, phaser.arrive());
716 >                    pleaseForceTermination.countDown();
717 >                    assertTrue(phaser.awaitAdvance(0) < 0);
718 >                    assertTrue(phaser.isTerminated());
719 >                    assertTrue(phaser.getPhase() < 0);
720 >                    assertEquals(0, phaser.getPhase() + Integer.MIN_VALUE);
721 >                    assertEquals(3, phaser.getRegisteredParties());
722 >                }};
723 >            threads.add(newStartedThread(r));
724 >        }
725 >        await(pleaseForceTermination);
726          phaser.forceTermination();
727 <        t1.join();
728 <        t2.join();
727 >        assertTrue(phaser.isTerminated());
728 >        assertEquals(0, phaser.getPhase() + Integer.MIN_VALUE);
729 >        for (Thread thread : threads)
730 >            awaitTermination(thread);
731 >        assertEquals(3, phaser.getRegisteredParties());
732      }
733  
734      /**
# Line 441 | Line 744 | public class PhaserTest extends JSR166Te
744      }
745  
746      /**
444     * Interrupted arriveAndAwaitAdvance does not throw InterruptedException
445     */
446    public void testArriveAndAwaitAdvance2() throws InterruptedException {
447        final Phaser phaser = new Phaser(2);
448        Thread th = newStartedThread(new CheckedRunnable() {
449            public void realRun() {
450                phaser.arriveAndAwaitAdvance();
451            }});
452
453        Thread.sleep(SMALL_DELAY_MS);
454        th.interrupt();
455        Thread.sleep(SMALL_DELAY_MS);
456        phaser.arrive();
457        assertFalse(th.isInterrupted());
458        th.join();
459    }
460
461    /**
747       * arriveAndAwaitAdvance waits for all threads to arrive, the
748       * number of arrived parties is the same number that is accounted
749       * for when the main thread awaitsAdvance
750       */
751 <    public void testArriveAndAwaitAdvance3() throws InterruptedException {
751 >    public void testArriveAndAwaitAdvance3() {
752          final Phaser phaser = new Phaser(1);
753 <        final AtomicInteger arrivingCount = new AtomicInteger(0);
753 >        final int THREADS = 3;
754 >        final CountDownLatch pleaseArrive = new CountDownLatch(THREADS);
755          final List<Thread> threads = new ArrayList<Thread>();
756 <        for (int i = 0; i < 6; i++) {
756 >        for (int i = 0; i < THREADS; i++)
757              threads.add(newStartedThread(new CheckedRunnable() {
758 <                public void realRun() throws InterruptedException {
759 <                    phaser.register();
760 <                    sleepTillInterrupted(SHORT_DELAY_MS);
761 <                    arrivingCount.getAndIncrement();
476 <                    phaser.arrive();
758 >                public void realRun() {
759 >                    assertEquals(0, phaser.register());
760 >                    pleaseArrive.countDown();
761 >                    assertEquals(1, phaser.arriveAndAwaitAdvance());
762                  }}));
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 <        assertEquals(expectedArrived, arrivingCount.get());
763 >
764 >        await(pleaseArrive);
765 >        long startTime = System.nanoTime();
766 >        while (phaser.getArrivedParties() < THREADS)
767 >            Thread.yield();
768 >        assertEquals(THREADS, phaser.getArrivedParties());
769 >        assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
770 >        for (Thread thread : threads)
771 >            waitForThreadToEnterWaitState(thread, SHORT_DELAY_MS);
772 >        for (Thread thread : threads)
773 >            assertTrue(thread.isAlive());
774 >        assertState(phaser, 0, THREADS + 1, 1);
775 >        phaser.arriveAndAwaitAdvance();
776          for (Thread thread : threads)
777 <            thread.join();
777 >            awaitTermination(thread);
778 >        assertState(phaser, 1, THREADS + 1, THREADS + 1);
779      }
780  
781   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines