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