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

Comparing jsr166/src/jsr166y/ForkJoinTask.java (file contents):
Revision 1.15 by jsr166, Fri Jul 24 22:05:22 2009 UTC vs.
Revision 1.23 by jsr166, Mon Jul 27 20:57:44 2009 UTC

# Line 5 | Line 5
5   */
6  
7   package jsr166y;
8 < import java.io.Serializable;
9 < import java.util.*;
8 >
9   import java.util.concurrent.*;
10 < import java.util.concurrent.atomic.*;
11 < import sun.misc.Unsafe;
12 < import java.lang.reflect.*;
10 >
11 > import java.io.Serializable;
12 > import java.util.Collection;
13 > import java.util.Collections;
14 > import java.util.List;
15 > import java.util.Map;
16 > import java.util.WeakHashMap;
17  
18   /**
19   * Abstract base class for tasks that run within a {@link
# Line 489 | Line 492 | public abstract class ForkJoinTask<V> im
492       * computations (as may be determined using method {@link
493       * #inForkJoinPool}). Attempts to invoke in other contexts result
494       * in exceptions or errors, possibly including ClassCastException.
495 +     *
496 +     * @return {@code this}, to simplify usage.
497       */
498 <    public final void fork() {
498 >    public final ForkJoinTask<V> fork() {
499          ((ForkJoinWorkerThread) Thread.currentThread())
500              .pushTask(this);
501 +        return this;
502      }
503  
504      /**
# Line 600 | Line 606 | public abstract class ForkJoinTask<V> im
606       * in exceptions or errors, possibly including ClassCastException.
607       *
608       * @param tasks the collection of tasks
609 +     * @return the tasks argument, to simplify usage
610       * @throws NullPointerException if tasks or any element are null
611       * @throws RuntimeException or Error if any task did so
612       */
613 <    public static void invokeAll(Collection<? extends ForkJoinTask<?>> tasks) {
613 >    public static <T extends ForkJoinTask<?>> Collection<T> invokeAll(Collection<T> tasks) {
614          if (!(tasks instanceof List<?>)) {
615              invokeAll(tasks.toArray(new ForkJoinTask<?>[tasks.size()]));
616 <            return;
616 >            return tasks;
617          }
618          @SuppressWarnings("unchecked")
619          List<? extends ForkJoinTask<?>> ts =
# Line 641 | Line 648 | public abstract class ForkJoinTask<V> im
648          }
649          if (ex != null)
650              rethrowException(ex);
651 +        return tasks;
652      }
653  
654      /**
655 <     * Returns true if the computation performed by this task has
656 <     * completed (or has been cancelled).
655 >     * Returns {@code true} if the computation performed by this task
656 >     * has completed (or has been cancelled).
657       *
658 <     * @return true if this computation has completed
658 >     * @return {@code true} if this computation has completed
659       */
660      public final boolean isDone() {
661          return status < 0;
662      }
663  
664      /**
665 <     * Returns true if this task was cancelled.
665 >     * Returns {@code true} if this task was cancelled.
666       *
667 <     * @return true if this task was cancelled
667 >     * @return {@code true} if this task was cancelled
668       */
669      public final boolean isCancelled() {
670          return (status & COMPLETION_MASK) == CANCELLED;
# Line 687 | Line 695 | public abstract class ForkJoinTask<V> im
695       * default implementation because tasks are not in general
696       * cancelled via interruption
697       *
698 <     * @return true if this task is now cancelled
698 >     * @return {@code true} if this task is now cancelled
699       */
700      public boolean cancel(boolean mayInterruptIfRunning) {
701          setCompletion(CANCELLED);
# Line 695 | Line 703 | public abstract class ForkJoinTask<V> im
703      }
704  
705      /**
706 <     * Returns true if this task threw an exception or was cancelled.
706 >     * Returns {@code true} if this task threw an exception or was cancelled.
707       *
708 <     * @return true if this task threw an exception or was cancelled
708 >     * @return {@code true} if this task threw an exception or was cancelled
709       */
710      public final boolean isCompletedAbnormally() {
711          return (status & COMPLETION_MASK) < NORMAL;
# Line 708 | Line 716 | public abstract class ForkJoinTask<V> im
716       * CancellationException if cancelled, or null if none or if the
717       * method has not yet completed.
718       *
719 <     * @return the exception, or null if none
719 >     * @return the exception, or {@code null} if none
720       */
721      public final Throwable getException() {
722          int s = status & COMPLETION_MASK;
# Line 871 | Line 879 | public abstract class ForkJoinTask<V> im
879       * Returns the pool hosting the current task execution, or null
880       * if this task is executing outside of any ForkJoinPool.
881       *
882 <     * @return the pool, or null if none
882 >     * @return the pool, or {@code null} if none
883       */
884      public static ForkJoinPool getPool() {
885          Thread t = Thread.currentThread();
# Line 902 | Line 910 | public abstract class ForkJoinTask<V> im
910       * result in exceptions or errors, possibly including
911       * ClassCastException.
912       *
913 <     * @return true if unforked
913 >     * @return {@code true} if unforked
914       */
915      public boolean tryUnfork() {
916          return ((ForkJoinWorkerThread) Thread.currentThread())
# Line 942 | Line 950 | public abstract class ForkJoinTask<V> im
950      // Extension methods
951  
952      /**
953 <     * Returns the result that would be returned by {@code join},
954 <     * even if this task completed abnormally, or null if this task is
955 <     * not known to have been completed.  This method is designed to
956 <     * aid debugging, as well as to support extensions. Its use in any
957 <     * other context is discouraged.
953 >     * Returns the result that would be returned by {@link #join}, even
954 >     * if this task completed abnormally, or {@code null} if this task
955 >     * is not known to have been completed.  This method is designed
956 >     * to aid debugging, as well as to support extensions. Its use in
957 >     * any other context is discouraged.
958       *
959 <     * @return the result, or null if not completed
959 >     * @return the result, or {@code null} if not completed
960       */
961      public abstract V getRawResult();
962  
# Line 967 | Line 975 | public abstract class ForkJoinTask<V> im
975       * called otherwise. The return value controls whether this task
976       * is considered to be done normally. It may return false in
977       * asynchronous actions that require explicit invocations of
978 <     * {@code complete} to become joinable. It may throw exceptions
978 >     * {@link #complete} to become joinable. It may throw exceptions
979       * to indicate abnormal exit.
980       *
981 <     * @return true if completed normally
981 >     * @return {@code true} if completed normally
982       * @throws Error or RuntimeException if encountered during computation
983       */
984      protected abstract boolean exec();
# Line 986 | Line 994 | public abstract class ForkJoinTask<V> im
994       * #inForkJoinPool}). Attempts to invoke in other contexts result
995       * in exceptions or errors, possibly including ClassCastException.
996       *
997 <     * @return the next task, or null if none are available
997 >     * @return the next task, or {@code null} if none are available
998       */
999      protected static ForkJoinTask<?> peekNextLocalTask() {
1000          return ((ForkJoinWorkerThread) Thread.currentThread())
# Line 1003 | Line 1011 | public abstract class ForkJoinTask<V> im
1011       * contexts result in exceptions or errors, possibly including
1012       * ClassCastException.
1013       *
1014 <     * @return the next task, or null if none are available
1014 >     * @return the next task, or {@code null} if none are available
1015       */
1016      protected static ForkJoinTask<?> pollNextLocalTask() {
1017          return ((ForkJoinWorkerThread) Thread.currentThread())
# Line 1024 | Line 1032 | public abstract class ForkJoinTask<V> im
1032       * result in exceptions or errors, possibly including
1033       * ClassCastException.
1034       *
1035 <     * @return a task, or null if none are available
1035 >     * @return a task, or {@code null} if none are available
1036       */
1037      protected static ForkJoinTask<?> pollTask() {
1038          return ((ForkJoinWorkerThread) Thread.currentThread())
1039              .pollTask();
1040      }
1041  
1042 +    // adaptors
1043 +
1044 +    /**
1045 +     * Returns a new ForkJoinTask that performs the {@code run}
1046 +     * method of the given Runnable as its action, and returns a null
1047 +     * result upon {@code join}.
1048 +     *
1049 +     * @param runnable the runnable action
1050 +     * @return the task
1051 +     */
1052 +    public static ForkJoinTask<Void> adapt(Runnable runnable) {
1053 +        return new ForkJoinPool.AdaptedRunnable<Void>(runnable, null);
1054 +    }
1055 +
1056 +    /**
1057 +     * Returns a new ForkJoinTask that performs the {@code run}
1058 +     * method of the given Runnable as its action, and returns the
1059 +     * given result upon {@code join}.
1060 +     *
1061 +     * @param runnable the runnable action
1062 +     * @param result the result upon completion
1063 +     * @return the task
1064 +     */
1065 +    public static <T> ForkJoinTask<T> adapt(Runnable runnable, T result) {
1066 +        return new ForkJoinPool.AdaptedRunnable<T>(runnable, result);
1067 +    }
1068 +
1069 +    /**
1070 +     * Returns a new ForkJoinTask that performs the {@code call}
1071 +     * method of the given Callable as its action, and returns its
1072 +     * result upon {@code join}, translating any checked
1073 +     * exceptions encountered into {@code RuntimeException}.
1074 +     *
1075 +     * @param callable the callable action
1076 +     * @return the task
1077 +     */
1078 +    public static <T> ForkJoinTask<T> adapt(Callable<T> callable) {
1079 +        return new ForkJoinPool.AdaptedCallable<T>(callable);
1080 +    }
1081 +
1082      // Serialization support
1083  
1084      private static final long serialVersionUID = -7721805057305804111L;
# Line 1039 | Line 1087 | public abstract class ForkJoinTask<V> im
1087       * Save the state to a stream.
1088       *
1089       * @serialData the current run status and the exception thrown
1090 <     * during execution, or null if none
1090 >     * during execution, or {@code null} if none
1091       * @param s the stream
1092       */
1093      private void writeObject(java.io.ObjectOutputStream s)
# Line 1063 | Line 1111 | public abstract class ForkJoinTask<V> im
1111              setDoneExceptionally((Throwable) ex);
1112      }
1113  
1114 <    // Temporary Unsafe mechanics for preliminary release
1115 <    private static Unsafe getUnsafe() throws Throwable {
1114 >    // Unsafe mechanics
1115 >
1116 >    private static final sun.misc.Unsafe UNSAFE = getUnsafe();
1117 >    private static final long statusOffset =
1118 >        objectFieldOffset("status", ForkJoinTask.class);
1119 >
1120 >    private static long objectFieldOffset(String field, Class<?> klazz) {
1121 >        try {
1122 >            return UNSAFE.objectFieldOffset(klazz.getDeclaredField(field));
1123 >        } catch (NoSuchFieldException e) {
1124 >            // Convert Exception to corresponding Error
1125 >            NoSuchFieldError error = new NoSuchFieldError(field);
1126 >            error.initCause(e);
1127 >            throw error;
1128 >        }
1129 >    }
1130 >
1131 >    /**
1132 >     * Returns a sun.misc.Unsafe.  Suitable for use in a 3rd party package.
1133 >     * Replace with a simple call to Unsafe.getUnsafe when integrating
1134 >     * into a jdk.
1135 >     *
1136 >     * @return a sun.misc.Unsafe
1137 >     */
1138 >    private static sun.misc.Unsafe getUnsafe() {
1139          try {
1140 <            return Unsafe.getUnsafe();
1140 >            return sun.misc.Unsafe.getUnsafe();
1141          } catch (SecurityException se) {
1142              try {
1143                  return java.security.AccessController.doPrivileged
1144 <                    (new java.security.PrivilegedExceptionAction<Unsafe>() {
1145 <                        public Unsafe run() throws Exception {
1146 <                            return getUnsafePrivileged();
1144 >                    (new java.security
1145 >                     .PrivilegedExceptionAction<sun.misc.Unsafe>() {
1146 >                        public sun.misc.Unsafe run() throws Exception {
1147 >                            java.lang.reflect.Field f = sun.misc
1148 >                                .Unsafe.class.getDeclaredField("theUnsafe");
1149 >                            f.setAccessible(true);
1150 >                            return (sun.misc.Unsafe) f.get(null);
1151                          }});
1152              } catch (java.security.PrivilegedActionException e) {
1153 <                throw e.getCause();
1153 >                throw new RuntimeException("Could not initialize intrinsics",
1154 >                                           e.getCause());
1155              }
1156          }
1157      }
1082
1083    private static Unsafe getUnsafePrivileged()
1084            throws NoSuchFieldException, IllegalAccessException {
1085        Field f = Unsafe.class.getDeclaredField("theUnsafe");
1086        f.setAccessible(true);
1087        return (Unsafe) f.get(null);
1088    }
1089
1090    private static long fieldOffset(String fieldName)
1091            throws NoSuchFieldException {
1092        return UNSAFE.objectFieldOffset
1093            (ForkJoinTask.class.getDeclaredField(fieldName));
1094    }
1095
1096    static final Unsafe UNSAFE;
1097    static final long statusOffset;
1098
1099    static {
1100        try {
1101            UNSAFE = getUnsafe();
1102            statusOffset = fieldOffset("status");
1103        } catch (Throwable e) {
1104            throw new RuntimeException("Could not initialize intrinsics", e);
1105        }
1106    }
1107
1158   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines