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

Comparing jsr166/src/test/tck/RecursiveActionTest.java (file contents):
Revision 1.7 by jsr166, Wed Aug 5 01:17:30 2009 UTC vs.
Revision 1.43 by jsr166, Sun Feb 22 19:16:38 2015 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   */
6 import junit.framework.*;
7 import java.util.concurrent.*;
8 import java.util.*;
6  
7 + import static java.util.concurrent.TimeUnit.SECONDS;
8 +
9 + import java.util.Arrays;
10 + import java.util.HashSet;
11 + import java.util.concurrent.CancellationException;
12 + import java.util.concurrent.ExecutionException;
13 + import java.util.concurrent.ForkJoinPool;
14 + import java.util.concurrent.ForkJoinTask;
15 + import java.util.concurrent.ForkJoinWorkerThread;
16 + import java.util.concurrent.RecursiveAction;
17 + import java.util.concurrent.SynchronousQueue;
18 + import java.util.concurrent.ThreadLocalRandom;
19 + import java.util.concurrent.TimeoutException;
20 +
21 + import junit.framework.Test;
22 + import junit.framework.TestSuite;
23  
24   public class RecursiveActionTest extends JSR166TestCase {
25  
26      public static void main(String[] args) {
27 <        junit.textui.TestRunner.run (suite());
27 >        junit.textui.TestRunner.run(suite());
28      }
29 +
30      public static Test suite() {
31 <        return new TestSuite(RecursiveActionTest.class);
31 >        return new TestSuite(RecursiveActionTest.class);
32      }
33  
34 <    static final ForkJoinPool mainPool = new ForkJoinPool();
35 <    static final ForkJoinPool singletonPool = new ForkJoinPool(1);
36 <    static final ForkJoinPool asyncSingletonPool = new ForkJoinPool(1);
37 <    static {
38 <        asyncSingletonPool.setAsyncMode(true);
34 >    private static ForkJoinPool mainPool() {
35 >        return new ForkJoinPool();
36 >    }
37 >
38 >    private static ForkJoinPool singletonPool() {
39 >        return new ForkJoinPool(1);
40 >    }
41 >
42 >    private static ForkJoinPool asyncSingletonPool() {
43 >        return new ForkJoinPool(1,
44 >                                ForkJoinPool.defaultForkJoinWorkerThreadFactory,
45 >                                null, true);
46 >    }
47 >
48 >    private void testInvokeOnPool(ForkJoinPool pool, RecursiveAction a) {
49 >        try {
50 >            checkNotDone(a);
51 >
52 >            assertNull(pool.invoke(a));
53 >
54 >            checkCompletedNormally(a);
55 >        } finally {
56 >            joinPool(pool);
57 >        }
58      }
59  
60 <    static final class FJException extends RuntimeException {
61 <        FJException() { super(); }
60 >    void checkNotDone(RecursiveAction a) {
61 >        assertFalse(a.isDone());
62 >        assertFalse(a.isCompletedNormally());
63 >        assertFalse(a.isCompletedAbnormally());
64 >        assertFalse(a.isCancelled());
65 >        assertNull(a.getException());
66 >        assertNull(a.getRawResult());
67 >
68 >        if (! ForkJoinTask.inForkJoinPool()) {
69 >            Thread.currentThread().interrupt();
70 >            try {
71 >                a.get();
72 >                shouldThrow();
73 >            } catch (InterruptedException success) {
74 >            } catch (Throwable fail) { threadUnexpectedException(fail); }
75 >
76 >            Thread.currentThread().interrupt();
77 >            try {
78 >                a.get(5L, SECONDS);
79 >                shouldThrow();
80 >            } catch (InterruptedException success) {
81 >            } catch (Throwable fail) { threadUnexpectedException(fail); }
82 >        }
83 >
84 >        try {
85 >            a.get(0L, SECONDS);
86 >            shouldThrow();
87 >        } catch (TimeoutException success) {
88 >        } catch (Throwable fail) { threadUnexpectedException(fail); }
89 >    }
90 >
91 >    void checkCompletedNormally(RecursiveAction a) {
92 >        assertTrue(a.isDone());
93 >        assertFalse(a.isCancelled());
94 >        assertTrue(a.isCompletedNormally());
95 >        assertFalse(a.isCompletedAbnormally());
96 >        assertNull(a.getException());
97 >        assertNull(a.getRawResult());
98 >        assertNull(a.join());
99 >        assertFalse(a.cancel(false));
100 >        assertFalse(a.cancel(true));
101 >        try {
102 >            assertNull(a.get());
103 >        } catch (Throwable fail) { threadUnexpectedException(fail); }
104 >        try {
105 >            assertNull(a.get(5L, SECONDS));
106 >        } catch (Throwable fail) { threadUnexpectedException(fail); }
107 >    }
108 >
109 >    void checkCancelled(RecursiveAction a) {
110 >        assertTrue(a.isDone());
111 >        assertTrue(a.isCancelled());
112 >        assertFalse(a.isCompletedNormally());
113 >        assertTrue(a.isCompletedAbnormally());
114 >        assertTrue(a.getException() instanceof CancellationException);
115 >        assertNull(a.getRawResult());
116 >
117 >        try {
118 >            a.join();
119 >            shouldThrow();
120 >        } catch (CancellationException success) {
121 >        } catch (Throwable fail) { threadUnexpectedException(fail); }
122 >
123 >        try {
124 >            a.get();
125 >            shouldThrow();
126 >        } catch (CancellationException success) {
127 >        } catch (Throwable fail) { threadUnexpectedException(fail); }
128 >
129 >        try {
130 >            a.get(5L, SECONDS);
131 >            shouldThrow();
132 >        } catch (CancellationException success) {
133 >        } catch (Throwable fail) { threadUnexpectedException(fail); }
134 >    }
135 >
136 >    void checkCompletedAbnormally(RecursiveAction a, Throwable t) {
137 >        assertTrue(a.isDone());
138 >        assertFalse(a.isCancelled());
139 >        assertFalse(a.isCompletedNormally());
140 >        assertTrue(a.isCompletedAbnormally());
141 >        assertSame(t.getClass(), a.getException().getClass());
142 >        assertNull(a.getRawResult());
143 >        assertFalse(a.cancel(false));
144 >        assertFalse(a.cancel(true));
145 >
146 >        try {
147 >            a.join();
148 >            shouldThrow();
149 >        } catch (Throwable expected) {
150 >            assertSame(expected.getClass(), t.getClass());
151 >        }
152 >
153 >        try {
154 >            a.get();
155 >            shouldThrow();
156 >        } catch (ExecutionException success) {
157 >            assertSame(t.getClass(), success.getCause().getClass());
158 >        } catch (Throwable fail) { threadUnexpectedException(fail); }
159 >
160 >        try {
161 >            a.get(5L, SECONDS);
162 >            shouldThrow();
163 >        } catch (ExecutionException success) {
164 >            assertSame(t.getClass(), success.getCause().getClass());
165 >        } catch (Throwable fail) { threadUnexpectedException(fail); }
166 >    }
167 >
168 >    public static final class FJException extends RuntimeException {
169 >        public FJException() { super(); }
170 >        public FJException(Throwable cause) { super(cause); }
171      }
172  
173      // A simple recursive action for testing
174 <    static final class FibAction extends RecursiveAction {
174 >    final class FibAction extends CheckedRecursiveAction {
175          final int number;
176          int result;
177          FibAction(int n) { number = n; }
178 <        public void compute() {
178 >        protected void realCompute() {
179              int n = number;
180              if (n <= 1)
181                  result = n;
# Line 68 | Line 210 | public class RecursiveActionTest extends
210       * invoke returns when task completes normally.
211       * isCompletedAbnormally and isCancelled return false for normally
212       * completed tasks. getRawResult of a RecursiveAction returns null;
71     *
213       */
214      public void testInvoke() {
215 <        RecursiveAction a = new RecursiveAction() {
216 <            public void compute() {
215 >        RecursiveAction a = new CheckedRecursiveAction() {
216 >            protected void realCompute() {
217                  FibAction f = new FibAction(8);
218 <                f.invoke();
219 <                threadAssertTrue(f.result == 21);
220 <                threadAssertTrue(f.isDone());
80 <                threadAssertFalse(f.isCancelled());
81 <                threadAssertFalse(f.isCompletedAbnormally());
82 <                threadAssertTrue(f.getRawResult() == null);
218 >                assertNull(f.invoke());
219 >                assertEquals(21, f.result);
220 >                checkCompletedNormally(f);
221              }};
222 <        mainPool.invoke(a);
222 >        testInvokeOnPool(mainPool(), a);
223      }
224  
225      /**
# Line 90 | Line 228 | public class RecursiveActionTest extends
228       * completed tasks
229       */
230      public void testQuietlyInvoke() {
231 <        RecursiveAction a = new RecursiveAction() {
232 <            public void compute() {
231 >        RecursiveAction a = new CheckedRecursiveAction() {
232 >            protected void realCompute() {
233                  FibAction f = new FibAction(8);
234                  f.quietlyInvoke();
235 <                threadAssertTrue(f.result == 21);
236 <                threadAssertTrue(f.isDone());
99 <                threadAssertFalse(f.isCancelled());
100 <                threadAssertFalse(f.isCompletedAbnormally());
101 <                threadAssertTrue(f.getRawResult() == null);
235 >                assertEquals(21, f.result);
236 >                checkCompletedNormally(f);
237              }};
238 <        mainPool.invoke(a);
238 >        testInvokeOnPool(mainPool(), a);
239      }
240  
241      /**
242       * join of a forked task returns when task completes
243       */
244      public void testForkJoin() {
245 <        RecursiveAction a = new RecursiveAction() {
246 <            public void compute() {
245 >        RecursiveAction a = new CheckedRecursiveAction() {
246 >            protected void realCompute() {
247                  FibAction f = new FibAction(8);
248 <                f.fork();
249 <                f.join();
250 <                threadAssertTrue(f.result == 21);
251 <                threadAssertTrue(f.isDone());
117 <                threadAssertTrue(f.getRawResult() == null);
248 >                assertSame(f, f.fork());
249 >                assertNull(f.join());
250 >                assertEquals(21, f.result);
251 >                checkCompletedNormally(f);
252              }};
253 <        mainPool.invoke(a);
253 >        testInvokeOnPool(mainPool(), a);
254      }
255  
256      /**
257 <     * get of a forked task returns when task completes
257 >     * join/quietlyJoin of a forked task succeeds in the presence of interrupts
258       */
259 <    public void testForkGet() {
260 <        RecursiveAction a = new RecursiveAction() {
261 <            public void compute() {
259 >    public void testJoinIgnoresInterrupts() {
260 >        RecursiveAction a = new CheckedRecursiveAction() {
261 >            protected void realCompute() {
262 >                FibAction f = new FibAction(8);
263 >                final Thread myself = Thread.currentThread();
264 >
265 >                // test join()
266 >                assertSame(f, f.fork());
267 >                myself.interrupt();
268 >                assertTrue(myself.isInterrupted());
269 >                assertNull(f.join());
270 >                Thread.interrupted();
271 >                assertEquals(21, f.result);
272 >                checkCompletedNormally(f);
273 >
274 >                f = new FibAction(8);
275 >                f.cancel(true);
276 >                assertSame(f, f.fork());
277 >                myself.interrupt();
278 >                assertTrue(myself.isInterrupted());
279                  try {
280 <                    FibAction f = new FibAction(8);
281 <                    f.fork();
282 <                    f.get();
283 <                    threadAssertTrue(f.result == 21);
284 <                    threadAssertTrue(f.isDone());
285 <                } catch (Exception ex) {
286 <                    unexpectedException(ex);
280 >                    f.join();
281 >                    shouldThrow();
282 >                } catch (CancellationException success) {
283 >                    Thread.interrupted();
284 >                    checkCancelled(f);
285 >                }
286 >
287 >                f = new FibAction(8);
288 >                f.completeExceptionally(new FJException());
289 >                assertSame(f, f.fork());
290 >                myself.interrupt();
291 >                assertTrue(myself.isInterrupted());
292 >                try {
293 >                    f.join();
294 >                    shouldThrow();
295 >                } catch (FJException success) {
296 >                    Thread.interrupted();
297 >                    checkCompletedAbnormally(f, success);
298                  }
299 +
300 +                // test quietlyJoin()
301 +                f = new FibAction(8);
302 +                assertSame(f, f.fork());
303 +                myself.interrupt();
304 +                assertTrue(myself.isInterrupted());
305 +                f.quietlyJoin();
306 +                Thread.interrupted();
307 +                assertEquals(21, f.result);
308 +                checkCompletedNormally(f);
309 +
310 +                f = new FibAction(8);
311 +                f.cancel(true);
312 +                assertSame(f, f.fork());
313 +                myself.interrupt();
314 +                assertTrue(myself.isInterrupted());
315 +                f.quietlyJoin();
316 +                Thread.interrupted();
317 +                checkCancelled(f);
318 +
319 +                f = new FibAction(8);
320 +                f.completeExceptionally(new FJException());
321 +                assertSame(f, f.fork());
322 +                myself.interrupt();
323 +                assertTrue(myself.isInterrupted());
324 +                f.quietlyJoin();
325 +                Thread.interrupted();
326 +                checkCompletedAbnormally(f, f.getException());
327              }};
328 <        mainPool.invoke(a);
328 >        testInvokeOnPool(mainPool(), a);
329 >        a.reinitialize();
330 >        testInvokeOnPool(singletonPool(), a);
331      }
332  
333      /**
334 <     * timed get of a forked task returns when task completes
334 >     * join/quietlyJoin of a forked task when not in ForkJoinPool
335 >     * succeeds in the presence of interrupts
336       */
337 <    public void testForkTimedGet() {
338 <        RecursiveAction a = new RecursiveAction() {
339 <            public void compute() {
337 >    public void testJoinIgnoresInterruptsOutsideForkJoinPool() {
338 >        final SynchronousQueue<FibAction[]> sq =
339 >            new SynchronousQueue<FibAction[]>();
340 >        RecursiveAction a = new CheckedRecursiveAction() {
341 >            protected void realCompute() throws InterruptedException {
342 >                FibAction[] fibActions = new FibAction[6];
343 >                for (int i = 0; i < fibActions.length; i++)
344 >                    fibActions[i] = new FibAction(8);
345 >
346 >                fibActions[1].cancel(false);
347 >                fibActions[2].completeExceptionally(new FJException());
348 >                fibActions[4].cancel(true);
349 >                fibActions[5].completeExceptionally(new FJException());
350 >
351 >                for (int i = 0; i < fibActions.length; i++)
352 >                    fibActions[i].fork();
353 >
354 >                sq.put(fibActions);
355 >
356 >                helpQuiesce();
357 >            }};
358 >
359 >        Runnable r = new CheckedRunnable() {
360 >            public void realRun() throws InterruptedException {
361 >                FibAction[] fibActions = sq.take();
362 >                FibAction f;
363 >                final Thread myself = Thread.currentThread();
364 >
365 >                // test join() ------------
366 >
367 >                f = fibActions[0];
368 >                assertFalse(ForkJoinTask.inForkJoinPool());
369 >                myself.interrupt();
370 >                assertTrue(myself.isInterrupted());
371 >                assertNull(f.join());
372 >                assertTrue(Thread.interrupted());
373 >                assertEquals(21, f.result);
374 >                checkCompletedNormally(f);
375 >
376 >                f = fibActions[1];
377 >                myself.interrupt();
378 >                assertTrue(myself.isInterrupted());
379 >                try {
380 >                    f.join();
381 >                    shouldThrow();
382 >                } catch (CancellationException success) {
383 >                    assertTrue(Thread.interrupted());
384 >                    checkCancelled(f);
385 >                }
386 >
387 >                f = fibActions[2];
388 >                myself.interrupt();
389 >                assertTrue(myself.isInterrupted());
390                  try {
391 <                    FibAction f = new FibAction(8);
392 <                    f.fork();
393 <                    f.get(5L, TimeUnit.SECONDS);
394 <                    threadAssertTrue(f.result == 21);
395 <                    threadAssertTrue(f.isDone());
153 <                } catch (Exception ex) {
154 <                    unexpectedException(ex);
391 >                    f.join();
392 >                    shouldThrow();
393 >                } catch (FJException success) {
394 >                    assertTrue(Thread.interrupted());
395 >                    checkCompletedAbnormally(f, success);
396                  }
397 +
398 +                // test quietlyJoin() ---------
399 +
400 +                f = fibActions[3];
401 +                myself.interrupt();
402 +                assertTrue(myself.isInterrupted());
403 +                f.quietlyJoin();
404 +                assertTrue(Thread.interrupted());
405 +                assertEquals(21, f.result);
406 +                checkCompletedNormally(f);
407 +
408 +                f = fibActions[4];
409 +                myself.interrupt();
410 +                assertTrue(myself.isInterrupted());
411 +                f.quietlyJoin();
412 +                assertTrue(Thread.interrupted());
413 +                checkCancelled(f);
414 +
415 +                f = fibActions[5];
416 +                myself.interrupt();
417 +                assertTrue(myself.isInterrupted());
418 +                f.quietlyJoin();
419 +                assertTrue(Thread.interrupted());
420 +                assertTrue(f.getException() instanceof FJException);
421 +                checkCompletedAbnormally(f, f.getException());
422              }};
423 <        mainPool.invoke(a);
423 >
424 >        Thread t;
425 >
426 >        t = newStartedThread(r);
427 >        testInvokeOnPool(mainPool(), a);
428 >        awaitTermination(t, LONG_DELAY_MS);
429 >
430 >        a.reinitialize();
431 >        t = newStartedThread(r);
432 >        testInvokeOnPool(singletonPool(), a);
433 >        awaitTermination(t, LONG_DELAY_MS);
434      }
435  
436      /**
437 <     * timed get with null time unit throws NPE
437 >     * get of a forked task returns when task completes
438       */
439 <    public void testForkTimedGetNPE() {
440 <        RecursiveAction a = new RecursiveAction() {
441 <                public void compute() {
442 <                    try {
443 <                        FibAction f = new FibAction(8);
444 <                        f.fork();
445 <                        f.get(5L, null);
446 <                        shouldThrow();
447 <                    } catch (NullPointerException success) {
448 <                    } catch (Exception ex) {
173 <                        unexpectedException(ex);
174 <                    }
175 <                }
176 <            };
177 <        mainPool.invoke(a);
439 >    public void testForkGet() {
440 >        RecursiveAction a = new CheckedRecursiveAction() {
441 >            protected void realCompute() throws Exception {
442 >                FibAction f = new FibAction(8);
443 >                assertSame(f, f.fork());
444 >                assertNull(f.get());
445 >                assertEquals(21, f.result);
446 >                checkCompletedNormally(f);
447 >            }};
448 >        testInvokeOnPool(mainPool(), a);
449      }
450  
451      /**
452 <     * helpJoin of a forked task returns when task completes
452 >     * timed get of a forked task returns when task completes
453       */
454 <    public void testForkHelpJoin() {
455 <        RecursiveAction a = new RecursiveAction() {
456 <            public void compute() {
454 >    public void testForkTimedGet() {
455 >        RecursiveAction a = new CheckedRecursiveAction() {
456 >            protected void realCompute() throws Exception {
457                  FibAction f = new FibAction(8);
458 <                f.fork();
459 <                f.helpJoin();
460 <                threadAssertTrue(f.result == 21);
461 <                threadAssertTrue(f.isDone());
458 >                assertSame(f, f.fork());
459 >                assertNull(f.get(5L, SECONDS));
460 >                assertEquals(21, f.result);
461 >                checkCompletedNormally(f);
462              }};
463 <        mainPool.invoke(a);
463 >        testInvokeOnPool(mainPool(), a);
464      }
465  
466      /**
467 <     * quietlyJoin of a forked task returns when task completes
467 >     * timed get with null time unit throws NPE
468       */
469 <    public void testForkQuietlyJoin() {
470 <        RecursiveAction a = new RecursiveAction() {
471 <            public void compute() {
469 >    public void testForkTimedGetNPE() {
470 >        RecursiveAction a = new CheckedRecursiveAction() {
471 >            protected void realCompute() throws Exception {
472                  FibAction f = new FibAction(8);
473 <                f.fork();
474 <                f.quietlyJoin();
475 <                threadAssertTrue(f.result == 21);
476 <                threadAssertTrue(f.isDone());
473 >                assertSame(f, f.fork());
474 >                try {
475 >                    f.get(5L, null);
476 >                    shouldThrow();
477 >                } catch (NullPointerException success) {}
478              }};
479 <        mainPool.invoke(a);
479 >        testInvokeOnPool(mainPool(), a);
480      }
481  
210
482      /**
483 <     * quietlyHelpJoin of a forked task returns when task completes
483 >     * quietlyJoin of a forked task returns when task completes
484       */
485 <    public void testForkQuietlyHelpJoin() {
486 <        RecursiveAction a = new RecursiveAction() {
487 <            public void compute() {
485 >    public void testForkQuietlyJoin() {
486 >        RecursiveAction a = new CheckedRecursiveAction() {
487 >            protected void realCompute() {
488                  FibAction f = new FibAction(8);
489 <                f.fork();
490 <                f.quietlyHelpJoin();
491 <                threadAssertTrue(f.result == 21);
492 <                threadAssertTrue(f.isDone());
489 >                assertSame(f, f.fork());
490 >                f.quietlyJoin();
491 >                assertEquals(21, f.result);
492 >                checkCompletedNormally(f);
493              }};
494 <        mainPool.invoke(a);
494 >        testInvokeOnPool(mainPool(), a);
495      }
496  
226
497      /**
498       * helpQuiesce returns when tasks are complete.
499       * getQueuedTaskCount returns 0 when quiescent
500       */
501      public void testForkHelpQuiesce() {
502 <        RecursiveAction a = new RecursiveAction() {
503 <            public void compute() {
502 >        RecursiveAction a = new CheckedRecursiveAction() {
503 >            protected void realCompute() {
504                  FibAction f = new FibAction(8);
505 <                f.fork();
506 <                f.helpQuiesce();
507 <                threadAssertTrue(f.result == 21);
508 <                threadAssertTrue(f.isDone());
509 <                threadAssertTrue(getQueuedTaskCount() == 0);
505 >                assertSame(f, f.fork());
506 >                helpQuiesce();
507 >                while (!f.isDone()) // wait out race
508 >                    ;
509 >                assertEquals(21, f.result);
510 >                assertEquals(0, getQueuedTaskCount());
511 >                checkCompletedNormally(f);
512              }};
513 <        mainPool.invoke(a);
513 >        testInvokeOnPool(mainPool(), a);
514      }
515  
244
516      /**
517       * invoke task throws exception when task completes abnormally
518       */
519      public void testAbnormalInvoke() {
520 <        RecursiveAction a = new RecursiveAction() {
521 <            public void compute() {
520 >        RecursiveAction a = new CheckedRecursiveAction() {
521 >            protected void realCompute() {
522 >                FailingFibAction f = new FailingFibAction(8);
523                  try {
252                    FailingFibAction f = new FailingFibAction(8);
524                      f.invoke();
525                      shouldThrow();
526                  } catch (FJException success) {
527 +                    checkCompletedAbnormally(f, success);
528                  }
529              }};
530 <        mainPool.invoke(a);
530 >        testInvokeOnPool(mainPool(), a);
531      }
532  
533      /**
534       * quietlyInvoke task returns when task completes abnormally
535       */
536      public void testAbnormalQuietlyInvoke() {
537 <        RecursiveAction a = new RecursiveAction() {
538 <            public void compute() {
537 >        RecursiveAction a = new CheckedRecursiveAction() {
538 >            protected void realCompute() {
539                  FailingFibAction f = new FailingFibAction(8);
540                  f.quietlyInvoke();
541 <                threadAssertTrue(f.isDone());
541 >                assertTrue(f.getException() instanceof FJException);
542 >                checkCompletedAbnormally(f, f.getException());
543              }};
544 <        mainPool.invoke(a);
544 >        testInvokeOnPool(mainPool(), a);
545      }
546  
547      /**
548       * join of a forked task throws exception when task completes abnormally
549       */
550      public void testAbnormalForkJoin() {
551 <        RecursiveAction a = new RecursiveAction() {
552 <            public void compute() {
551 >        RecursiveAction a = new CheckedRecursiveAction() {
552 >            protected void realCompute() {
553 >                FailingFibAction f = new FailingFibAction(8);
554 >                assertSame(f, f.fork());
555                  try {
281                    FailingFibAction f = new FailingFibAction(8);
282                    f.fork();
556                      f.join();
557                      shouldThrow();
558                  } catch (FJException success) {
559 +                    checkCompletedAbnormally(f, success);
560                  }
561              }};
562 <        mainPool.invoke(a);
562 >        testInvokeOnPool(mainPool(), a);
563      }
564  
565      /**
566       * get of a forked task throws exception when task completes abnormally
567       */
568      public void testAbnormalForkGet() {
569 <        RecursiveAction a = new RecursiveAction() {
570 <            public void compute() {
569 >        RecursiveAction a = new CheckedRecursiveAction() {
570 >            protected void realCompute() throws Exception {
571 >                FailingFibAction f = new FailingFibAction(8);
572 >                assertSame(f, f.fork());
573                  try {
298                    FailingFibAction f = new FailingFibAction(8);
299                    f.fork();
574                      f.get();
575                      shouldThrow();
576                  } catch (ExecutionException success) {
577 <                } catch (Exception ex) {
578 <                    unexpectedException(ex);
577 >                    Throwable cause = success.getCause();
578 >                    assertTrue(cause instanceof FJException);
579 >                    checkCompletedAbnormally(f, cause);
580                  }
581              }};
582 <        mainPool.invoke(a);
582 >        testInvokeOnPool(mainPool(), a);
583      }
584  
585      /**
586       * timed get of a forked task throws exception when task completes abnormally
587       */
588      public void testAbnormalForkTimedGet() {
589 <        RecursiveAction a = new RecursiveAction() {
590 <            public void compute() {
589 >        RecursiveAction a = new CheckedRecursiveAction() {
590 >            protected void realCompute() throws Exception {
591 >                FailingFibAction f = new FailingFibAction(8);
592 >                assertSame(f, f.fork());
593                  try {
594 <                    FailingFibAction f = new FailingFibAction(8);
318 <                    f.fork();
319 <                    f.get(5L, TimeUnit.SECONDS);
594 >                    f.get(5L, SECONDS);
595                      shouldThrow();
596                  } catch (ExecutionException success) {
597 <                } catch (Exception ex) {
598 <                    unexpectedException(ex);
599 <                }
325 <            }};
326 <        mainPool.invoke(a);
327 <    }
328 <
329 <    /**
330 <     * join of a forked task throws exception when task completes abnormally
331 <     */
332 <    public void testAbnormalForkHelpJoin() {
333 <        RecursiveAction a = new RecursiveAction() {
334 <            public void compute() {
335 <                try {
336 <                    FailingFibAction f = new FailingFibAction(8);
337 <                    f.fork();
338 <                    f.helpJoin();
339 <                    shouldThrow();
340 <                } catch (FJException success) {
597 >                    Throwable cause = success.getCause();
598 >                    assertTrue(cause instanceof FJException);
599 >                    checkCompletedAbnormally(f, cause);
600                  }
601              }};
602 <        mainPool.invoke(a);
344 <    }
345 <
346 <    /**
347 <     * quietlyHelpJoin of a forked task returns when task completes abnormally.
348 <     * getException of failed task returns its exception.
349 <     * isCompletedAbnormally of a failed task returns true.
350 <     * isCancelled of a failed uncancelled task returns false
351 <     */
352 <    public void testAbnormalForkQuietlyHelpJoin() {
353 <        RecursiveAction a = new RecursiveAction() {
354 <            public void compute() {
355 <                FailingFibAction f = new FailingFibAction(8);
356 <                f.fork();
357 <                f.quietlyHelpJoin();
358 <                threadAssertTrue(f.isDone());
359 <                threadAssertTrue(f.isCompletedAbnormally());
360 <                threadAssertFalse(f.isCancelled());
361 <                threadAssertTrue(f.getException() instanceof FJException);
362 <            }};
363 <        mainPool.invoke(a);
602 >        testInvokeOnPool(mainPool(), a);
603      }
604  
605      /**
606       * quietlyJoin of a forked task returns when task completes abnormally
607       */
608      public void testAbnormalForkQuietlyJoin() {
609 <        RecursiveAction a = new RecursiveAction() {
610 <            public void compute() {
609 >        RecursiveAction a = new CheckedRecursiveAction() {
610 >            protected void realCompute() {
611                  FailingFibAction f = new FailingFibAction(8);
612 <                f.fork();
612 >                assertSame(f, f.fork());
613                  f.quietlyJoin();
614 <                threadAssertTrue(f.isDone());
615 <                threadAssertTrue(f.isCompletedAbnormally());
377 <                threadAssertTrue(f.getException() instanceof FJException);
614 >                assertTrue(f.getException() instanceof FJException);
615 >                checkCompletedAbnormally(f, f.getException());
616              }};
617 <        mainPool.invoke(a);
617 >        testInvokeOnPool(mainPool(), a);
618      }
619  
620      /**
621       * invoke task throws exception when task cancelled
622       */
623      public void testCancelledInvoke() {
624 <        RecursiveAction a = new RecursiveAction() {
625 <            public void compute() {
624 >        RecursiveAction a = new CheckedRecursiveAction() {
625 >            protected void realCompute() {
626 >                FibAction f = new FibAction(8);
627 >                assertTrue(f.cancel(true));
628                  try {
389                    FibAction f = new FibAction(8);
390                    f.cancel(true);
629                      f.invoke();
630                      shouldThrow();
631                  } catch (CancellationException success) {
632 +                    checkCancelled(f);
633                  }
634              }};
635 <        mainPool.invoke(a);
635 >        testInvokeOnPool(mainPool(), a);
636      }
637  
638      /**
639       * join of a forked task throws exception when task cancelled
640       */
641      public void testCancelledForkJoin() {
642 <        RecursiveAction a = new RecursiveAction() {
643 <            public void compute() {
642 >        RecursiveAction a = new CheckedRecursiveAction() {
643 >            protected void realCompute() {
644 >                FibAction f = new FibAction(8);
645 >                assertTrue(f.cancel(true));
646 >                assertSame(f, f.fork());
647                  try {
406                    FibAction f = new FibAction(8);
407                    f.cancel(true);
408                    f.fork();
648                      f.join();
649                      shouldThrow();
650                  } catch (CancellationException success) {
651 +                    checkCancelled(f);
652                  }
653              }};
654 <        mainPool.invoke(a);
654 >        testInvokeOnPool(mainPool(), a);
655      }
656  
657      /**
658       * get of a forked task throws exception when task cancelled
659       */
660      public void testCancelledForkGet() {
661 <        RecursiveAction a = new RecursiveAction() {
662 <            public void compute() {
661 >        RecursiveAction a = new CheckedRecursiveAction() {
662 >            protected void realCompute() throws Exception {
663 >                FibAction f = new FibAction(8);
664 >                assertTrue(f.cancel(true));
665 >                assertSame(f, f.fork());
666                  try {
424                    FibAction f = new FibAction(8);
425                    f.cancel(true);
426                    f.fork();
667                      f.get();
668                      shouldThrow();
669                  } catch (CancellationException success) {
670 <                } catch (Exception ex) {
431 <                    unexpectedException(ex);
670 >                    checkCancelled(f);
671                  }
672              }};
673 <        mainPool.invoke(a);
673 >        testInvokeOnPool(mainPool(), a);
674      }
675  
676      /**
677       * timed get of a forked task throws exception when task cancelled
678       */
679      public void testCancelledForkTimedGet() {
680 <        RecursiveAction a = new RecursiveAction() {
681 <            public void compute() {
680 >        RecursiveAction a = new CheckedRecursiveAction() {
681 >            protected void realCompute() throws Exception {
682 >                FibAction f = new FibAction(8);
683 >                assertTrue(f.cancel(true));
684 >                assertSame(f, f.fork());
685                  try {
686 <                    FibAction f = new FibAction(8);
445 <                    f.cancel(true);
446 <                    f.fork();
447 <                    f.get(5L, TimeUnit.SECONDS);
448 <                    shouldThrow();
449 <                } catch (CancellationException success) {
450 <                } catch (Exception ex) {
451 <                    unexpectedException(ex);
452 <                }
453 <            }};
454 <        mainPool.invoke(a);
455 <    }
456 <
457 <    /**
458 <     * join of a forked task throws exception when task cancelled
459 <     */
460 <    public void testCancelledForkHelpJoin() {
461 <        RecursiveAction a = new RecursiveAction() {
462 <            public void compute() {
463 <                try {
464 <                    FibAction f = new FibAction(8);
465 <                    f.cancel(true);
466 <                    f.fork();
467 <                    f.helpJoin();
686 >                    f.get(5L, SECONDS);
687                      shouldThrow();
688                  } catch (CancellationException success) {
689 +                    checkCancelled(f);
690                  }
691              }};
692 <        mainPool.invoke(a);
473 <    }
474 <
475 <    /**
476 <     * quietlyHelpJoin of a forked task returns when task cancelled.
477 <     * getException of cancelled task returns its exception.
478 <     * isCompletedAbnormally of a cancelled task returns true.
479 <     * isCancelled of a cancelled task returns true
480 <     */
481 <    public void testCancelledForkQuietlyHelpJoin() {
482 <        RecursiveAction a = new RecursiveAction() {
483 <            public void compute() {
484 <                FibAction f = new FibAction(8);
485 <                f.cancel(true);
486 <                f.fork();
487 <                f.quietlyHelpJoin();
488 <                threadAssertTrue(f.isDone());
489 <                threadAssertTrue(f.isCompletedAbnormally());
490 <                threadAssertTrue(f.isCancelled());
491 <                threadAssertTrue(f.getException() instanceof CancellationException);
492 <            }};
493 <        mainPool.invoke(a);
692 >        testInvokeOnPool(mainPool(), a);
693      }
694  
695      /**
696       * quietlyJoin of a forked task returns when task cancelled
697       */
698      public void testCancelledForkQuietlyJoin() {
699 <        RecursiveAction a = new RecursiveAction() {
700 <            public void compute() {
699 >        RecursiveAction a = new CheckedRecursiveAction() {
700 >            protected void realCompute() {
701                  FibAction f = new FibAction(8);
702 <                f.cancel(true);
703 <                f.fork();
702 >                assertTrue(f.cancel(true));
703 >                assertSame(f, f.fork());
704                  f.quietlyJoin();
705 <                threadAssertTrue(f.isDone());
507 <                threadAssertTrue(f.isCompletedAbnormally());
508 <                threadAssertTrue(f.getException() instanceof CancellationException);
705 >                checkCancelled(f);
706              }};
707 <        mainPool.invoke(a);
707 >        testInvokeOnPool(mainPool(), a);
708      }
709  
710      /**
711       * getPool of executing task returns its pool
712       */
713      public void testGetPool() {
714 <        RecursiveAction a = new RecursiveAction() {
715 <            public void compute() {
716 <                threadAssertTrue(getPool() == mainPool);
714 >        final ForkJoinPool mainPool = mainPool();
715 >        RecursiveAction a = new CheckedRecursiveAction() {
716 >            protected void realCompute() {
717 >                assertSame(mainPool, getPool());
718              }};
719 <        mainPool.invoke(a);
719 >        testInvokeOnPool(mainPool, a);
720      }
721  
722      /**
723       * getPool of non-FJ task returns null
724       */
725      public void testGetPool2() {
726 <        RecursiveAction a = new RecursiveAction() {
727 <            public void compute() {
728 <                threadAssertTrue(getPool() == null);
726 >        RecursiveAction a = new CheckedRecursiveAction() {
727 >            protected void realCompute() {
728 >                assertNull(getPool());
729              }};
730 <        a.invoke();
730 >        assertNull(a.invoke());
731      }
732  
733      /**
734       * inForkJoinPool of executing task returns true
735       */
736      public void testInForkJoinPool() {
737 <        RecursiveAction a = new RecursiveAction() {
738 <            public void compute() {
739 <                threadAssertTrue(inForkJoinPool());
737 >        RecursiveAction a = new CheckedRecursiveAction() {
738 >            protected void realCompute() {
739 >                assertTrue(inForkJoinPool());
740              }};
741 <        mainPool.invoke(a);
741 >        testInvokeOnPool(mainPool(), a);
742      }
743  
744      /**
745       * inForkJoinPool of non-FJ task returns false
746       */
747      public void testInForkJoinPool2() {
748 <        RecursiveAction a = new RecursiveAction() {
749 <            public void compute() {
750 <                threadAssertTrue(!inForkJoinPool());
748 >        RecursiveAction a = new CheckedRecursiveAction() {
749 >            protected void realCompute() {
750 >                assertFalse(inForkJoinPool());
751              }};
752 <        a.invoke();
752 >        assertNull(a.invoke());
753      }
754  
755      /**
756       * getPool of current thread in pool returns its pool
757       */
758      public void testWorkerGetPool() {
759 <        RecursiveAction a = new RecursiveAction() {
760 <            public void compute() {
759 >        final ForkJoinPool mainPool = mainPool();
760 >        RecursiveAction a = new CheckedRecursiveAction() {
761 >            protected void realCompute() {
762                  ForkJoinWorkerThread w =
763 <                    (ForkJoinWorkerThread)(Thread.currentThread());
764 <                threadAssertTrue(w.getPool() == mainPool);
763 >                    (ForkJoinWorkerThread) Thread.currentThread();
764 >                assertSame(mainPool, w.getPool());
765              }};
766 <        mainPool.invoke(a);
766 >        testInvokeOnPool(mainPool, a);
767      }
768  
769      /**
770       * getPoolIndex of current thread in pool returns 0 <= value < poolSize
572     *
771       */
772      public void testWorkerGetPoolIndex() {
773 <        RecursiveAction a = new RecursiveAction() {
774 <            public void compute() {
773 >        final ForkJoinPool mainPool = mainPool();
774 >        RecursiveAction a = new CheckedRecursiveAction() {
775 >            protected void realCompute() {
776                  ForkJoinWorkerThread w =
777 <                    (ForkJoinWorkerThread)(Thread.currentThread());
778 <                int idx = w.getPoolIndex();
779 <                threadAssertTrue(idx >= 0);
780 <                threadAssertTrue(idx < mainPool.getPoolSize());
777 >                    (ForkJoinWorkerThread) Thread.currentThread();
778 >                assertTrue(w.getPoolIndex() >= 0);
779 >                // pool size can shrink after assigning index, so cannot check
780 >                // assertTrue(w.getPoolIndex() < mainPool.getPoolSize());
781              }};
782 <        mainPool.invoke(a);
782 >        testInvokeOnPool(mainPool, a);
783      }
784  
586
785      /**
786       * setRawResult(null) succeeds
787       */
788      public void testSetRawResult() {
789 <        RecursiveAction a = new RecursiveAction() {
790 <            public void compute() {
789 >        RecursiveAction a = new CheckedRecursiveAction() {
790 >            protected void realCompute() {
791                  setRawResult(null);
792 +                assertNull(getRawResult());
793              }};
794 <        a.invoke();
794 >        assertNull(a.invoke());
795      }
796  
797      /**
798 <     * A reinitialized task may be re-invoked
798 >     * A reinitialized normally completed task may be re-invoked
799       */
800      public void testReinitialize() {
801 <        RecursiveAction a = new RecursiveAction() {
802 <            public void compute() {
801 >        RecursiveAction a = new CheckedRecursiveAction() {
802 >            protected void realCompute() {
803                  FibAction f = new FibAction(8);
804 <                f.invoke();
805 <                threadAssertTrue(f.result == 21);
806 <                threadAssertTrue(f.isDone());
807 <                threadAssertFalse(f.isCancelled());
808 <                threadAssertFalse(f.isCompletedAbnormally());
809 <                f.reinitialize();
810 <                f.invoke();
811 <                threadAssertTrue(f.result == 21);
804 >                checkNotDone(f);
805 >
806 >                for (int i = 0; i < 3; i++) {
807 >                    assertNull(f.invoke());
808 >                    assertEquals(21, f.result);
809 >                    checkCompletedNormally(f);
810 >                    f.reinitialize();
811 >                    checkNotDone(f);
812 >                }
813 >            }};
814 >        testInvokeOnPool(mainPool(), a);
815 >    }
816 >
817 >    /**
818 >     * A reinitialized abnormally completed task may be re-invoked
819 >     */
820 >    public void testReinitializeAbnormal() {
821 >        RecursiveAction a = new CheckedRecursiveAction() {
822 >            protected void realCompute() {
823 >                FailingFibAction f = new FailingFibAction(8);
824 >                checkNotDone(f);
825 >
826 >                for (int i = 0; i < 3; i++) {
827 >                    try {
828 >                        f.invoke();
829 >                        shouldThrow();
830 >                    } catch (FJException success) {
831 >                        checkCompletedAbnormally(f, success);
832 >                    }
833 >                    f.reinitialize();
834 >                    checkNotDone(f);
835 >                }
836              }};
837 <        mainPool.invoke(a);
837 >        testInvokeOnPool(mainPool(), a);
838      }
839  
840      /**
841       * invoke task throws exception after invoking completeExceptionally
842       */
843      public void testCompleteExceptionally() {
844 <        RecursiveAction a = new RecursiveAction() {
845 <            public void compute() {
844 >        RecursiveAction a = new CheckedRecursiveAction() {
845 >            protected void realCompute() {
846 >                FibAction f = new FibAction(8);
847 >                f.completeExceptionally(new FJException());
848                  try {
624                    FibAction f = new FibAction(8);
625                    f.completeExceptionally(new FJException());
849                      f.invoke();
850                      shouldThrow();
851                  } catch (FJException success) {
852 +                    checkCompletedAbnormally(f, success);
853                  }
854              }};
855 <        mainPool.invoke(a);
855 >        testInvokeOnPool(mainPool(), a);
856      }
857  
858      /**
859       * invoke task suppresses execution invoking complete
860       */
861      public void testComplete() {
862 <        RecursiveAction a = new RecursiveAction() {
863 <            public void compute() {
862 >        RecursiveAction a = new CheckedRecursiveAction() {
863 >            protected void realCompute() {
864                  FibAction f = new FibAction(8);
865                  f.complete(null);
866 <                f.invoke();
867 <                threadAssertTrue(f.isDone());
868 <                threadAssertTrue(f.result == 0);
866 >                assertNull(f.invoke());
867 >                assertEquals(0, f.result);
868 >                checkCompletedNormally(f);
869              }};
870 <        mainPool.invoke(a);
870 >        testInvokeOnPool(mainPool(), a);
871      }
872  
873      /**
874       * invokeAll(t1, t2) invokes all task arguments
875       */
876      public void testInvokeAll2() {
877 <        RecursiveAction a = new RecursiveAction() {
878 <            public void compute() {
877 >        RecursiveAction a = new CheckedRecursiveAction() {
878 >            protected void realCompute() {
879                  FibAction f = new FibAction(8);
880                  FibAction g = new FibAction(9);
881                  invokeAll(f, g);
882 <                threadAssertTrue(f.isDone());
883 <                threadAssertTrue(f.result == 21);
884 <                threadAssertTrue(g.isDone());
885 <                threadAssertTrue(g.result == 34);
882 >                checkCompletedNormally(f);
883 >                assertEquals(21, f.result);
884 >                checkCompletedNormally(g);
885 >                assertEquals(34, g.result);
886              }};
887 <        mainPool.invoke(a);
887 >        testInvokeOnPool(mainPool(), a);
888      }
889  
890      /**
891       * invokeAll(tasks) with 1 argument invokes task
892       */
893      public void testInvokeAll1() {
894 <        RecursiveAction a = new RecursiveAction() {
895 <            public void compute() {
894 >        RecursiveAction a = new CheckedRecursiveAction() {
895 >            protected void realCompute() {
896                  FibAction f = new FibAction(8);
897                  invokeAll(f);
898 <                threadAssertTrue(f.isDone());
899 <                threadAssertTrue(f.result == 21);
898 >                checkCompletedNormally(f);
899 >                assertEquals(21, f.result);
900              }};
901 <        mainPool.invoke(a);
901 >        testInvokeOnPool(mainPool(), a);
902      }
903  
904      /**
905       * invokeAll(tasks) with > 2 argument invokes tasks
906       */
907      public void testInvokeAll3() {
908 <        RecursiveAction a = new RecursiveAction() {
909 <            public void compute() {
908 >        RecursiveAction a = new CheckedRecursiveAction() {
909 >            protected void realCompute() {
910                  FibAction f = new FibAction(8);
911                  FibAction g = new FibAction(9);
912                  FibAction h = new FibAction(7);
913                  invokeAll(f, g, h);
914 <                threadAssertTrue(f.isDone());
915 <                threadAssertTrue(f.result == 21);
916 <                threadAssertTrue(g.isDone());
917 <                threadAssertTrue(g.result == 34);
918 <                threadAssertTrue(h.isDone());
919 <                threadAssertTrue(h.result == 13);
914 >                assertTrue(f.isDone());
915 >                assertTrue(g.isDone());
916 >                assertTrue(h.isDone());
917 >                checkCompletedNormally(f);
918 >                assertEquals(21, f.result);
919 >                checkCompletedNormally(g);
920 >                assertEquals(34, g.result);
921 >                checkCompletedNormally(g);
922 >                assertEquals(13, h.result);
923              }};
924 <        mainPool.invoke(a);
924 >        testInvokeOnPool(mainPool(), a);
925      }
926  
927      /**
928       * invokeAll(collection) invokes all tasks in the collection
929       */
930      public void testInvokeAllCollection() {
931 <        RecursiveAction a = new RecursiveAction() {
932 <            public void compute() {
931 >        RecursiveAction a = new CheckedRecursiveAction() {
932 >            protected void realCompute() {
933                  FibAction f = new FibAction(8);
934                  FibAction g = new FibAction(9);
935                  FibAction h = new FibAction(7);
# Line 711 | Line 938 | public class RecursiveActionTest extends
938                  set.add(g);
939                  set.add(h);
940                  invokeAll(set);
941 <                threadAssertTrue(f.isDone());
942 <                threadAssertTrue(f.result == 21);
943 <                threadAssertTrue(g.isDone());
944 <                threadAssertTrue(g.result == 34);
945 <                threadAssertTrue(h.isDone());
946 <                threadAssertTrue(h.result == 13);
941 >                assertTrue(f.isDone());
942 >                assertTrue(g.isDone());
943 >                assertTrue(h.isDone());
944 >                checkCompletedNormally(f);
945 >                assertEquals(21, f.result);
946 >                checkCompletedNormally(g);
947 >                assertEquals(34, g.result);
948 >                checkCompletedNormally(g);
949 >                assertEquals(13, h.result);
950              }};
951 <        mainPool.invoke(a);
951 >        testInvokeOnPool(mainPool(), a);
952      }
953  
724
954      /**
955       * invokeAll(tasks) with any null task throws NPE
956       */
957      public void testInvokeAllNPE() {
958 <        RecursiveAction a = new RecursiveAction() {
959 <            public void compute() {
958 >        RecursiveAction a = new CheckedRecursiveAction() {
959 >            protected void realCompute() {
960 >                FibAction f = new FibAction(8);
961 >                FibAction g = new FibAction(9);
962 >                FibAction h = null;
963                  try {
732                    FibAction f = new FibAction(8);
733                    FibAction g = new FibAction(9);
734                    FibAction h = null;
964                      invokeAll(f, g, h);
965                      shouldThrow();
966 <                } catch (NullPointerException success) {
738 <                }
966 >                } catch (NullPointerException success) {}
967              }};
968 <        mainPool.invoke(a);
968 >        testInvokeOnPool(mainPool(), a);
969      }
970  
971      /**
972       * invokeAll(t1, t2) throw exception if any task does
973       */
974      public void testAbnormalInvokeAll2() {
975 <        RecursiveAction a = new RecursiveAction() {
976 <            public void compute() {
975 >        RecursiveAction a = new CheckedRecursiveAction() {
976 >            protected void realCompute() {
977 >                FibAction f = new FibAction(8);
978 >                FailingFibAction g = new FailingFibAction(9);
979                  try {
750                    FibAction f = new FibAction(8);
751                    FailingFibAction g = new FailingFibAction(9);
980                      invokeAll(f, g);
981                      shouldThrow();
982                  } catch (FJException success) {
983 +                    checkCompletedAbnormally(g, success);
984                  }
985              }};
986 <        mainPool.invoke(a);
986 >        testInvokeOnPool(mainPool(), a);
987      }
988  
989      /**
990       * invokeAll(tasks) with 1 argument throws exception if task does
991       */
992      public void testAbnormalInvokeAll1() {
993 <        RecursiveAction a = new RecursiveAction() {
994 <            public void compute() {
993 >        RecursiveAction a = new CheckedRecursiveAction() {
994 >            protected void realCompute() {
995 >                FailingFibAction g = new FailingFibAction(9);
996                  try {
767                    FailingFibAction g = new FailingFibAction(9);
997                      invokeAll(g);
998                      shouldThrow();
999                  } catch (FJException success) {
1000 +                    checkCompletedAbnormally(g, success);
1001                  }
1002              }};
1003 <        mainPool.invoke(a);
1003 >        testInvokeOnPool(mainPool(), a);
1004      }
1005  
1006      /**
1007       * invokeAll(tasks) with > 2 argument throws exception if any task does
1008       */
1009      public void testAbnormalInvokeAll3() {
1010 <        RecursiveAction a = new RecursiveAction() {
1011 <            public void compute() {
1010 >        RecursiveAction a = new CheckedRecursiveAction() {
1011 >            protected void realCompute() {
1012 >                FibAction f = new FibAction(8);
1013 >                FailingFibAction g = new FailingFibAction(9);
1014 >                FibAction h = new FibAction(7);
1015                  try {
783                    FibAction f = new FibAction(8);
784                    FailingFibAction g = new FailingFibAction(9);
785                    FibAction h = new FibAction(7);
1016                      invokeAll(f, g, h);
1017                      shouldThrow();
1018                  } catch (FJException success) {
1019 +                    checkCompletedAbnormally(g, success);
1020                  }
1021              }};
1022 <        mainPool.invoke(a);
1022 >        testInvokeOnPool(mainPool(), a);
1023      }
1024  
1025      /**
1026       * invokeAll(collection) throws exception if any task does
1027       */
1028      public void testAbnormalInvokeAllCollection() {
1029 <        RecursiveAction a = new RecursiveAction() {
1030 <            public void compute() {
1029 >        RecursiveAction a = new CheckedRecursiveAction() {
1030 >            protected void realCompute() {
1031 >                FailingFibAction f = new FailingFibAction(8);
1032 >                FibAction g = new FibAction(9);
1033 >                FibAction h = new FibAction(7);
1034 >                HashSet set = new HashSet();
1035 >                set.add(f);
1036 >                set.add(g);
1037 >                set.add(h);
1038                  try {
801                    FailingFibAction f = new FailingFibAction(8);
802                    FibAction g = new FibAction(9);
803                    FibAction h = new FibAction(7);
804                    HashSet set = new HashSet();
805                    set.add(f);
806                    set.add(g);
807                    set.add(h);
1039                      invokeAll(set);
1040                      shouldThrow();
1041                  } catch (FJException success) {
1042 +                    checkCompletedAbnormally(f, success);
1043                  }
1044              }};
1045 <        mainPool.invoke(a);
1045 >        testInvokeOnPool(mainPool(), a);
1046      }
1047  
1048      /**
# Line 818 | Line 1050 | public class RecursiveActionTest extends
1050       * and suppresses execution
1051       */
1052      public void testTryUnfork() {
1053 <        RecursiveAction a = new RecursiveAction() {
1054 <            public void compute() {
1053 >        RecursiveAction a = new CheckedRecursiveAction() {
1054 >            protected void realCompute() {
1055                  FibAction g = new FibAction(9);
1056 <                g.fork();
1056 >                assertSame(g, g.fork());
1057                  FibAction f = new FibAction(8);
1058 <                f.fork();
1059 <                threadAssertTrue(f.tryUnfork());
1058 >                assertSame(f, f.fork());
1059 >                assertTrue(f.tryUnfork());
1060                  helpQuiesce();
1061 <                threadAssertFalse(f.isDone());
1062 <                threadAssertTrue(g.isDone());
1061 >                checkNotDone(f);
1062 >                checkCompletedNormally(g);
1063              }};
1064 <        singletonPool.invoke(a);
1064 >        testInvokeOnPool(singletonPool(), a);
1065      }
1066  
1067      /**
# Line 837 | Line 1069 | public class RecursiveActionTest extends
1069       * there are more tasks than threads
1070       */
1071      public void testGetSurplusQueuedTaskCount() {
1072 <        RecursiveAction a = new RecursiveAction() {
1073 <            public void compute() {
1072 >        RecursiveAction a = new CheckedRecursiveAction() {
1073 >            protected void realCompute() {
1074                  FibAction h = new FibAction(7);
1075 <                h.fork();
1075 >                assertSame(h, h.fork());
1076                  FibAction g = new FibAction(9);
1077 <                g.fork();
1077 >                assertSame(g, g.fork());
1078                  FibAction f = new FibAction(8);
1079 <                f.fork();
1080 <                threadAssertTrue(getSurplusQueuedTaskCount() > 0);
1079 >                assertSame(f, f.fork());
1080 >                assertTrue(getSurplusQueuedTaskCount() > 0);
1081                  helpQuiesce();
1082 +                assertEquals(0, getSurplusQueuedTaskCount());
1083 +                checkCompletedNormally(f);
1084 +                checkCompletedNormally(g);
1085 +                checkCompletedNormally(h);
1086              }};
1087 <        singletonPool.invoke(a);
1087 >        testInvokeOnPool(singletonPool(), a);
1088      }
1089  
1090      /**
1091       * peekNextLocalTask returns most recent unexecuted task.
1092       */
1093      public void testPeekNextLocalTask() {
1094 <        RecursiveAction a = new RecursiveAction() {
1095 <            public void compute() {
1094 >        RecursiveAction a = new CheckedRecursiveAction() {
1095 >            protected void realCompute() {
1096                  FibAction g = new FibAction(9);
1097 <                g.fork();
1097 >                assertSame(g, g.fork());
1098                  FibAction f = new FibAction(8);
1099 <                f.fork();
1100 <                threadAssertTrue(peekNextLocalTask() == f);
1101 <                f.join();
1102 <                threadAssertTrue(f.isDone());
1099 >                assertSame(f, f.fork());
1100 >                assertSame(f, peekNextLocalTask());
1101 >                assertNull(f.join());
1102 >                checkCompletedNormally(f);
1103                  helpQuiesce();
1104 +                checkCompletedNormally(f);
1105 +                checkCompletedNormally(g);
1106              }};
1107 <        singletonPool.invoke(a);
1107 >        testInvokeOnPool(singletonPool(), a);
1108      }
1109  
1110      /**
# Line 874 | Line 1112 | public class RecursiveActionTest extends
1112       * without executing it
1113       */
1114      public void testPollNextLocalTask() {
1115 <        RecursiveAction a = new RecursiveAction() {
1116 <            public void compute() {
1115 >        RecursiveAction a = new CheckedRecursiveAction() {
1116 >            protected void realCompute() {
1117                  FibAction g = new FibAction(9);
1118 <                g.fork();
1118 >                assertSame(g, g.fork());
1119                  FibAction f = new FibAction(8);
1120 <                f.fork();
1121 <                threadAssertTrue(pollNextLocalTask() == f);
1120 >                assertSame(f, f.fork());
1121 >                assertSame(f, pollNextLocalTask());
1122                  helpQuiesce();
1123 <                threadAssertFalse(f.isDone());
1123 >                checkNotDone(f);
1124 >                checkCompletedNormally(g);
1125              }};
1126 <        singletonPool.invoke(a);
1126 >        testInvokeOnPool(singletonPool(), a);
1127      }
1128  
1129      /**
1130 <     * pollTask returns an unexecuted task
892 <     * without executing it
1130 >     * pollTask returns an unexecuted task without executing it
1131       */
1132      public void testPollTask() {
1133 <        RecursiveAction a = new RecursiveAction() {
1134 <            public void compute() {
1133 >        RecursiveAction a = new CheckedRecursiveAction() {
1134 >            protected void realCompute() {
1135                  FibAction g = new FibAction(9);
1136 <                g.fork();
1136 >                assertSame(g, g.fork());
1137                  FibAction f = new FibAction(8);
1138 <                f.fork();
1139 <                threadAssertTrue(pollTask() == f);
1138 >                assertSame(f, f.fork());
1139 >                assertSame(f, pollTask());
1140                  helpQuiesce();
1141 <                threadAssertFalse(f.isDone());
1142 <                threadAssertTrue(g.isDone());
1141 >                checkNotDone(f);
1142 >                checkCompletedNormally(g);
1143              }};
1144 <        singletonPool.invoke(a);
1144 >        testInvokeOnPool(singletonPool(), a);
1145      }
1146  
1147      /**
1148       * peekNextLocalTask returns least recent unexecuted task in async mode
1149       */
1150      public void testPeekNextLocalTaskAsync() {
1151 <        RecursiveAction a = new RecursiveAction() {
1152 <            public void compute() {
1151 >        RecursiveAction a = new CheckedRecursiveAction() {
1152 >            protected void realCompute() {
1153                  FibAction g = new FibAction(9);
1154 <                g.fork();
1154 >                assertSame(g, g.fork());
1155                  FibAction f = new FibAction(8);
1156 <                f.fork();
1157 <                threadAssertTrue(peekNextLocalTask() == g);
1158 <                f.join();
1156 >                assertSame(f, f.fork());
1157 >                assertSame(g, peekNextLocalTask());
1158 >                assertNull(f.join());
1159                  helpQuiesce();
1160 <                threadAssertTrue(f.isDone());
1160 >                checkCompletedNormally(f);
1161 >                checkCompletedNormally(g);
1162              }};
1163 <        asyncSingletonPool.invoke(a);
1163 >        testInvokeOnPool(asyncSingletonPool(), a);
1164      }
1165  
1166      /**
1167 <     * pollNextLocalTask returns least recent unexecuted task
1168 <     * without executing it, in async mode
1167 >     * pollNextLocalTask returns least recent unexecuted task without
1168 >     * executing it, in async mode
1169       */
1170      public void testPollNextLocalTaskAsync() {
1171 <        RecursiveAction a = new RecursiveAction() {
1172 <            public void compute() {
1171 >        RecursiveAction a = new CheckedRecursiveAction() {
1172 >            protected void realCompute() {
1173                  FibAction g = new FibAction(9);
1174 <                g.fork();
1174 >                assertSame(g, g.fork());
1175                  FibAction f = new FibAction(8);
1176 <                f.fork();
1177 <                threadAssertTrue(pollNextLocalTask() == g);
1176 >                assertSame(f, f.fork());
1177 >                assertSame(g, pollNextLocalTask());
1178                  helpQuiesce();
1179 <                threadAssertTrue(f.isDone());
1180 <                threadAssertFalse(g.isDone());
1179 >                checkCompletedNormally(f);
1180 >                checkNotDone(g);
1181              }};
1182 <        asyncSingletonPool.invoke(a);
1182 >        testInvokeOnPool(asyncSingletonPool(), a);
1183      }
1184  
1185      /**
1186 <     * pollTask returns an unexecuted task
1187 <     * without executing it, in async mode
1186 >     * pollTask returns an unexecuted task without executing it, in
1187 >     * async mode
1188       */
1189      public void testPollTaskAsync() {
1190 <        RecursiveAction a = new RecursiveAction() {
1191 <            public void compute() {
1190 >        RecursiveAction a = new CheckedRecursiveAction() {
1191 >            protected void realCompute() {
1192                  FibAction g = new FibAction(9);
1193 <                g.fork();
1193 >                assertSame(g, g.fork());
1194                  FibAction f = new FibAction(8);
1195 <                f.fork();
1196 <                threadAssertTrue(pollTask() == g);
1195 >                assertSame(f, f.fork());
1196 >                assertSame(g, pollTask());
1197                  helpQuiesce();
1198 <                threadAssertTrue(f.isDone());
1199 <                threadAssertFalse(g.isDone());
1198 >                checkCompletedNormally(f);
1199 >                checkNotDone(g);
1200              }};
1201 <        asyncSingletonPool.invoke(a);
1201 >        testInvokeOnPool(asyncSingletonPool(), a);
1202      }
1203  
1204 +    /** Demo from RecursiveAction javadoc */
1205 +    static class SortTask extends RecursiveAction {
1206 +        final long[] array; final int lo, hi;
1207 +        SortTask(long[] array, int lo, int hi) {
1208 +            this.array = array; this.lo = lo; this.hi = hi;
1209 +        }
1210 +        SortTask(long[] array) { this(array, 0, array.length); }
1211 +        protected void compute() {
1212 +            if (hi - lo < THRESHOLD)
1213 +                sortSequentially(lo, hi);
1214 +            else {
1215 +                int mid = (lo + hi) >>> 1;
1216 +                invokeAll(new SortTask(array, lo, mid),
1217 +                          new SortTask(array, mid, hi));
1218 +                merge(lo, mid, hi);
1219 +            }
1220 +        }
1221 +        // implementation details follow:
1222 +        static final int THRESHOLD = 100;
1223 +        void sortSequentially(int lo, int hi) {
1224 +            Arrays.sort(array, lo, hi);
1225 +        }
1226 +        void merge(int lo, int mid, int hi) {
1227 +            long[] buf = Arrays.copyOfRange(array, lo, mid);
1228 +            for (int i = 0, j = lo, k = mid; i < buf.length; j++)
1229 +                array[j] = (k == hi || buf[i] < array[k]) ?
1230 +                    buf[i++] : array[k++];
1231 +        }
1232 +    }
1233 +
1234 +    /**
1235 +     * SortTask demo works as advertised
1236 +     */
1237 +    public void testSortTaskDemo() {
1238 +        ThreadLocalRandom rnd = ThreadLocalRandom.current();
1239 +        long[] array = new long[1007];
1240 +        for (int i = 0; i < array.length; i++)
1241 +            array[i] = rnd.nextLong();
1242 +        long[] arrayClone = array.clone();
1243 +        testInvokeOnPool(mainPool(), new SortTask(array));
1244 +        Arrays.sort(arrayClone);
1245 +        assertTrue(Arrays.equals(array, arrayClone));
1246 +    }
1247   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines