ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ForkJoinTask8Test.java
Revision: 1.31
Committed: Wed Nov 8 02:21:43 2017 UTC (6 years, 5 months ago) by jsr166
Branch: MAIN
Changes since 1.30: +1 -1 lines
Log Message:
rollback: better exception handling

File Contents

# User Rev Content
1 dl 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/publicdomain/zero/1.0/
5     */
6 jsr166 1.7
7     import static java.util.concurrent.TimeUnit.MILLISECONDS;
8    
9 jsr166 1.12 import java.util.Arrays;
10 dl 1.15 import java.util.concurrent.CountDownLatch;
11 dl 1.1 import java.util.concurrent.ExecutionException;
12     import java.util.concurrent.ForkJoinPool;
13     import java.util.concurrent.ForkJoinTask;
14 dl 1.15 import java.util.concurrent.ForkJoinWorkerThread;
15 dl 1.1 import java.util.concurrent.RecursiveAction;
16     import java.util.concurrent.TimeoutException;
17 jsr166 1.7
18     import junit.framework.Test;
19     import junit.framework.TestSuite;
20 dl 1.1
21     public class ForkJoinTask8Test extends JSR166TestCase {
22    
23     /*
24     * Testing notes: This differs from ForkJoinTaskTest mainly by
25     * defining a version of BinaryAsyncAction that uses JDK8 task
26     * tags for control state, thereby testing getForkJoinTaskTag,
27     * setForkJoinTaskTag, and compareAndSetForkJoinTaskTag across
28     * various contexts. Most of the test methods using it are
29     * otherwise identical, but omitting retest of those dealing with
30     * cancellation, which is not represented in this tag scheme.
31     */
32    
33     static final short INITIAL_STATE = -1;
34     static final short COMPLETE_STATE = 0;
35     static final short EXCEPTION_STATE = 1;
36    
37     public static void main(String[] args) {
38 jsr166 1.14 main(suite(), args);
39 dl 1.1 }
40    
41     public static Test suite() {
42     return new TestSuite(ForkJoinTask8Test.class);
43     }
44    
45     // Runs with "mainPool" use > 1 thread. singletonPool tests use 1
46     static final int mainPoolSize =
47     Math.max(2, Runtime.getRuntime().availableProcessors());
48    
49     private static ForkJoinPool mainPool() {
50     return new ForkJoinPool(mainPoolSize);
51     }
52    
53     private static ForkJoinPool singletonPool() {
54     return new ForkJoinPool(1);
55     }
56    
57     private static ForkJoinPool asyncSingletonPool() {
58     return new ForkJoinPool(1,
59     ForkJoinPool.defaultForkJoinWorkerThreadFactory,
60     null, true);
61     }
62    
63 jsr166 1.12 // Compute fib naively and efficiently
64     final int[] fib;
65     {
66     int[] fib = new int[10];
67     fib[0] = 0;
68     fib[1] = 1;
69     for (int i = 2; i < fib.length; i++)
70     fib[i] = fib[i - 1] + fib[i - 2];
71     this.fib = fib;
72     }
73    
74 dl 1.1 private void testInvokeOnPool(ForkJoinPool pool, RecursiveAction a) {
75 jsr166 1.18 try (PoolCleaner cleaner = cleaner(pool)) {
76 dl 1.1 assertFalse(a.isDone());
77     assertFalse(a.isCompletedNormally());
78     assertFalse(a.isCompletedAbnormally());
79     assertFalse(a.isCancelled());
80     assertNull(a.getException());
81     assertNull(a.getRawResult());
82    
83     assertNull(pool.invoke(a));
84    
85     assertTrue(a.isDone());
86     assertTrue(a.isCompletedNormally());
87     assertFalse(a.isCompletedAbnormally());
88     assertFalse(a.isCancelled());
89     assertNull(a.getException());
90     assertNull(a.getRawResult());
91     }
92     }
93    
94     void checkNotDone(ForkJoinTask a) {
95     assertFalse(a.isDone());
96     assertFalse(a.isCompletedNormally());
97     assertFalse(a.isCompletedAbnormally());
98     assertFalse(a.isCancelled());
99     assertNull(a.getException());
100     assertNull(a.getRawResult());
101     if (a instanceof BinaryAsyncAction)
102 jsr166 1.28 assertEquals(INITIAL_STATE,
103     ((BinaryAsyncAction)a).getForkJoinTaskTag());
104 dl 1.1
105     try {
106 jsr166 1.29 a.get(randomExpiredTimeout(), randomTimeUnit());
107 dl 1.1 shouldThrow();
108     } catch (TimeoutException success) {
109     } catch (Throwable fail) { threadUnexpectedException(fail); }
110     }
111    
112     <T> void checkCompletedNormally(ForkJoinTask<T> a) {
113     checkCompletedNormally(a, null);
114     }
115    
116     <T> void checkCompletedNormally(ForkJoinTask<T> a, T expected) {
117     assertTrue(a.isDone());
118     assertFalse(a.isCancelled());
119     assertTrue(a.isCompletedNormally());
120     assertFalse(a.isCompletedAbnormally());
121     assertNull(a.getException());
122     assertSame(expected, a.getRawResult());
123     if (a instanceof BinaryAsyncAction)
124 jsr166 1.28 assertEquals(COMPLETE_STATE,
125     ((BinaryAsyncAction)a).getForkJoinTaskTag());
126 dl 1.1
127     {
128     Thread.currentThread().interrupt();
129 jsr166 1.20 long startTime = System.nanoTime();
130 dl 1.1 assertSame(expected, a.join());
131 jsr166 1.29 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
132 dl 1.1 Thread.interrupted();
133     }
134    
135     {
136     Thread.currentThread().interrupt();
137 jsr166 1.20 long startTime = System.nanoTime();
138 dl 1.1 a.quietlyJoin(); // should be no-op
139 jsr166 1.29 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
140 dl 1.1 Thread.interrupted();
141     }
142    
143     assertFalse(a.cancel(false));
144     assertFalse(a.cancel(true));
145     try {
146     assertSame(expected, a.get());
147 jsr166 1.29 assertSame(expected, a.get(randomTimeout(), randomTimeUnit()));
148 jsr166 1.31 } catch (Throwable fail) { threadUnexpectedException(fail); }
149 dl 1.1 }
150    
151     void checkCompletedAbnormally(ForkJoinTask a, Throwable t) {
152     assertTrue(a.isDone());
153     assertFalse(a.isCancelled());
154     assertFalse(a.isCompletedNormally());
155     assertTrue(a.isCompletedAbnormally());
156     assertSame(t.getClass(), a.getException().getClass());
157     assertNull(a.getRawResult());
158     assertFalse(a.cancel(false));
159     assertFalse(a.cancel(true));
160     if (a instanceof BinaryAsyncAction)
161     assertTrue(((BinaryAsyncAction)a).getForkJoinTaskTag() != INITIAL_STATE);
162    
163     try {
164     Thread.currentThread().interrupt();
165     a.join();
166     shouldThrow();
167     } catch (Throwable expected) {
168     assertSame(t.getClass(), expected.getClass());
169     }
170     Thread.interrupted();
171    
172     {
173 jsr166 1.20 long startTime = System.nanoTime();
174 dl 1.1 a.quietlyJoin(); // should be no-op
175 jsr166 1.29 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
176 dl 1.1 }
177    
178     try {
179     a.get();
180     shouldThrow();
181     } catch (ExecutionException success) {
182     assertSame(t.getClass(), success.getCause().getClass());
183     } catch (Throwable fail) { threadUnexpectedException(fail); }
184    
185     try {
186 jsr166 1.29 a.get(randomTimeout(), randomTimeUnit());
187 dl 1.1 shouldThrow();
188     } catch (ExecutionException success) {
189     assertSame(t.getClass(), success.getCause().getClass());
190     } catch (Throwable fail) { threadUnexpectedException(fail); }
191     }
192    
193     public static final class FJException extends RuntimeException {
194     FJException() { super(); }
195     }
196    
197     abstract static class BinaryAsyncAction extends ForkJoinTask<Void> {
198    
199 dl 1.19 private volatile BinaryAsyncAction parent;
200 dl 1.1
201 dl 1.19 private volatile BinaryAsyncAction sibling;
202 dl 1.1
203     protected BinaryAsyncAction() {
204     setForkJoinTaskTag(INITIAL_STATE);
205     }
206    
207     public final Void getRawResult() { return null; }
208     protected final void setRawResult(Void mustBeNull) { }
209    
210     public final void linkSubtasks(BinaryAsyncAction x, BinaryAsyncAction y) {
211     x.parent = y.parent = this;
212     x.sibling = y;
213     y.sibling = x;
214     }
215    
216     protected void onComplete(BinaryAsyncAction x, BinaryAsyncAction y) {
217 jsr166 1.2 if (this.getForkJoinTaskTag() != COMPLETE_STATE ||
218     x.getForkJoinTaskTag() != COMPLETE_STATE ||
219 dl 1.1 y.getForkJoinTaskTag() != COMPLETE_STATE) {
220     completeThisExceptionally(new FJException());
221     }
222     }
223    
224     protected boolean onException() {
225     return true;
226     }
227    
228     public void linkAndForkSubtasks(BinaryAsyncAction x, BinaryAsyncAction y) {
229     linkSubtasks(x, y);
230     y.fork();
231     x.fork();
232     }
233    
234     private void completeThis() {
235     setForkJoinTaskTag(COMPLETE_STATE);
236     super.complete(null);
237     }
238    
239     private void completeThisExceptionally(Throwable ex) {
240     setForkJoinTaskTag(EXCEPTION_STATE);
241     super.completeExceptionally(ex);
242     }
243    
244 dl 1.23 public boolean cancel(boolean mayInterruptIfRunning) {
245     if (super.cancel(mayInterruptIfRunning)) {
246     completeExceptionally(new FJException());
247     return true;
248     }
249     return false;
250     }
251 jsr166 1.24
252 dl 1.1 public final void complete() {
253     BinaryAsyncAction a = this;
254     for (;;) {
255     BinaryAsyncAction s = a.sibling;
256     BinaryAsyncAction p = a.parent;
257     a.sibling = null;
258     a.parent = null;
259     a.completeThis();
260 jsr166 1.2 if (p == null ||
261 dl 1.1 p.compareAndSetForkJoinTaskTag(INITIAL_STATE, COMPLETE_STATE))
262     break;
263     try {
264     p.onComplete(a, s);
265     } catch (Throwable rex) {
266     p.completeExceptionally(rex);
267     return;
268     }
269     a = p;
270     }
271     }
272    
273     public final void completeExceptionally(Throwable ex) {
274 dl 1.23 for (BinaryAsyncAction a = this;;) {
275 dl 1.1 a.completeThisExceptionally(ex);
276     BinaryAsyncAction s = a.sibling;
277 dl 1.23 if (s != null && !s.isDone())
278     s.completeExceptionally(ex);
279     if ((a = a.parent) == null)
280 dl 1.1 break;
281     }
282     }
283    
284     public final BinaryAsyncAction getParent() {
285     return parent;
286     }
287    
288     public BinaryAsyncAction getSibling() {
289     return sibling;
290     }
291    
292     public void reinitialize() {
293     parent = sibling = null;
294     super.reinitialize();
295     }
296    
297     }
298    
299 jsr166 1.12 final class AsyncFib extends BinaryAsyncAction {
300 dl 1.1 int number;
301 jsr166 1.12 int expectedResult;
302     public AsyncFib(int number) {
303     this.number = number;
304     this.expectedResult = fib[number];
305 dl 1.1 }
306    
307     public final boolean exec() {
308     try {
309     AsyncFib f = this;
310     int n = f.number;
311 dl 1.25 while (n > 1) {
312     AsyncFib p = f;
313     AsyncFib r = new AsyncFib(n - 2);
314     f = new AsyncFib(--n);
315     p.linkSubtasks(r, f);
316     r.fork();
317 dl 1.1 }
318     f.complete();
319     }
320 jsr166 1.2 catch (Throwable ex) {
321 dl 1.1 compareAndSetForkJoinTaskTag(INITIAL_STATE, EXCEPTION_STATE);
322     }
323 dl 1.23 if (getForkJoinTaskTag() == EXCEPTION_STATE)
324     throw new FJException();
325 dl 1.1 return false;
326     }
327    
328     protected void onComplete(BinaryAsyncAction x, BinaryAsyncAction y) {
329     number = ((AsyncFib)x).number + ((AsyncFib)y).number;
330     super.onComplete(x, y);
331     }
332 jsr166 1.12
333     public void checkCompletedNormally() {
334     assertEquals(expectedResult, number);
335     ForkJoinTask8Test.this.checkCompletedNormally(this);
336     }
337 dl 1.1 }
338    
339     static final class FailingAsyncFib extends BinaryAsyncAction {
340     int number;
341     public FailingAsyncFib(int n) {
342     this.number = n;
343     }
344    
345     public final boolean exec() {
346 dl 1.23 try {
347     FailingAsyncFib f = this;
348     int n = f.number;
349 dl 1.25 while (n > 1) {
350     FailingAsyncFib p = f;
351     FailingAsyncFib r = new FailingAsyncFib(n - 2);
352     f = new FailingAsyncFib(--n);
353     p.linkSubtasks(r, f);
354     r.fork();
355 dl 1.1 }
356 dl 1.23 f.complete();
357     }
358     catch (Throwable ex) {
359     compareAndSetForkJoinTaskTag(INITIAL_STATE, EXCEPTION_STATE);
360 dl 1.1 }
361 dl 1.23 if (getForkJoinTaskTag() == EXCEPTION_STATE)
362     throw new FJException();
363 dl 1.1 return false;
364     }
365    
366     protected void onComplete(BinaryAsyncAction x, BinaryAsyncAction y) {
367     completeExceptionally(new FJException());
368     }
369     }
370    
371     /**
372     * invoke returns when task completes normally.
373     * isCompletedAbnormally and isCancelled return false for normally
374     * completed tasks; getRawResult returns null.
375     */
376     public void testInvoke() {
377 jsr166 1.12 testInvoke(mainPool());
378     }
379     public void testInvoke_Singleton() {
380     testInvoke(singletonPool());
381     }
382     public void testInvoke(ForkJoinPool pool) {
383 dl 1.1 RecursiveAction a = new CheckedRecursiveAction() {
384     protected void realCompute() {
385     AsyncFib f = new AsyncFib(8);
386     assertNull(f.invoke());
387 jsr166 1.12 f.checkCompletedNormally();
388 dl 1.1 }};
389 jsr166 1.12 testInvokeOnPool(pool, a);
390 dl 1.1 }
391    
392     /**
393     * quietlyInvoke task returns when task completes normally.
394     * isCompletedAbnormally and isCancelled return false for normally
395     * completed tasks
396     */
397     public void testQuietlyInvoke() {
398 jsr166 1.12 testQuietlyInvoke(mainPool());
399     }
400     public void testQuietlyInvoke_Singleton() {
401     testQuietlyInvoke(singletonPool());
402     }
403     public void testQuietlyInvoke(ForkJoinPool pool) {
404 dl 1.1 RecursiveAction a = new CheckedRecursiveAction() {
405     protected void realCompute() {
406     AsyncFib f = new AsyncFib(8);
407     f.quietlyInvoke();
408 jsr166 1.12 f.checkCompletedNormally();
409 dl 1.1 }};
410 jsr166 1.12 testInvokeOnPool(pool, a);
411 dl 1.1 }
412    
413     /**
414     * join of a forked task returns when task completes
415     */
416     public void testForkJoin() {
417 jsr166 1.12 testForkJoin(mainPool());
418     }
419     public void testForkJoin_Singleton() {
420     testForkJoin(singletonPool());
421     }
422     public void testForkJoin(ForkJoinPool pool) {
423 dl 1.1 RecursiveAction a = new CheckedRecursiveAction() {
424     protected void realCompute() {
425     AsyncFib f = new AsyncFib(8);
426     assertSame(f, f.fork());
427     assertNull(f.join());
428 jsr166 1.12 f.checkCompletedNormally();
429 dl 1.1 }};
430 jsr166 1.12 testInvokeOnPool(pool, a);
431 dl 1.1 }
432    
433     /**
434     * get of a forked task returns when task completes
435     */
436     public void testForkGet() {
437 jsr166 1.12 testForkGet(mainPool());
438     }
439     public void testForkGet_Singleton() {
440     testForkGet(singletonPool());
441     }
442     public void testForkGet(ForkJoinPool pool) {
443 dl 1.1 RecursiveAction a = new CheckedRecursiveAction() {
444     protected void realCompute() throws Exception {
445     AsyncFib f = new AsyncFib(8);
446     assertSame(f, f.fork());
447     assertNull(f.get());
448 jsr166 1.12 f.checkCompletedNormally();
449 dl 1.1 }};
450 jsr166 1.12 testInvokeOnPool(pool, a);
451 dl 1.1 }
452    
453     /**
454     * timed get of a forked task returns when task completes
455     */
456     public void testForkTimedGet() {
457 jsr166 1.12 testForkTimedGet(mainPool());
458     }
459     public void testForkTimedGet_Singleton() {
460     testForkTimedGet(singletonPool());
461     }
462     public void testForkTimedGet(ForkJoinPool pool) {
463 dl 1.1 RecursiveAction a = new CheckedRecursiveAction() {
464     protected void realCompute() throws Exception {
465     AsyncFib f = new AsyncFib(8);
466     assertSame(f, f.fork());
467     assertNull(f.get(LONG_DELAY_MS, MILLISECONDS));
468 jsr166 1.12 f.checkCompletedNormally();
469 dl 1.1 }};
470 jsr166 1.12 testInvokeOnPool(pool, a);
471 dl 1.1 }
472    
473     /**
474 jsr166 1.12 * timed get with null time unit throws NullPointerException
475 dl 1.1 */
476 jsr166 1.12 public void testForkTimedGetNullTimeUnit() {
477     testForkTimedGetNullTimeUnit(mainPool());
478     }
479     public void testForkTimedGetNullTimeUnit_Singleton() {
480     testForkTimedGet(singletonPool());
481     }
482     public void testForkTimedGetNullTimeUnit(ForkJoinPool pool) {
483 dl 1.1 RecursiveAction a = new CheckedRecursiveAction() {
484     protected void realCompute() throws Exception {
485     AsyncFib f = new AsyncFib(8);
486     assertSame(f, f.fork());
487     try {
488 jsr166 1.29 f.get(randomTimeout(), null);
489 dl 1.1 shouldThrow();
490     } catch (NullPointerException success) {}
491     }};
492 jsr166 1.12 testInvokeOnPool(pool, a);
493 dl 1.1 }
494    
495     /**
496     * quietlyJoin of a forked task returns when task completes
497     */
498     public void testForkQuietlyJoin() {
499 jsr166 1.12 testForkQuietlyJoin(mainPool());
500     }
501     public void testForkQuietlyJoin_Singleton() {
502     testForkQuietlyJoin(singletonPool());
503     }
504     public void testForkQuietlyJoin(ForkJoinPool pool) {
505 dl 1.1 RecursiveAction a = new CheckedRecursiveAction() {
506     protected void realCompute() {
507     AsyncFib f = new AsyncFib(8);
508     assertSame(f, f.fork());
509     f.quietlyJoin();
510 jsr166 1.12 f.checkCompletedNormally();
511 dl 1.1 }};
512 jsr166 1.12 testInvokeOnPool(pool, a);
513 dl 1.1 }
514    
515     /**
516     * helpQuiesce returns when tasks are complete.
517     * getQueuedTaskCount returns 0 when quiescent
518     */
519     public void testForkHelpQuiesce() {
520 jsr166 1.12 testForkHelpQuiesce(mainPool());
521     }
522     public void testForkHelpQuiesce_Singleton() {
523     testForkHelpQuiesce(singletonPool());
524     }
525     public void testForkHelpQuiesce(ForkJoinPool pool) {
526 dl 1.1 RecursiveAction a = new CheckedRecursiveAction() {
527     protected void realCompute() {
528     AsyncFib f = new AsyncFib(8);
529     assertSame(f, f.fork());
530     helpQuiesce();
531     assertEquals(0, getQueuedTaskCount());
532 jsr166 1.12 f.checkCompletedNormally();
533 dl 1.1 }};
534 jsr166 1.12 testInvokeOnPool(pool, a);
535 dl 1.1 }
536    
537     /**
538     * invoke task throws exception when task completes abnormally
539     */
540     public void testAbnormalInvoke() {
541 jsr166 1.12 testAbnormalInvoke(mainPool());
542     }
543     public void testAbnormalInvoke_Singleton() {
544     testAbnormalInvoke(singletonPool());
545     }
546     public void testAbnormalInvoke(ForkJoinPool pool) {
547 dl 1.1 RecursiveAction a = new CheckedRecursiveAction() {
548     protected void realCompute() {
549     FailingAsyncFib f = new FailingAsyncFib(8);
550     try {
551     f.invoke();
552     shouldThrow();
553     } catch (FJException success) {
554     checkCompletedAbnormally(f, success);
555     }
556     }};
557 jsr166 1.12 testInvokeOnPool(pool, a);
558 dl 1.1 }
559    
560     /**
561     * quietlyInvoke task returns when task completes abnormally
562     */
563     public void testAbnormalQuietlyInvoke() {
564 jsr166 1.12 testAbnormalQuietlyInvoke(mainPool());
565     }
566     public void testAbnormalQuietlyInvoke_Singleton() {
567     testAbnormalQuietlyInvoke(singletonPool());
568     }
569     public void testAbnormalQuietlyInvoke(ForkJoinPool pool) {
570 dl 1.1 RecursiveAction a = new CheckedRecursiveAction() {
571     protected void realCompute() {
572     FailingAsyncFib f = new FailingAsyncFib(8);
573     f.quietlyInvoke();
574     assertTrue(f.getException() instanceof FJException);
575     checkCompletedAbnormally(f, f.getException());
576     }};
577 jsr166 1.12 testInvokeOnPool(pool, a);
578 dl 1.1 }
579    
580     /**
581     * join of a forked task throws exception when task completes abnormally
582     */
583     public void testAbnormalForkJoin() {
584 jsr166 1.12 testAbnormalForkJoin(mainPool());
585     }
586     public void testAbnormalForkJoin_Singleton() {
587     testAbnormalForkJoin(singletonPool());
588     }
589     public void testAbnormalForkJoin(ForkJoinPool pool) {
590 dl 1.1 RecursiveAction a = new CheckedRecursiveAction() {
591     protected void realCompute() {
592     FailingAsyncFib f = new FailingAsyncFib(8);
593     assertSame(f, f.fork());
594     try {
595     f.join();
596     shouldThrow();
597     } catch (FJException success) {
598     checkCompletedAbnormally(f, success);
599     }
600     }};
601 jsr166 1.12 testInvokeOnPool(pool, a);
602 dl 1.1 }
603    
604     /**
605     * get of a forked task throws exception when task completes abnormally
606     */
607     public void testAbnormalForkGet() {
608 jsr166 1.12 testAbnormalForkGet(mainPool());
609     }
610     public void testAbnormalForkGet_Singleton() {
611     testAbnormalForkJoin(singletonPool());
612     }
613     public void testAbnormalForkGet(ForkJoinPool pool) {
614 dl 1.1 RecursiveAction a = new CheckedRecursiveAction() {
615     protected void realCompute() throws Exception {
616     FailingAsyncFib f = new FailingAsyncFib(8);
617     assertSame(f, f.fork());
618     try {
619     f.get();
620     shouldThrow();
621     } catch (ExecutionException success) {
622     Throwable cause = success.getCause();
623     assertTrue(cause instanceof FJException);
624     checkCompletedAbnormally(f, cause);
625     }
626     }};
627 jsr166 1.12 testInvokeOnPool(pool, a);
628 dl 1.1 }
629    
630     /**
631     * timed get of a forked task throws exception when task completes abnormally
632     */
633     public void testAbnormalForkTimedGet() {
634 jsr166 1.12 testAbnormalForkTimedGet(mainPool());
635     }
636     public void testAbnormalForkTimedGet_Singleton() {
637     testAbnormalForkTimedGet(singletonPool());
638     }
639     public void testAbnormalForkTimedGet(ForkJoinPool pool) {
640 dl 1.1 RecursiveAction a = new CheckedRecursiveAction() {
641     protected void realCompute() throws Exception {
642     FailingAsyncFib f = new FailingAsyncFib(8);
643     assertSame(f, f.fork());
644     try {
645     f.get(LONG_DELAY_MS, MILLISECONDS);
646     shouldThrow();
647     } catch (ExecutionException success) {
648     Throwable cause = success.getCause();
649     assertTrue(cause instanceof FJException);
650     checkCompletedAbnormally(f, cause);
651     }
652     }};
653 jsr166 1.12 testInvokeOnPool(pool, a);
654 dl 1.1 }
655    
656     /**
657     * quietlyJoin of a forked task returns when task completes abnormally
658     */
659     public void testAbnormalForkQuietlyJoin() {
660 jsr166 1.12 testAbnormalForkQuietlyJoin(mainPool());
661     }
662     public void testAbnormalForkQuietlyJoin_Singleton() {
663     testAbnormalForkQuietlyJoin(singletonPool());
664     }
665     public void testAbnormalForkQuietlyJoin(ForkJoinPool pool) {
666 dl 1.1 RecursiveAction a = new CheckedRecursiveAction() {
667     protected void realCompute() {
668     FailingAsyncFib f = new FailingAsyncFib(8);
669     assertSame(f, f.fork());
670     f.quietlyJoin();
671     assertTrue(f.getException() instanceof FJException);
672     checkCompletedAbnormally(f, f.getException());
673     }};
674 jsr166 1.12 testInvokeOnPool(pool, a);
675 dl 1.1 }
676    
677     /**
678     * getPool of executing task returns its pool
679     */
680     public void testGetPool() {
681 jsr166 1.12 testGetPool(mainPool());
682     }
683     public void testGetPool_Singleton() {
684     testGetPool(singletonPool());
685     }
686     public void testGetPool(ForkJoinPool pool) {
687 dl 1.1 RecursiveAction a = new CheckedRecursiveAction() {
688     protected void realCompute() {
689 jsr166 1.12 assertSame(pool, getPool());
690 dl 1.1 }};
691 jsr166 1.12 testInvokeOnPool(pool, a);
692 dl 1.1 }
693    
694     /**
695     * getPool of non-FJ task returns null
696     */
697     public void testGetPool2() {
698     RecursiveAction a = new CheckedRecursiveAction() {
699     protected void realCompute() {
700     assertNull(getPool());
701     }};
702     assertNull(a.invoke());
703     }
704    
705     /**
706     * inForkJoinPool of executing task returns true
707     */
708     public void testInForkJoinPool() {
709 jsr166 1.12 testInForkJoinPool(mainPool());
710     }
711     public void testInForkJoinPool_Singleton() {
712     testInForkJoinPool(singletonPool());
713     }
714     public void testInForkJoinPool(ForkJoinPool pool) {
715 dl 1.1 RecursiveAction a = new CheckedRecursiveAction() {
716     protected void realCompute() {
717     assertTrue(inForkJoinPool());
718     }};
719 jsr166 1.12 testInvokeOnPool(pool, a);
720 dl 1.1 }
721    
722     /**
723     * inForkJoinPool of non-FJ task returns false
724     */
725     public void testInForkJoinPool2() {
726     RecursiveAction a = new CheckedRecursiveAction() {
727     protected void realCompute() {
728     assertFalse(inForkJoinPool());
729     }};
730     assertNull(a.invoke());
731     }
732    
733     /**
734     * setRawResult(null) succeeds
735     */
736     public void testSetRawResult() {
737     RecursiveAction a = new CheckedRecursiveAction() {
738     protected void realCompute() {
739     setRawResult(null);
740     assertNull(getRawResult());
741     }};
742     assertNull(a.invoke());
743     }
744    
745     /**
746     * invoke task throws exception after invoking completeExceptionally
747     */
748     public void testCompleteExceptionally() {
749 jsr166 1.12 testCompleteExceptionally(mainPool());
750     }
751     public void testCompleteExceptionally_Singleton() {
752     testCompleteExceptionally(singletonPool());
753     }
754     public void testCompleteExceptionally(ForkJoinPool pool) {
755 dl 1.1 RecursiveAction a = new CheckedRecursiveAction() {
756     protected void realCompute() {
757     AsyncFib f = new AsyncFib(8);
758     f.completeExceptionally(new FJException());
759     try {
760     f.invoke();
761     shouldThrow();
762     } catch (FJException success) {
763     checkCompletedAbnormally(f, success);
764     }
765     }};
766 jsr166 1.12 testInvokeOnPool(pool, a);
767 dl 1.1 }
768    
769     /**
770 jsr166 1.12 * invokeAll(tasks) with 1 argument invokes task
771 dl 1.1 */
772 jsr166 1.12 public void testInvokeAll1() {
773     testInvokeAll1(mainPool());
774     }
775     public void testInvokeAll1_Singleton() {
776     testInvokeAll1(singletonPool());
777     }
778     public void testInvokeAll1(ForkJoinPool pool) {
779 dl 1.1 RecursiveAction a = new CheckedRecursiveAction() {
780     protected void realCompute() {
781     AsyncFib f = new AsyncFib(8);
782 jsr166 1.12 invokeAll(f);
783     f.checkCompletedNormally();
784 dl 1.1 }};
785 jsr166 1.12 testInvokeOnPool(pool, a);
786 dl 1.1 }
787    
788     /**
789 jsr166 1.12 * invokeAll(t1, t2) invokes all task arguments
790 dl 1.1 */
791 jsr166 1.12 public void testInvokeAll2() {
792     testInvokeAll2(mainPool());
793     }
794     public void testInvokeAll2_Singleton() {
795     testInvokeAll2(singletonPool());
796     }
797     public void testInvokeAll2(ForkJoinPool pool) {
798 dl 1.1 RecursiveAction a = new CheckedRecursiveAction() {
799     protected void realCompute() {
800 jsr166 1.12 AsyncFib[] tasks = {
801     new AsyncFib(8),
802     new AsyncFib(9),
803     };
804     invokeAll(tasks[0], tasks[1]);
805     for (AsyncFib task : tasks) assertTrue(task.isDone());
806     for (AsyncFib task : tasks) task.checkCompletedNormally();
807 dl 1.1 }};
808 jsr166 1.12 testInvokeOnPool(pool, a);
809 dl 1.1 }
810    
811     /**
812     * invokeAll(tasks) with > 2 argument invokes tasks
813     */
814     public void testInvokeAll3() {
815 jsr166 1.12 testInvokeAll3(mainPool());
816     }
817     public void testInvokeAll3_Singleton() {
818     testInvokeAll3(singletonPool());
819     }
820     public void testInvokeAll3(ForkJoinPool pool) {
821 dl 1.1 RecursiveAction a = new CheckedRecursiveAction() {
822     protected void realCompute() {
823 jsr166 1.12 AsyncFib[] tasks = {
824     new AsyncFib(8),
825     new AsyncFib(9),
826     new AsyncFib(7),
827     };
828     invokeAll(tasks[0], tasks[1], tasks[2]);
829     for (AsyncFib task : tasks) assertTrue(task.isDone());
830     for (AsyncFib task : tasks) task.checkCompletedNormally();
831 dl 1.1 }};
832 jsr166 1.12 testInvokeOnPool(pool, a);
833 dl 1.1 }
834    
835     /**
836     * invokeAll(collection) invokes all tasks in the collection
837     */
838     public void testInvokeAllCollection() {
839 jsr166 1.12 testInvokeAllCollection(mainPool());
840     }
841     public void testInvokeAllCollection_Singleton() {
842     testInvokeAllCollection(singletonPool());
843     }
844     public void testInvokeAllCollection(ForkJoinPool pool) {
845 dl 1.1 RecursiveAction a = new CheckedRecursiveAction() {
846     protected void realCompute() {
847 jsr166 1.12 AsyncFib[] tasks = {
848     new AsyncFib(8),
849     new AsyncFib(9),
850     new AsyncFib(7),
851     };
852     invokeAll(Arrays.asList(tasks));
853     for (AsyncFib task : tasks) assertTrue(task.isDone());
854     for (AsyncFib task : tasks) task.checkCompletedNormally();
855 dl 1.1 }};
856 jsr166 1.12 testInvokeOnPool(pool, a);
857 dl 1.1 }
858    
859     /**
860 jsr166 1.10 * invokeAll(tasks) with any null task throws NullPointerException
861 dl 1.1 */
862 jsr166 1.10 public void testInvokeAllNullTask() {
863 jsr166 1.12 testInvokeAllNullTask(mainPool());
864     }
865     public void testInvokeAllNullTask_Singleton() {
866     testInvokeAllNullTask(singletonPool());
867     }
868     public void testInvokeAllNullTask(ForkJoinPool pool) {
869 dl 1.1 RecursiveAction a = new CheckedRecursiveAction() {
870     protected void realCompute() {
871 jsr166 1.10 AsyncFib nul = null;
872 jsr166 1.9 Runnable[] throwingActions = {
873 jsr166 1.10 () -> invokeAll(nul),
874     () -> invokeAll(nul, nul),
875 jsr166 1.12 () -> invokeAll(new AsyncFib(8), new AsyncFib(9), nul),
876     () -> invokeAll(new AsyncFib(8), nul, new AsyncFib(9)),
877     () -> invokeAll(nul, new AsyncFib(8), new AsyncFib(9)),
878 jsr166 1.9 };
879     assertThrows(NullPointerException.class, throwingActions);
880 dl 1.1 }};
881 jsr166 1.12 testInvokeOnPool(pool, a);
882 dl 1.1 }
883    
884     /**
885 jsr166 1.13 * invokeAll(tasks) with 1 argument throws exception if task does
886 dl 1.1 */
887 jsr166 1.13 public void testAbnormalInvokeAll1() {
888     testAbnormalInvokeAll1(mainPool());
889 jsr166 1.12 }
890 jsr166 1.13 public void testAbnormalInvokeAll1_Singleton() {
891     testAbnormalInvokeAll1(singletonPool());
892 jsr166 1.12 }
893 jsr166 1.13 public void testAbnormalInvokeAll1(ForkJoinPool pool) {
894 dl 1.1 RecursiveAction a = new CheckedRecursiveAction() {
895     protected void realCompute() {
896     FailingAsyncFib g = new FailingAsyncFib(9);
897     try {
898 jsr166 1.13 invokeAll(g);
899 dl 1.1 shouldThrow();
900     } catch (FJException success) {
901     checkCompletedAbnormally(g, success);
902     }
903     }};
904 jsr166 1.12 testInvokeOnPool(pool, a);
905 dl 1.1 }
906    
907     /**
908 jsr166 1.13 * invokeAll(t1, t2) throw exception if any task does
909 dl 1.1 */
910 jsr166 1.13 public void testAbnormalInvokeAll2() {
911     testAbnormalInvokeAll2(mainPool());
912 jsr166 1.12 }
913 jsr166 1.13 public void testAbnormalInvokeAll2_Singleton() {
914     testAbnormalInvokeAll2(singletonPool());
915 jsr166 1.12 }
916 jsr166 1.13 public void testAbnormalInvokeAll2(ForkJoinPool pool) {
917 dl 1.1 RecursiveAction a = new CheckedRecursiveAction() {
918     protected void realCompute() {
919 jsr166 1.13 AsyncFib f = new AsyncFib(8);
920 dl 1.1 FailingAsyncFib g = new FailingAsyncFib(9);
921 jsr166 1.13 ForkJoinTask[] tasks = { f, g };
922 jsr166 1.26 shuffle(tasks);
923 dl 1.1 try {
924 jsr166 1.13 invokeAll(tasks[0], tasks[1]);
925 dl 1.1 shouldThrow();
926     } catch (FJException success) {
927     checkCompletedAbnormally(g, success);
928     }
929     }};
930 jsr166 1.12 testInvokeOnPool(pool, a);
931 dl 1.1 }
932    
933     /**
934     * invokeAll(tasks) with > 2 argument throws exception if any task does
935     */
936     public void testAbnormalInvokeAll3() {
937 jsr166 1.12 testAbnormalInvokeAll3(mainPool());
938     }
939     public void testAbnormalInvokeAll3_Singleton() {
940     testAbnormalInvokeAll3(singletonPool());
941     }
942     public void testAbnormalInvokeAll3(ForkJoinPool pool) {
943 dl 1.1 RecursiveAction a = new CheckedRecursiveAction() {
944     protected void realCompute() {
945     AsyncFib f = new AsyncFib(8);
946     FailingAsyncFib g = new FailingAsyncFib(9);
947     AsyncFib h = new AsyncFib(7);
948 jsr166 1.13 ForkJoinTask[] tasks = { f, g, h };
949 jsr166 1.26 shuffle(tasks);
950 dl 1.1 try {
951 jsr166 1.13 invokeAll(tasks[0], tasks[1], tasks[2]);
952 dl 1.1 shouldThrow();
953     } catch (FJException success) {
954     checkCompletedAbnormally(g, success);
955     }
956     }};
957 jsr166 1.12 testInvokeOnPool(pool, a);
958 dl 1.1 }
959    
960     /**
961 jsr166 1.4 * invokeAll(collection) throws exception if any task does
962 dl 1.1 */
963     public void testAbnormalInvokeAllCollection() {
964 jsr166 1.12 testAbnormalInvokeAllCollection(mainPool());
965     }
966     public void testAbnormalInvokeAllCollection_Singleton() {
967     testAbnormalInvokeAllCollection(singletonPool());
968     }
969     public void testAbnormalInvokeAllCollection(ForkJoinPool pool) {
970 dl 1.1 RecursiveAction a = new CheckedRecursiveAction() {
971     protected void realCompute() {
972     FailingAsyncFib f = new FailingAsyncFib(8);
973     AsyncFib g = new AsyncFib(9);
974     AsyncFib h = new AsyncFib(7);
975 jsr166 1.12 ForkJoinTask[] tasks = { f, g, h };
976 jsr166 1.26 shuffle(tasks);
977 dl 1.1 try {
978 jsr166 1.12 invokeAll(Arrays.asList(tasks));
979 dl 1.1 shouldThrow();
980     } catch (FJException success) {
981     checkCompletedAbnormally(f, success);
982     }
983     }};
984 jsr166 1.12 testInvokeOnPool(pool, a);
985 dl 1.1 }
986    
987     /**
988     * tryUnfork returns true for most recent unexecuted task,
989     * and suppresses execution
990     */
991     public void testTryUnfork() {
992     RecursiveAction a = new CheckedRecursiveAction() {
993     protected void realCompute() {
994     AsyncFib g = new AsyncFib(9);
995     assertSame(g, g.fork());
996     AsyncFib f = new AsyncFib(8);
997     assertSame(f, f.fork());
998     assertTrue(f.tryUnfork());
999     helpQuiesce();
1000     checkNotDone(f);
1001 jsr166 1.12 g.checkCompletedNormally();
1002 dl 1.1 }};
1003     testInvokeOnPool(singletonPool(), a);
1004     }
1005    
1006     /**
1007     * getSurplusQueuedTaskCount returns > 0 when
1008     * there are more tasks than threads
1009     */
1010     public void testGetSurplusQueuedTaskCount() {
1011     RecursiveAction a = new CheckedRecursiveAction() {
1012     protected void realCompute() {
1013     AsyncFib h = new AsyncFib(7);
1014     assertSame(h, h.fork());
1015     AsyncFib g = new AsyncFib(9);
1016     assertSame(g, g.fork());
1017     AsyncFib f = new AsyncFib(8);
1018     assertSame(f, f.fork());
1019     assertTrue(getSurplusQueuedTaskCount() > 0);
1020     helpQuiesce();
1021     assertEquals(0, getSurplusQueuedTaskCount());
1022 jsr166 1.12 f.checkCompletedNormally();
1023     g.checkCompletedNormally();
1024     h.checkCompletedNormally();
1025 dl 1.1 }};
1026     testInvokeOnPool(singletonPool(), a);
1027     }
1028    
1029     /**
1030     * peekNextLocalTask returns most recent unexecuted task.
1031     */
1032     public void testPeekNextLocalTask() {
1033     RecursiveAction a = new CheckedRecursiveAction() {
1034     protected void realCompute() {
1035     AsyncFib g = new AsyncFib(9);
1036     assertSame(g, g.fork());
1037     AsyncFib f = new AsyncFib(8);
1038     assertSame(f, f.fork());
1039     assertSame(f, peekNextLocalTask());
1040     assertNull(f.join());
1041 jsr166 1.12 f.checkCompletedNormally();
1042 dl 1.1 helpQuiesce();
1043 jsr166 1.12 g.checkCompletedNormally();
1044 dl 1.1 }};
1045     testInvokeOnPool(singletonPool(), a);
1046     }
1047    
1048     /**
1049     * pollNextLocalTask returns most recent unexecuted task without
1050     * executing it
1051     */
1052     public void testPollNextLocalTask() {
1053     RecursiveAction a = new CheckedRecursiveAction() {
1054     protected void realCompute() {
1055     AsyncFib g = new AsyncFib(9);
1056     assertSame(g, g.fork());
1057     AsyncFib f = new AsyncFib(8);
1058     assertSame(f, f.fork());
1059     assertSame(f, pollNextLocalTask());
1060     helpQuiesce();
1061     checkNotDone(f);
1062 jsr166 1.12 g.checkCompletedNormally();
1063 dl 1.1 }};
1064     testInvokeOnPool(singletonPool(), a);
1065     }
1066    
1067     /**
1068     * pollTask returns an unexecuted task without executing it
1069     */
1070     public void testPollTask() {
1071     RecursiveAction a = new CheckedRecursiveAction() {
1072     protected void realCompute() {
1073     AsyncFib g = new AsyncFib(9);
1074     assertSame(g, g.fork());
1075     AsyncFib f = new AsyncFib(8);
1076     assertSame(f, f.fork());
1077     assertSame(f, pollTask());
1078     helpQuiesce();
1079     checkNotDone(f);
1080 jsr166 1.12 g.checkCompletedNormally();
1081 dl 1.1 }};
1082     testInvokeOnPool(singletonPool(), a);
1083     }
1084    
1085     /**
1086     * peekNextLocalTask returns least recent unexecuted task in async mode
1087     */
1088     public void testPeekNextLocalTaskAsync() {
1089     RecursiveAction a = new CheckedRecursiveAction() {
1090     protected void realCompute() {
1091     AsyncFib g = new AsyncFib(9);
1092     assertSame(g, g.fork());
1093     AsyncFib f = new AsyncFib(8);
1094     assertSame(f, f.fork());
1095     assertSame(g, peekNextLocalTask());
1096     assertNull(f.join());
1097     helpQuiesce();
1098 jsr166 1.12 f.checkCompletedNormally();
1099     g.checkCompletedNormally();
1100 dl 1.1 }};
1101     testInvokeOnPool(asyncSingletonPool(), a);
1102     }
1103    
1104     /**
1105     * pollNextLocalTask returns least recent unexecuted task without
1106     * executing it, in async mode
1107     */
1108     public void testPollNextLocalTaskAsync() {
1109     RecursiveAction a = new CheckedRecursiveAction() {
1110     protected void realCompute() {
1111     AsyncFib g = new AsyncFib(9);
1112     assertSame(g, g.fork());
1113     AsyncFib f = new AsyncFib(8);
1114     assertSame(f, f.fork());
1115     assertSame(g, pollNextLocalTask());
1116     helpQuiesce();
1117 jsr166 1.12 f.checkCompletedNormally();
1118 dl 1.1 checkNotDone(g);
1119     }};
1120     testInvokeOnPool(asyncSingletonPool(), a);
1121     }
1122    
1123     /**
1124     * pollTask returns an unexecuted task without executing it, in
1125     * async mode
1126     */
1127     public void testPollTaskAsync() {
1128     RecursiveAction a = new CheckedRecursiveAction() {
1129     protected void realCompute() {
1130     AsyncFib g = new AsyncFib(9);
1131     assertSame(g, g.fork());
1132     AsyncFib f = new AsyncFib(8);
1133     assertSame(f, f.fork());
1134     assertSame(g, pollTask());
1135     helpQuiesce();
1136 jsr166 1.12 f.checkCompletedNormally();
1137 dl 1.1 checkNotDone(g);
1138     }};
1139     testInvokeOnPool(asyncSingletonPool(), a);
1140     }
1141    
1142     /**
1143     * ForkJoinTask.quietlyComplete returns when task completes
1144     * normally without setting a value. The most recent value
1145     * established by setRawResult(V) (or null by default) is returned
1146     * from invoke.
1147     */
1148     public void testQuietlyComplete() {
1149     RecursiveAction a = new CheckedRecursiveAction() {
1150     protected void realCompute() {
1151     AsyncFib f = new AsyncFib(8);
1152     f.quietlyComplete();
1153     assertEquals(8, f.number);
1154     assertTrue(f.isDone());
1155     assertFalse(f.isCancelled());
1156     assertTrue(f.isCompletedNormally());
1157     assertFalse(f.isCompletedAbnormally());
1158     assertNull(f.getException());
1159     }};
1160     testInvokeOnPool(mainPool(), a);
1161     }
1162    
1163 dl 1.15 // jdk9
1164 jsr166 1.16
1165 dl 1.15 /**
1166     * pollSubmission returns unexecuted submitted task, if present
1167     */
1168     public void testPollSubmission() {
1169     final CountDownLatch done = new CountDownLatch(1);
1170     final ForkJoinTask a = ForkJoinTask.adapt(awaiter(done));
1171     final ForkJoinTask b = ForkJoinTask.adapt(awaiter(done));
1172     final ForkJoinTask c = ForkJoinTask.adapt(awaiter(done));
1173     final ForkJoinPool p = singletonPool();
1174 jsr166 1.21 try (PoolCleaner cleaner = cleaner(p, done)) {
1175 jsr166 1.18 Thread external = new Thread(new CheckedRunnable() {
1176     public void realRun() {
1177     p.execute(a);
1178     p.execute(b);
1179     p.execute(c);
1180     }});
1181     RecursiveAction s = new CheckedRecursiveAction() {
1182     protected void realCompute() {
1183     external.start();
1184     try {
1185     external.join();
1186     } catch (Exception ex) {
1187     threadUnexpectedException(ex);
1188     }
1189     assertTrue(p.hasQueuedSubmissions());
1190     assertTrue(Thread.currentThread() instanceof ForkJoinWorkerThread);
1191     ForkJoinTask r = ForkJoinTask.pollSubmission();
1192     assertTrue(r == a || r == b || r == c);
1193     assertFalse(r.isDone());
1194     }};
1195 dl 1.15 p.invoke(s);
1196     }
1197     }
1198    
1199 dl 1.1 }