257 |
|
* surrounded with pool notifications. |
258 |
|
* @return status upon exit |
259 |
|
*/ |
260 |
< |
final int awaitDone(ForkJoinWorkerThread w, boolean maintainParallelism) { |
260 |
> |
private int awaitDone(ForkJoinWorkerThread w, boolean maintainParallelism) { |
261 |
|
ForkJoinPool pool = w == null? null : w.pool; |
262 |
|
int s; |
263 |
|
while ((s = status) >= 0) { |
276 |
|
* Timed version of awaitDone |
277 |
|
* @return status upon exit |
278 |
|
*/ |
279 |
< |
final int awaitDone(ForkJoinWorkerThread w, long nanos) { |
279 |
> |
private int awaitDone(ForkJoinWorkerThread w, long nanos) { |
280 |
|
ForkJoinPool pool = w == null? null : w.pool; |
281 |
|
int s; |
282 |
|
while ((s = status) >= 0) { |
330 |
|
if (w == null) |
331 |
|
Thread.currentThread().interrupt(); // re-interrupt |
332 |
|
else if (w.isTerminating()) |
333 |
< |
cancelIgnoreExceptions(); |
333 |
> |
cancelIgnoringExceptions(); |
334 |
|
// else if FJworker, ignore interrupt |
335 |
|
} |
336 |
|
|
449 |
|
/** |
450 |
|
* Cancel, ignoring any exceptions it throws |
451 |
|
*/ |
452 |
< |
final void cancelIgnoreExceptions() { |
452 |
> |
final void cancelIgnoringExceptions() { |
453 |
|
try { |
454 |
|
cancel(false); |
455 |
|
} catch(Throwable ignore) { |
456 |
|
} |
457 |
|
} |
458 |
|
|
459 |
+ |
/** |
460 |
+ |
* Main implementation of helpJoin |
461 |
+ |
*/ |
462 |
+ |
private int busyJoin(ForkJoinWorkerThread w) { |
463 |
+ |
int s; |
464 |
+ |
ForkJoinTask<?> t; |
465 |
+ |
while ((s = status) >= 0 && (t = w.scanWhileJoining(this)) != null) |
466 |
+ |
t.quietlyExec(); |
467 |
+ |
return (s >= 0)? awaitDone(w, false) : s; // block if no work |
468 |
+ |
} |
469 |
+ |
|
470 |
|
// public methods |
471 |
|
|
472 |
|
/** |
496 |
|
return getRawResult(); |
497 |
|
} |
498 |
|
|
488 |
– |
public final V get() throws InterruptedException, ExecutionException { |
489 |
– |
ForkJoinWorkerThread w = getWorker(); |
490 |
– |
if (w == null || status < 0 || !w.unpushTask(this) || !tryQuietlyInvoke()) |
491 |
– |
awaitDone(w, true); |
492 |
– |
return reportFutureResult(); |
493 |
– |
} |
494 |
– |
|
495 |
– |
public final V get(long timeout, TimeUnit unit) |
496 |
– |
throws InterruptedException, ExecutionException, TimeoutException { |
497 |
– |
ForkJoinWorkerThread w = getWorker(); |
498 |
– |
if (w == null || status < 0 || !w.unpushTask(this) || !tryQuietlyInvoke()) |
499 |
– |
awaitDone(w, unit.toNanos(timeout)); |
500 |
– |
return reportTimedFutureResult(); |
501 |
– |
} |
502 |
– |
|
499 |
|
/** |
500 |
|
* Commences performing this task, awaits its completion if |
501 |
|
* necessary, and return its result. |
638 |
|
} |
639 |
|
|
640 |
|
/** |
645 |
– |
* Returns true if this task threw an exception or was cancelled |
646 |
– |
* @return true if this task threw an exception or was cancelled |
647 |
– |
*/ |
648 |
– |
public final boolean isCompletedAbnormally() { |
649 |
– |
return (status & COMPLETION_MASK) < NORMAL; |
650 |
– |
} |
651 |
– |
|
652 |
– |
/** |
653 |
– |
* Returns the exception thrown by the base computation, or a |
654 |
– |
* CancellationException if cancelled, or null if none or if the |
655 |
– |
* method has not yet completed. |
656 |
– |
* @return the exception, or null if none |
657 |
– |
*/ |
658 |
– |
public final Throwable getException() { |
659 |
– |
int s = status & COMPLETION_MASK; |
660 |
– |
if (s >= NORMAL) |
661 |
– |
return null; |
662 |
– |
if (s == CANCELLED) |
663 |
– |
return new CancellationException(); |
664 |
– |
return exceptionMap.get(this); |
665 |
– |
} |
666 |
– |
|
667 |
– |
/** |
641 |
|
* Asserts that the results of this task's computation will not be |
642 |
|
* used. If a cancellation occurs before atempting to execute this |
643 |
|
* task, then execution will be suppressed, <code>isCancelled</code> |
670 |
|
} |
671 |
|
|
672 |
|
/** |
673 |
+ |
* Returns true if this task threw an exception or was cancelled |
674 |
+ |
* @return true if this task threw an exception or was cancelled |
675 |
+ |
*/ |
676 |
+ |
public final boolean isCompletedAbnormally() { |
677 |
+ |
return (status & COMPLETION_MASK) < NORMAL; |
678 |
+ |
} |
679 |
+ |
|
680 |
+ |
/** |
681 |
+ |
* Returns the exception thrown by the base computation, or a |
682 |
+ |
* CancellationException if cancelled, or null if none or if the |
683 |
+ |
* method has not yet completed. |
684 |
+ |
* @return the exception, or null if none |
685 |
+ |
*/ |
686 |
+ |
public final Throwable getException() { |
687 |
+ |
int s = status & COMPLETION_MASK; |
688 |
+ |
if (s >= NORMAL) |
689 |
+ |
return null; |
690 |
+ |
if (s == CANCELLED) |
691 |
+ |
return new CancellationException(); |
692 |
+ |
return exceptionMap.get(this); |
693 |
+ |
} |
694 |
+ |
|
695 |
+ |
/** |
696 |
|
* Completes this task abnormally, and if not already aborted or |
697 |
|
* cancelled, causes it to throw the given exception upon |
698 |
|
* <code>join</code> and related operations. This method may be used |
734 |
|
setNormalCompletion(); |
735 |
|
} |
736 |
|
|
737 |
+ |
public final V get() throws InterruptedException, ExecutionException { |
738 |
+ |
ForkJoinWorkerThread w = getWorker(); |
739 |
+ |
if (w == null || status < 0 || !w.unpushTask(this) || !tryQuietlyInvoke()) |
740 |
+ |
awaitDone(w, true); |
741 |
+ |
return reportFutureResult(); |
742 |
+ |
} |
743 |
+ |
|
744 |
+ |
public final V get(long timeout, TimeUnit unit) |
745 |
+ |
throws InterruptedException, ExecutionException, TimeoutException { |
746 |
+ |
ForkJoinWorkerThread w = getWorker(); |
747 |
+ |
if (w == null || status < 0 || !w.unpushTask(this) || !tryQuietlyInvoke()) |
748 |
+ |
awaitDone(w, unit.toNanos(timeout)); |
749 |
+ |
return reportTimedFutureResult(); |
750 |
+ |
} |
751 |
+ |
|
752 |
|
/** |
753 |
|
* Possibly executes other tasks until this task is ready, then |
754 |
|
* returns the result of the computation. This method may be more |
764 |
|
public final V helpJoin() { |
765 |
|
ForkJoinWorkerThread w = (ForkJoinWorkerThread)(Thread.currentThread()); |
766 |
|
if (status < 0 || !w.unpushTask(this) || !tryExec()) |
767 |
< |
reportException(w.helpJoinTask(this)); |
767 |
> |
reportException(busyJoin(w)); |
768 |
|
return getRawResult(); |
769 |
|
} |
770 |
|
|
779 |
|
ForkJoinWorkerThread w = |
780 |
|
(ForkJoinWorkerThread)(Thread.currentThread()); |
781 |
|
if (!w.unpushTask(this) || !tryQuietlyInvoke()) |
782 |
< |
w.helpJoinTask(this); |
782 |
> |
busyJoin(w); |
783 |
|
} |
784 |
|
} |
785 |
|
|
810 |
|
} |
811 |
|
|
812 |
|
/** |
813 |
+ |
* Possibly executes tasks until the pool hosting the current task |
814 |
+ |
* {@link ForkJoinPool#isQuiescent}. This method may be of use in |
815 |
+ |
* designs in which many tasks are forked, but none are explicitly |
816 |
+ |
* joined, instead executing them until all are processed. |
817 |
+ |
*/ |
818 |
+ |
public static void helpQuiesce() { |
819 |
+ |
((ForkJoinWorkerThread)(Thread.currentThread())). |
820 |
+ |
helpQuiescePool(); |
821 |
+ |
} |
822 |
+ |
|
823 |
+ |
/** |
824 |
|
* Resets the internal bookkeeping state of this task, allowing a |
825 |
|
* subsequent <code>fork</code>. This method allows repeated reuse of |
826 |
|
* this task, but only if reuse occurs when this task has either |
863 |
|
} |
864 |
|
|
865 |
|
/** |
844 |
– |
* Possibly executes tasks until the pool hosting the current task |
845 |
– |
* {@link ForkJoinPool#isQuiescent}. This method may be of use in |
846 |
– |
* designs in which many tasks are forked, but none are explicitly |
847 |
– |
* joined, instead executing them until all are processed. |
848 |
– |
*/ |
849 |
– |
public static void helpQuiesce() { |
850 |
– |
((ForkJoinWorkerThread)(Thread.currentThread())). |
851 |
– |
helpQuiescePool(); |
852 |
– |
} |
853 |
– |
|
854 |
– |
/** |
866 |
|
* Returns an estimate of the number of tasks that have been |
867 |
|
* forked by the current worker thread but not yet executed. This |
868 |
|
* value may be useful for heuristic decisions about whether to |
965 |
|
*/ |
966 |
|
protected static ForkJoinTask<?> pollTask() { |
967 |
|
return ((ForkJoinWorkerThread)(Thread.currentThread())). |
968 |
< |
getLocalOrStolenTask(); |
968 |
> |
pollLocalOrStolenTask(); |
969 |
|
} |
970 |
|
|
971 |
|
// Serialization support |