--- jsr166/src/jsr166e/CountedCompleter.java 2012/11/25 21:04:43 1.22 +++ jsr166/src/jsr166e/CountedCompleter.java 2013/06/19 14:55:40 1.30 @@ -8,18 +8,19 @@ package jsr166e; /** * A {@link ForkJoinTask} with a completion action performed when - * triggered and there are no remaining pending - * actions. CountedCompleters are in general more robust in the + * triggered and there are no remaining pending actions. + * CountedCompleters are in general more robust in the * presence of subtask stalls and blockage than are other forms of * ForkJoinTasks, but are less intuitive to program. Uses of * CountedCompleter are similar to those of other completion based * components (such as {@link java.nio.channels.CompletionHandler}) * except that multiple pending completions may be necessary - * to trigger the {@link #onCompletion} action, not just one. Unless - * initialized otherwise, the {@link #getPendingCount pending count} - * starts at zero, but may be (atomically) changed using methods - * {@link #setPendingCount}, {@link #addToPendingCount}, and {@link - * #compareAndSetPendingCount}. Upon invocation of {@link + * to trigger the completion action {@link #onCompletion(CountedCompleter)}, + * not just one. + * Unless initialized otherwise, the {@linkplain #getPendingCount pending + * count} starts at zero, but may be (atomically) changed using + * methods {@link #setPendingCount}, {@link #addToPendingCount}, and + * {@link #compareAndSetPendingCount}. Upon invocation of {@link * #tryComplete}, if the pending action count is nonzero, it is * decremented; otherwise, the completion action is performed, and if * this completer itself has a completer, the process is continued @@ -40,9 +41,10 @@ package jsr166e; *

A concrete CountedCompleter class must define method {@link * #compute}, that should in most cases (as illustrated below), invoke * {@code tryComplete()} once before returning. The class may also - * optionally override method {@link #onCompletion} to perform an - * action upon normal completion, and method {@link - * #onExceptionalCompletion} to perform an action upon any exception. + * optionally override method {@link #onCompletion(CountedCompleter)} + * to perform an action upon normal completion, and method + * {@link #onExceptionalCompletion(Throwable, CountedCompleter)} to + * perform an action upon any exception. * *

CountedCompleters most often do not bear results, in which case * they are normally declared as {@code CountedCompleter}, and @@ -63,13 +65,14 @@ package jsr166e; * only as an internal helper for other computations, so its own task * status (as reported in methods such as {@link ForkJoinTask#isDone}) * is arbitrary; this status changes only upon explicit invocations of - * {@link #complete}, {@link ForkJoinTask#cancel}, {@link - * ForkJoinTask#completeExceptionally} or upon exceptional completion - * of method {@code compute}. Upon any exceptional completion, the - * exception may be relayed to a task's completer (and its completer, - * and so on), if one exists and it has not otherwise already - * completed. Similarly, cancelling an internal CountedCompleter has - * only a local effect on that completer, so is not often useful. + * {@link #complete}, {@link ForkJoinTask#cancel}, + * {@link ForkJoinTask#completeExceptionally(Throwable)} or upon + * exceptional completion of method {@code compute}. Upon any + * exceptional completion, the exception may be relayed to a task's + * completer (and its completer, and so on), if one exists and it has + * not otherwise already completed. Similarly, cancelling an internal + * CountedCompleter has only a local effect on that completer, so is + * not often useful. * *

Sample Usages. * @@ -83,7 +86,7 @@ package jsr166e; * subdivided) to each element of an array or collection; especially * when the operation takes a significantly different amount of time * to complete for some elements than others, either because of - * intrinsic variation (for example IO) or auxiliary effects such as + * intrinsic variation (for example I/O) or auxiliary effects such as * garbage collection. Because CountedCompleters provide their own * continuations, other threads need not block waiting to perform * them. @@ -96,8 +99,8 @@ package jsr166e; * improve load balancing. In the recursive case, the second of each * pair of subtasks to finish triggers completion of its parent * (because no result combination is performed, the default no-op - * implementation of method {@code onCompletion} is not overridden). A - * static utility method sets up the base task and invokes it + * implementation of method {@code onCompletion} is not overridden). + * A static utility method sets up the base task and invokes it * (here, implicitly using the {@link ForkJoinPool#commonPool()}). * *

 {@code
@@ -152,12 +155,11 @@ package jsr166e;
  *   }
  * }
* - * As a further improvement, notice that the left task need not even - * exist. Instead of creating a new one, we can iterate using the - * original task, and add a pending count for each fork. Additionally, - * because no task in this tree implements an {@link #onCompletion} - * method, {@code tryComplete()} can be replaced with {@link - * #propagateCompletion}. + * As a further improvement, notice that the left task need not even exist. + * Instead of creating a new one, we can iterate using the original task, + * and add a pending count for each fork. Additionally, because no task + * in this tree implements an {@link #onCompletion(CountedCompleter)} method, + * {@code tryComplete()} can be replaced with {@link #propagateCompletion}. * *
 {@code
  * class ForEach ...
@@ -183,12 +185,13 @@ package jsr166e;
  *
  * 

Searching. A tree of CountedCompleters can search for a * value or property in different parts of a data structure, and - * report a result in an {@link java.util.concurrent.AtomicReference} - * as soon as one is found. The others can poll the result to avoid - * unnecessary work. (You could additionally {@link #cancel} other - * tasks, but it is usually simpler and more efficient to just let - * them notice that the result is set and if so skip further - * processing.) Illustrating again with an array using full + * report a result in an {@link + * java.util.concurrent.atomic.AtomicReference AtomicReference} as + * soon as one is found. The others can poll the result to avoid + * unnecessary work. (You could additionally {@linkplain #cancel + * cancel} other tasks, but it is usually simpler and more efficient + * to just let them notice that the result is set and if so skip + * further processing.) Illustrating again with an array using full * partitioning (again, in practice, leaf tasks will almost always * process more than one element): * @@ -223,7 +226,7 @@ package jsr166e; * public static E search(E[] array) { * return new Searcher(null, array, new AtomicReference(), 0, array.length).invoke(); * } - *}}

+ * }} * * In this example, as well as others in which tasks have no other * effects except to compareAndSet a common result, the trailing @@ -234,7 +237,7 @@ package jsr166e; * *

Recording subtasks. CountedCompleter tasks that combine * results of multiple subtasks usually need to access these results - * in method {@link #onCompletion}. As illustrated in the following + * in method {@link #onCompletion(CountedCompleter)}. As illustrated in the following * class (that performs a simplified form of map-reduce where mappings * and reductions are all of type {@code E}), one way to do this in * divide and conquer designs is to have each subtask record its @@ -335,7 +338,7 @@ package jsr166e; * while (h - l >= 2) { * int mid = (l + h) >>> 1; * addToPendingCount(1); - * (forks = new MapReducer(this, array, mapper, reducer, mid, h, forks)).fork; + * (forks = new MapReducer(this, array, mapper, reducer, mid, h, forks)).fork(); * h = mid; * } * if (h > l) @@ -356,7 +359,7 @@ package jsr166e; * *

Triggers. Some CountedCompleters are themselves never * forked, but instead serve as bits of plumbing in other designs; - * including those in which the completion of one of more async tasks + * including those in which the completion of one or more async tasks * triggers another async task. For example: * *

 {@code
@@ -388,7 +391,7 @@ public abstract class CountedCompleter completer,
@@ -401,7 +404,7 @@ public abstract class CountedCompleter completer) {
         this.completer = completer;
@@ -422,7 +425,7 @@ public abstract class CountedCompleter caller) {
     }
 
     /**
-     * Performs an action when method {@link #completeExceptionally}
-     * is invoked or method {@link #compute} throws an exception, and
-     * this task has not otherwise already completed normally. On
-     * entry to this method, this task {@link
-     * ForkJoinTask#isCompletedAbnormally}.  The return value of this
-     * method controls further propagation: If {@code true} and this
-     * task has a completer, then this completer is also completed
-     * exceptionally.  The default implementation of this method does
-     * nothing except return {@code true}.
+     * Performs an action when method {@link
+     * #completeExceptionally(Throwable)} is invoked or method {@link
+     * #compute} throws an exception, and this task has not already
+     * otherwise completed normally. On entry to this method, this task
+     * {@link ForkJoinTask#isCompletedAbnormally}.  The return value
+     * of this method controls further propagation: If {@code true}
+     * and this task has a completer that has not completed, then that
+     * completer is also completed exceptionally, with the same
+     * exception as this completer.  The default implementation of
+     * this method does nothing except return {@code true}.
      *
      * @param ex the exception
      * @param caller the task invoking this method (which may
-     * be this task itself).
-     * @return true if this exception should be propagated to this
-     * tasks completer, if one exists.
+     * be this task itself)
+     * @return {@code true} if this exception should be propagated to this
+     * task's completer, if one exists
      */
     public boolean onExceptionalCompletion(Throwable ex, CountedCompleter caller) {
         return true;
@@ -490,7 +494,7 @@ public abstract class CountedCompleter a = this, s = a;
@@ -555,12 +559,12 @@ public abstract class CountedCompleter a = this, s = a;
@@ -577,13 +581,15 @@ public abstract class CountedCompleterThis method may be useful when forcing completion as soon as
      * any one (versus all) of several subtask results are obtained.
@@ -623,8 +629,8 @@ public abstract class CountedCompleter a = this, s = a;
         while (a.onExceptionalCompletion(ex, s) &&
-               (a = (s = a).completer) != null && a.status >= 0)
-            a.recordExceptionalCompletion(ex);
+               (a = (s = a).completer) != null && a.status >= 0 &&
+               a.recordExceptionalCompletion(ex) == EXCEPTIONAL)
+            ;
     }
 
     /**
@@ -703,7 +710,7 @@ public abstract class CountedCompleter() {
-                        public sun.misc.Unsafe run() throws Exception {
-                            java.lang.reflect.Field f = sun.misc
-                                .Unsafe.class.getDeclaredField("theUnsafe");
-                            f.setAccessible(true);
-                            return (sun.misc.Unsafe) f.get(null);
-                        }});
-            } catch (java.security.PrivilegedActionException e) {
-                throw new RuntimeException("Could not initialize intrinsics",
-                                           e.getCause());
-            }
+        } catch (SecurityException tryReflectionInstead) {}
+        try {
+            return java.security.AccessController.doPrivileged
+            (new java.security.PrivilegedExceptionAction() {
+                public sun.misc.Unsafe run() throws Exception {
+                    Class k = sun.misc.Unsafe.class;
+                    for (java.lang.reflect.Field f : k.getDeclaredFields()) {
+                        f.setAccessible(true);
+                        Object x = f.get(null);
+                        if (k.isInstance(x))
+                            return k.cast(x);
+                    }
+                    throw new NoSuchFieldError("the Unsafe");
+                }});
+        } catch (java.security.PrivilegedActionException e) {
+            throw new RuntimeException("Could not initialize intrinsics",
+                                       e.getCause());
         }
     }
 }