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.94 by dl, Mon Nov 19 18:12:42 2012 UTC vs.
Revision 1.102 by jsr166, Thu Sep 3 22:54:46 2015 UTC

# Line 55 | Line 55 | import java.lang.reflect.Constructor;
55   * minimize other blocking synchronization apart from joining other
56   * tasks or using synchronizers such as Phasers that are advertised to
57   * cooperate with fork/join scheduling. Subdividable tasks should also
58 < * not perform blocking IO, and should ideally access variables that
58 > * not perform blocking I/O, and should ideally access variables that
59   * are completely independent of those accessed by other running
60   * tasks. These guidelines are loosely enforced by not permitting
61   * checked exceptions such as {@code IOExceptions} to be
# Line 73 | Line 73 | import java.lang.reflect.Constructor;
73   * <p>It is possible to define and use ForkJoinTasks that may block,
74   * but doing do requires three further considerations: (1) Completion
75   * of few if any <em>other</em> tasks should be dependent on a task
76 < * that blocks on external synchronization or IO. Event-style async
76 > * that blocks on external synchronization or I/O. Event-style async
77   * tasks that are never joined (for example, those subclassing {@link
78   * CountedCompleter}) often fall into this category.  (2) To minimize
79   * resource impact, tasks should be small; ideally performing only the
# Line 395 | Line 395 | public abstract class ForkJoinTask<V> im
395          final Throwable ex;
396          ExceptionNode next;
397          final long thrower;  // use id not ref to avoid weak cycles
398 +        final int hashCode;  // store task hashCode before weak ref disappears
399          ExceptionNode(ForkJoinTask<?> task, Throwable ex, ExceptionNode next) {
400              super(task, exceptionTableRefQueue);
401              this.ex = ex;
402              this.next = next;
403              this.thrower = Thread.currentThread().getId();
404 +            this.hashCode = System.identityHashCode(task);
405          }
406      }
407  
# Line 435 | Line 437 | public abstract class ForkJoinTask<V> im
437      }
438  
439      /**
440 <     * Records exception and possibly propagates
440 >     * Records exception and possibly propagates.
441       *
442       * @return status on exit
443       */
# Line 468 | Line 470 | public abstract class ForkJoinTask<V> im
470      }
471  
472      /**
473 <     * Removes exception node and clears status
473 >     * Removes exception node and clears status.
474       */
475      private void clearExceptionalCompletion() {
476          int h = System.identityHashCode(this);
# Line 561 | Line 563 | public abstract class ForkJoinTask<V> im
563      private static void expungeStaleExceptions() {
564          for (Object x; (x = exceptionTableRefQueue.poll()) != null;) {
565              if (x instanceof ExceptionNode) {
566 <                ForkJoinTask<?> key = ((ExceptionNode)x).get();
566 >                int hashCode = ((ExceptionNode)x).hashCode;
567                  ExceptionNode[] t = exceptionTable;
568 <                int i = System.identityHashCode(key) & (t.length - 1);
568 >                int i = hashCode & (t.length - 1);
569                  ExceptionNode e = t[i];
570                  ExceptionNode pred = null;
571                  while (e != null) {
# Line 606 | Line 608 | public abstract class ForkJoinTask<V> im
608                  throw (Error)ex;
609              if (ex instanceof RuntimeException)
610                  throw (RuntimeException)ex;
611 <            throw uncheckedThrowable(ex, RuntimeException.class);
611 >            ForkJoinTask.<RuntimeException>uncheckedThrow(ex);
612          }
613      }
614  
# Line 616 | Line 618 | public abstract class ForkJoinTask<V> im
618       * unchecked exceptions
619       */
620      @SuppressWarnings("unchecked") static <T extends Throwable>
621 <        T uncheckedThrowable(final Throwable t, final Class<T> c) {
622 <        return (T)t; // rely on vacuous cast
621 >        void uncheckedThrow(Throwable t) throws T {
622 >        if (t != null)
623 >            throw (T)t; // rely on vacuous cast
624      }
625  
626      /**
# Line 652 | Line 655 | public abstract class ForkJoinTask<V> im
655          if ((t = Thread.currentThread()) instanceof ForkJoinWorkerThread)
656              ((ForkJoinWorkerThread)t).workQueue.push(this);
657          else
658 <            ForkJoinPool.commonPool.externalPush(this);
658 >            ForkJoinPool.common.externalPush(this);
659          return this;
660      }
661  
# Line 978 | Line 981 | public abstract class ForkJoinTask<V> im
981          if (Thread.interrupted())
982              throw new InterruptedException();
983          // Messy in part because we measure in nanosecs, but wait in millisecs
984 <        int s; long ns, ms;
985 <        if ((s = status) >= 0 && (ns = unit.toNanos(timeout)) > 0L) {
984 >        int s; long ms;
985 >        long ns = unit.toNanos(timeout);
986 >        if ((s = status) >= 0 && ns > 0L) {
987              long deadline = System.nanoTime() + ns;
988              ForkJoinPool p = null;
989              ForkJoinPool.WorkQueue w = null;
# Line 1075 | Line 1079 | public abstract class ForkJoinTask<V> im
1079              wt.pool.helpQuiescePool(wt.workQueue);
1080          }
1081          else
1082 <            ForkJoinPool.externalHelpQuiescePool();
1082 >            ForkJoinPool.quiesceCommonPool();
1083      }
1084  
1085      /**
# Line 1324 | Line 1328 | public abstract class ForkJoinTask<V> im
1328      }
1329  
1330      /**
1331 <     * Adaptor for Runnables. This implements RunnableFuture
1331 >     * Adapter for Runnables. This implements RunnableFuture
1332       * to be compliant with AbstractExecutorService constraints
1333       * when used in ForkJoinPool.
1334       */
# Line 1345 | Line 1349 | public abstract class ForkJoinTask<V> im
1349      }
1350  
1351      /**
1352 <     * Adaptor for Runnables without results
1352 >     * Adapter for Runnables without results
1353       */
1354      static final class AdaptedRunnableAction extends ForkJoinTask<Void>
1355          implements RunnableFuture<Void> {
# Line 1362 | Line 1366 | public abstract class ForkJoinTask<V> im
1366      }
1367  
1368      /**
1369 <     * Adaptor for Callables
1369 >     * Adapter for Callables
1370       */
1371      static final class AdaptedCallable<T> extends ForkJoinTask<T>
1372          implements RunnableFuture<T> {
# Line 1483 | Line 1487 | public abstract class ForkJoinTask<V> im
1487      private static sun.misc.Unsafe getUnsafe() {
1488          try {
1489              return sun.misc.Unsafe.getUnsafe();
1490 <        } catch (SecurityException se) {
1491 <            try {
1492 <                return java.security.AccessController.doPrivileged
1493 <                    (new java.security
1494 <                     .PrivilegedExceptionAction<sun.misc.Unsafe>() {
1495 <                        public sun.misc.Unsafe run() throws Exception {
1496 <                            java.lang.reflect.Field f = sun.misc
1497 <                                .Unsafe.class.getDeclaredField("theUnsafe");
1498 <                            f.setAccessible(true);
1499 <                            return (sun.misc.Unsafe) f.get(null);
1500 <                        }});
1501 <            } catch (java.security.PrivilegedActionException e) {
1502 <                throw new RuntimeException("Could not initialize intrinsics",
1503 <                                           e.getCause());
1504 <            }
1490 >        } catch (SecurityException tryReflectionInstead) {}
1491 >        try {
1492 >            return java.security.AccessController.doPrivileged
1493 >            (new java.security.PrivilegedExceptionAction<sun.misc.Unsafe>() {
1494 >                public sun.misc.Unsafe run() throws Exception {
1495 >                    Class<sun.misc.Unsafe> k = sun.misc.Unsafe.class;
1496 >                    for (java.lang.reflect.Field f : k.getDeclaredFields()) {
1497 >                        f.setAccessible(true);
1498 >                        Object x = f.get(null);
1499 >                        if (k.isInstance(x))
1500 >                            return k.cast(x);
1501 >                    }
1502 >                    throw new NoSuchFieldError("the Unsafe");
1503 >                }});
1504 >        } catch (java.security.PrivilegedActionException e) {
1505 >            throw new RuntimeException("Could not initialize intrinsics",
1506 >                                       e.getCause());
1507          }
1508      }
1509   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines