--- jsr166/src/jsr166y/ForkJoinTask.java 2009/07/24 23:47:01 1.16 +++ jsr166/src/jsr166y/ForkJoinTask.java 2009/07/26 17:33:37 1.22 @@ -5,10 +5,15 @@ */ package jsr166y; -import java.io.Serializable; -import java.util.*; + import java.util.concurrent.*; -import java.util.concurrent.atomic.*; + +import java.io.Serializable; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.WeakHashMap; /** * Abstract base class for tasks that run within a {@link @@ -487,10 +492,13 @@ public abstract class ForkJoinTask im * computations (as may be determined using method {@link * #inForkJoinPool}). Attempts to invoke in other contexts result * in exceptions or errors, possibly including ClassCastException. + * + * @return {@code this}, to simplify usage. */ - public final void fork() { + public final ForkJoinTask fork() { ((ForkJoinWorkerThread) Thread.currentThread()) .pushTask(this); + return this; } /** @@ -598,13 +606,14 @@ public abstract class ForkJoinTask im * in exceptions or errors, possibly including ClassCastException. * * @param tasks the collection of tasks + * @return the tasks argument, to simplify usage * @throws NullPointerException if tasks or any element are null * @throws RuntimeException or Error if any task did so */ - public static void invokeAll(Collection> tasks) { + public static > Collection invokeAll(Collection tasks) { if (!(tasks instanceof List)) { invokeAll(tasks.toArray(new ForkJoinTask[tasks.size()])); - return; + return tasks; } @SuppressWarnings("unchecked") List> ts = @@ -639,6 +648,7 @@ public abstract class ForkJoinTask im } if (ex != null) rethrowException(ex); + return tasks; } /** @@ -1029,6 +1039,46 @@ public abstract class ForkJoinTask im .pollTask(); } + // adaptors + + /** + * Returns a new ForkJoinTask that performs the {@code run} + * method of the given Runnable as its action, and returns a null + * result upon {@code join}. + * + * @param runnable the runnable action + * @return the task + */ + public static ForkJoinTask adapt(Runnable runnable) { + return new ForkJoinPool.AdaptedRunnable(runnable, null); + } + + /** + * Returns a new ForkJoinTask that performs the {@code run} + * method of the given Runnable as its action, and returns the + * given result upon {@code join}. + * + * @param runnable the runnable action + * @param result the result upon completion + * @return the task + */ + public static ForkJoinTask adapt(Runnable runnable, T result) { + return new ForkJoinPool.AdaptedRunnable(runnable, result); + } + + /** + * Returns a new ForkJoinTask that performs the {@code call} + * method of the given Callable as its action, and returns its + * result upon {@code join}, translating any checked + * exceptions encountered into {@code RuntimeException}. + * + * @param callable the callable action + * @return the task + */ + public static ForkJoinTask adapt(Callable callable) { + return new ForkJoinPool.AdaptedCallable(callable); + } + // Serialization support private static final long serialVersionUID = -7721805057305804111L; @@ -1061,16 +1111,43 @@ public abstract class ForkJoinTask im setDoneExceptionally((Throwable) ex); } - // Unsafe mechanics for jsr166y 3rd party package. + // Unsafe mechanics + + private static final sun.misc.Unsafe UNSAFE = getUnsafe(); + private static final long statusOffset = + objectFieldOffset("status", ForkJoinTask.class); + + private static long objectFieldOffset(String field, Class klazz) { + try { + return UNSAFE.objectFieldOffset(klazz.getDeclaredField(field)); + } catch (NoSuchFieldException e) { + // Convert Exception to corresponding Error + NoSuchFieldError error = new NoSuchFieldError(field); + error.initCause(e); + throw error; + } + } + + /** + * Returns a sun.misc.Unsafe. Suitable for use in a 3rd party package. + * Replace with a simple call to Unsafe.getUnsafe when integrating + * into a jdk. + * + * @return a sun.misc.Unsafe + */ private static sun.misc.Unsafe getUnsafe() { try { return sun.misc.Unsafe.getUnsafe(); } catch (SecurityException se) { try { return java.security.AccessController.doPrivileged - (new java.security.PrivilegedExceptionAction() { + (new java.security + .PrivilegedExceptionAction() { public sun.misc.Unsafe run() throws Exception { - return getUnsafeByReflection(); + 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", @@ -1078,28 +1155,4 @@ public abstract class ForkJoinTask im } } } - - private static sun.misc.Unsafe getUnsafeByReflection() - throws NoSuchFieldException, IllegalAccessException { - java.lang.reflect.Field f = - sun.misc.Unsafe.class.getDeclaredField("theUnsafe"); - f.setAccessible(true); - return (sun.misc.Unsafe) f.get(null); - } - - private static long fieldOffset(String fieldName, Class klazz) { - try { - return UNSAFE.objectFieldOffset(klazz.getDeclaredField(fieldName)); - } catch (NoSuchFieldException e) { - // Convert Exception to Error - NoSuchFieldError error = new NoSuchFieldError(fieldName); - error.initCause(e); - throw error; - } - } - - private static final sun.misc.Unsafe UNSAFE = getUnsafe(); - static final long statusOffset = - fieldOffset("status", ForkJoinTask.class); - }