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 |
|
|
7 |
|
package jsr166y; |
8 |
|
|
9 |
|
import java.io.Serializable; |
10 |
|
import java.util.Collection; |
11 |
– |
import java.util.Collections; |
11 |
|
import java.util.List; |
12 |
|
import java.util.RandomAccess; |
14 |
– |
import java.util.Map; |
13 |
|
import java.lang.ref.WeakReference; |
14 |
|
import java.lang.ref.ReferenceQueue; |
15 |
|
import java.util.concurrent.Callable; |
16 |
|
import java.util.concurrent.CancellationException; |
17 |
|
import java.util.concurrent.ExecutionException; |
20 |
– |
import java.util.concurrent.Executor; |
21 |
– |
import java.util.concurrent.ExecutorService; |
18 |
|
import java.util.concurrent.Future; |
19 |
|
import java.util.concurrent.RejectedExecutionException; |
20 |
|
import java.util.concurrent.RunnableFuture; |
161 |
|
* See the internal documentation of class ForkJoinPool for a |
162 |
|
* general implementation overview. ForkJoinTasks are mainly |
163 |
|
* responsible for maintaining their "status" field amidst relays |
164 |
< |
* to methods in ForkJoinWorkerThread and ForkJoinPool. The |
165 |
< |
* methods of this class are more-or-less layered into (1) basic |
166 |
< |
* status maintenance (2) execution and awaiting completion (3) |
167 |
< |
* user-level methods that additionally report results. This is |
168 |
< |
* sometimes hard to see because this file orders exported methods |
169 |
< |
* in a way that flows well in javadocs. |
164 |
> |
* to methods in ForkJoinWorkerThread and ForkJoinPool. |
165 |
> |
* |
166 |
> |
* The methods of this class are more-or-less layered into |
167 |
> |
* (1) basic status maintenance |
168 |
> |
* (2) execution and awaiting completion |
169 |
> |
* (3) user-level methods that additionally report results. |
170 |
> |
* This is sometimes hard to see because this file orders exported |
171 |
> |
* methods in a way that flows well in javadocs. |
172 |
|
*/ |
173 |
|
|
174 |
|
/* |
382 |
|
* periods. However, since we do not know when the last joiner |
383 |
|
* completes, we must use weak references and expunge them. We do |
384 |
|
* so on each operation (hence full locking). Also, some thread in |
385 |
< |
* any ForkJoinPool will call helpExpunge when its pool becomes |
386 |
< |
* isQuiescent. |
385 |
> |
* any ForkJoinPool will call helpExpungeStaleExceptions when its |
386 |
> |
* pool becomes isQuiescent. |
387 |
|
*/ |
388 |
|
static final class ExceptionNode extends WeakReference<ForkJoinTask<?>>{ |
389 |
|
final Throwable ex; |
390 |
|
ExceptionNode next; |
391 |
< |
final long thrower; |
391 |
> |
final long thrower; // use id not ref to avoid weak cycles |
392 |
|
ExceptionNode(ForkJoinTask<?> task, Throwable ex, ExceptionNode next) { |
393 |
|
super(task, exceptionTableRefQueue); |
394 |
|
this.ex = ex; |
404 |
|
*/ |
405 |
|
private int setExceptionalCompletion(Throwable ex) { |
406 |
|
int h = System.identityHashCode(this); |
407 |
< |
ReentrantLock lock = exceptionTableLock; |
407 |
> |
final ReentrantLock lock = exceptionTableLock; |
408 |
|
lock.lock(); |
409 |
|
try { |
410 |
|
expungeStaleExceptions(); |
429 |
|
*/ |
430 |
|
private void clearExceptionalCompletion() { |
431 |
|
int h = System.identityHashCode(this); |
432 |
< |
ReentrantLock lock = exceptionTableLock; |
432 |
> |
final ReentrantLock lock = exceptionTableLock; |
433 |
|
lock.lock(); |
434 |
|
try { |
435 |
|
ExceptionNode[] t = exceptionTable; |
474 |
|
return null; |
475 |
|
int h = System.identityHashCode(this); |
476 |
|
ExceptionNode e; |
477 |
< |
ReentrantLock lock = exceptionTableLock; |
477 |
> |
final ReentrantLock lock = exceptionTableLock; |
478 |
|
lock.lock(); |
479 |
|
try { |
480 |
|
expungeStaleExceptions(); |
489 |
|
if (e == null || (ex = e.ex) == null) |
490 |
|
return null; |
491 |
|
if (e.thrower != Thread.currentThread().getId()) { |
492 |
< |
Class ec = ex.getClass(); |
492 |
> |
Class<? extends Throwable> ec = ex.getClass(); |
493 |
|
try { |
494 |
|
Constructor<?> noArgCtor = null; |
495 |
|
Constructor<?>[] cs = ec.getConstructors();// public ctors only |
540 |
|
} |
541 |
|
|
542 |
|
/** |
543 |
< |
* If lock is available, poll any stale refs and remove them. |
543 |
> |
* If lock is available, poll stale refs and remove them. |
544 |
|
* Called from ForkJoinPool when pools become quiescent. |
545 |
|
*/ |
546 |
|
static final void helpExpungeStaleExceptions() { |
547 |
< |
ReentrantLock lock = exceptionTableLock; |
547 |
> |
final ReentrantLock lock = exceptionTableLock; |
548 |
|
if (lock.tryLock()) { |
549 |
|
try { |
550 |
|
expungeStaleExceptions(); |
695 |
|
if (t != null) { |
696 |
|
if (ex != null) |
697 |
|
t.cancel(false); |
698 |
< |
else if (t.doJoin() < NORMAL && ex == null) |
698 |
> |
else if (t.doJoin() < NORMAL) |
699 |
|
ex = t.getException(); |
700 |
|
} |
701 |
|
} |
752 |
|
if (t != null) { |
753 |
|
if (ex != null) |
754 |
|
t.cancel(false); |
755 |
< |
else if (t.doJoin() < NORMAL && ex == null) |
755 |
> |
else if (t.doJoin() < NORMAL) |
756 |
|
ex = t.getException(); |
757 |
|
} |
758 |
|
} |