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

Comparing jsr166/src/jsr166y/CountedCompleter.java (file contents):
Revision 1.1 by dl, Mon Apr 9 13:12:18 2012 UTC vs.
Revision 1.2 by dl, Sat Apr 21 11:45:20 2012 UTC

# Line 21 | Line 21 | package jsr166y;
21   * #tryComplete}, if the pending action count is nonzero, it is
22   * decremented; otherwise, the completion action is performed, and if
23   * this completer itself has a completer, the process is continued
24 < * with its completer.  As is the case with most basic synchronization
25 < * constructs, these methods affect only internal counts; they do not
26 < * establish any further internal bookkeeping. In particular, the
27 < * identities of pending tasks are not maintained. As illustrated
28 < * below, you can create subclasses that do record some or all pended
29 < * tasks or their results when needed.
24 > * with its completer.  As is the case with related synchronization
25 > * components such as {@link Phaser} and {@link
26 > * java.util.concurrent.Semaphore} these methods affect only internal
27 > * counts; they do not establish any further internal bookkeeping. In
28 > * particular, the identities of pending tasks are not maintained. As
29 > * illustrated below, you can create subclasses that do record some or
30 > * all pended tasks or their results when needed.
31   *
32   * <p>A concrete CountedCompleter class must define method {@link
33   * #compute}, that should, in almost all use cases, invoke {@code
34 < * tryComplete()} before returning. The class may also optionally
34 > * tryComplete()} once before returning. The class may also optionally
35   * override method {@link #onCompletion} to perform an action upon
36 < * normal completion.
36 > * normal completion, and method {@link #onExceptionalCompletion} to
37 > * perform an action upon any exception.
38   *
39   * <p>A CountedCompleter that does not itself have a completer (i.e.,
40   * one for which {@link #getCompleter} returns {@code null}) can be
# Line 44 | Line 46 | package jsr166y;
46   * {@link #complete}, {@link ForkJoinTask#cancel}, {@link
47   * ForkJoinTask#completeExceptionally} or upon exceptional completion
48   * of method {@code compute}. Upon any exceptional completion, the
49 < * exception is relayed to a task's completer (and its completer, and
50 < * so on), if one exists and it has not otherwise already completed.
49 > * exception may be relayed to a task's completer (and its completer,
50 > * and so on), if one exists and it has not otherwise already
51 > * completed.
52   *
53   * <p><b>Sample Usages.</b>
54   *
# Line 237 | Line 240 | package jsr166y;
240   * @author Doug Lea
241   */
242   public abstract class CountedCompleter extends ForkJoinTask<Void> {
243 +    private static final long serialVersionUID = 5232453752276485070L;
244 +
245      /** This task's completer, or null if none */
246      final CountedCompleter completer;
247      /** The number of pending tasks until completion */
# Line 279 | Line 284 | public abstract class CountedCompleter e
284      public abstract void compute();
285  
286      /**
287 <     * Executes the completion action when method {@link #tryComplete}
288 <     * is invoked and there are no pending counts, or when the
289 <     * unconditional method {@link #complete} is invoked.  By default,
290 <     * this method does nothing.
287 >     * Performs an action when method {@link #tryComplete} is invoked
288 >     * and there are no pending counts, or when the unconditional
289 >     * method {@link #complete} is invoked.  By default, this method
290 >     * does nothing.
291       *
292       * @param caller the task invoking this method (which may
293       * be this task itself).
# Line 291 | Line 296 | public abstract class CountedCompleter e
296      }
297  
298      /**
299 +     * Performs an action when method {@link #completeExceptionally}
300 +     * is invoked or method {@link #compute} throws an exception, and
301 +     * this task has not otherwise already completed normally. On
302 +     * entry to this method, this task {@link
303 +     * ForkJoinTask#isCompletedAbnormally}.  The return value of this
304 +     * method controls further propagation: If {@code true} and this
305 +     * task has a completer, then this completer is also completed
306 +     * exceptionally.  The default implementation of this method does
307 +     * nothing except return {@code true}.
308 +     *
309 +     * @param ex the exception
310 +     * @param caller the task invoking this method (which may
311 +     * be this task itself).
312 +     * @return true if this exception should be propagated to this
313 +     * tasks completer, if one exists.
314 +     */
315 +    public boolean onExceptionalCompletion(Throwable ex, CountedCompleter caller) {
316 +        return true;
317 +    }
318 +
319 +    /**
320       * Returns the completer established in this task's constructor,
321       * or {@code null} if none.
322       *
# Line 347 | Line 373 | public abstract class CountedCompleter e
373       * else marks this task as complete.
374       */
375      public final void tryComplete() {
376 <        for (CountedCompleter a = this, s = a;;) {
377 <            int c;
376 >        CountedCompleter a = this, s = a;
377 >        for (int c;;) {
378              if ((c = a.pending) == 0) {
379                  a.onCompletion(s);
380                  if ((a = (s = a).completer) == null) {
# Line 380 | Line 406 | public abstract class CountedCompleter e
406      }
407  
408      /**
409 +     * Support for FJT exception propagation
410 +     */
411 +    void internalPropagateException(Throwable ex) {
412 +        CountedCompleter a = this, s = a;
413 +        while (a.onExceptionalCompletion(ex, s) &&
414 +               (a = (s = a).completer) != null && a.status >= 0)
415 +            a.recordExceptionalCompletion(ex);
416 +    }
417 +
418 +    /**
419       * Implements execution conventions for CountedCompleters
420       */
421      protected final boolean exec() {
# Line 399 | Line 435 | public abstract class CountedCompleter e
435       */
436      protected final void setRawResult(Void mustBeNull) { }
437  
402    /**
403     * Support for FJT exception propagation
404     */
405    final ForkJoinTask<?> internalGetCompleter() { return completer; }
406
438      // Unsafe mechanics
439      private static final sun.misc.Unsafe U;
440      private static final long PENDING;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines