--- jsr166/src/jsr166y/ForkJoinTask.java 2009/07/23 23:07:57 1.14 +++ jsr166/src/jsr166y/ForkJoinTask.java 2009/07/26 05:55:34 1.20 @@ -5,12 +5,15 @@ */ package jsr166y; -import java.io.Serializable; -import java.util.*; + import java.util.concurrent.*; -import java.util.concurrent.atomic.*; -import sun.misc.Unsafe; -import java.lang.reflect.*; + +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 @@ -489,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 this, to simplify usage. */ - public final void fork() { + public final ForkJoinTask fork() { ((ForkJoinWorkerThread) Thread.currentThread()) .pushTask(this); + return this; } /** @@ -600,14 +606,16 @@ 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) { - if (!(tasks instanceof List)) { + public static > Collection invokeAll(Collection tasks) { + if (!(tasks instanceof List)) { invokeAll(tasks.toArray(new ForkJoinTask[tasks.size()])); - return; + return tasks; } + @SuppressWarnings("unchecked") List> ts = (List>) tasks; Throwable ex = null; @@ -640,6 +648,7 @@ public abstract class ForkJoinTask im } if (ex != null) rethrowException(ex); + return tasks; } /** @@ -874,8 +883,8 @@ public abstract class ForkJoinTask im */ public static ForkJoinPool getPool() { Thread t = Thread.currentThread(); - return ((t instanceof ForkJoinWorkerThread) ? - ((ForkJoinWorkerThread) t).pool : null); + return (t instanceof ForkJoinWorkerThread) ? + ((ForkJoinWorkerThread) t).pool : null; } /** @@ -1030,6 +1039,46 @@ public abstract class ForkJoinTask im .pollTask(); } + // adaptors + + /** + * Returns a new ForkJoinTask that performs the run + * method of the given Runnable as its action, and returns a null + * result upon 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 run + * method of the given Runnable as its action, and returns the + * given result upon 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 call + * method of the given Callable as its action, and returns its + * result upon join, translating any checked + * exceptions encountered into 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; @@ -1062,46 +1111,45 @@ public abstract class ForkJoinTask im setDoneExceptionally((Throwable) ex); } - // Temporary Unsafe mechanics for preliminary release - private static Unsafe getUnsafe() throws Throwable { + // Unsafe mechanics for jsr166y 3rd party package. + private static sun.misc.Unsafe getUnsafe() { try { - return Unsafe.getUnsafe(); + return sun.misc.Unsafe.getUnsafe(); } catch (SecurityException se) { try { return java.security.AccessController.doPrivileged - (new java.security.PrivilegedExceptionAction() { - public Unsafe run() throws Exception { - return getUnsafePrivileged(); + (new java.security.PrivilegedExceptionAction() { + public sun.misc.Unsafe run() throws Exception { + return getUnsafeByReflection(); }}); } catch (java.security.PrivilegedActionException e) { - throw e.getCause(); + throw new RuntimeException("Could not initialize intrinsics", + e.getCause()); } } } - private static Unsafe getUnsafePrivileged() + private static sun.misc.Unsafe getUnsafeByReflection() throws NoSuchFieldException, IllegalAccessException { - Field f = Unsafe.class.getDeclaredField("theUnsafe"); + java.lang.reflect.Field f = + sun.misc.Unsafe.class.getDeclaredField("theUnsafe"); f.setAccessible(true); - return (Unsafe) f.get(null); - } - - private static long fieldOffset(String fieldName) - throws NoSuchFieldException { - return UNSAFE.objectFieldOffset - (ForkJoinTask.class.getDeclaredField(fieldName)); + return (sun.misc.Unsafe) f.get(null); } - static final Unsafe UNSAFE; - static final long statusOffset; - - static { + private static long fieldOffset(String fieldName, Class klazz) { try { - UNSAFE = getUnsafe(); - statusOffset = fieldOffset("status"); - } catch (Throwable e) { - throw new RuntimeException("Could not initialize intrinsics", e); + 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(); + private static final long statusOffset = + fieldOffset("status", ForkJoinTask.class); + }