content: /*
   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   *
   * This code is free software; you can redistribute it and/or modify it
   * under the terms of the GNU General Public License version 2 only, as
   * published by the Free Software Foundation.  Oracle designates this
   * particular file as subject to the "Classpath" exception as provided
   * by Oracle in the LICENSE file that accompanied this code.
   *
   * This code is distributed in the hope that it will be useful, but WITHOUT
   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   * version 2 for more details (a copy is included in the LICENSE file that
   * accompanied this code).
   *
   * You should have received a copy of the GNU General Public License version
   * 2 along with this work; if not, write to the Free Software Foundation,
   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   *
   * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   * or visit www.oracle.com if you need additional information or have any
   * questions.
   */
  
  /*
   * This file is available under and governed by the GNU General Public
   * License version 2 only, as published by the Free Software Foundation.
   * However, the following notice accompanied the original version of this
   * file:
   *
   * Written by Doug Lea with assistance from members of JCP JSR-166
   * Expert Group and released to the public domain, as explained at
   * http://creativecommons.org/publicdomain/zero/1.0/
   */
  
  package java.util.concurrent;
  
  import java.security.AccessControlContext;
  import java.security.ProtectionDomain;
  
  /**
   * A thread managed by a {@link ForkJoinPool}, which executes
   * {@link ForkJoinTask}s.
   * This class is subclassable solely for the sake of adding
   * functionality -- there are no overridable methods dealing with
   * scheduling or execution.  However, you can override initialization
   * and termination methods surrounding the main task processing loop.
   * If you do create such a subclass, you will also need to supply a
   * custom {@link ForkJoinPool.ForkJoinWorkerThreadFactory} to
   * {@linkplain ForkJoinPool#ForkJoinPool use it} in a {@code ForkJoinPool}.
   *
   * @since 1.7
   * @author Doug Lea
   */
  public class ForkJoinWorkerThread extends Thread {
      /*
       * ForkJoinWorkerThreads are managed by ForkJoinPools and perform
       * ForkJoinTasks. For explanation, see the internal documentation
       * of class ForkJoinPool.
       *
       * This class just maintains links to its pool and WorkQueue.  The
       * pool field is set immediately upon construction, but the
       * workQueue field is not set until a call to registerWorker
       * completes. This leads to a visibility race, that is tolerated
       * by requiring that the workQueue field is only accessed by the
       * owning thread.
       *
       * Support for (non-public) subclass InnocuousForkJoinWorkerThread
       * requires that we break quite a lot of encapsulation (via Unsafe)
       * both here and in the subclass to access and set Thread fields.
       */
  
      final ForkJoinPool pool;                // the pool this thread works in
      final ForkJoinPool.WorkQueue workQueue; // work-stealing mechanics
  
      /**
       * Creates a ForkJoinWorkerThread operating in the given pool.
       *
       * @param pool the pool this thread works in
       * @throws NullPointerException if pool is null
       */
      protected ForkJoinWorkerThread(ForkJoinPool pool) {
          // Use a placeholder until a useful name can be set in registerWorker
          super("aForkJoinWorkerThread");
          this.pool = pool;
          this.workQueue = pool.registerWorker(this);
      }
  
      /**
       * Version for InnocuousForkJoinWorkerThread.
       */
      ForkJoinWorkerThread(ForkJoinPool pool, ThreadGroup threadGroup,
                           AccessControlContext acc) {
          super(threadGroup, null, "aForkJoinWorkerThread");
          U.putOrderedObject(this, INHERITEDACCESSCONTROLCONTEXT, acc);
          eraseThreadLocals(); // clear before registering
          this.pool = pool;
          this.workQueue = pool.registerWorker(this);
      }
  
      /**
       * Returns the pool hosting this thread.
       *
       * @return the pool
       */
      public ForkJoinPool getPool() {
          return pool;
      }
  
      /**
       * Returns the unique index number of this thread in its pool.
       * The returned value ranges from zero to the maximum number of
       * threads (minus one) that may exist in the pool, and does not
       * change during the lifetime of the thread.  This method may be
       * useful for applications that track status or collect results
       * per-worker-thread rather than per-task.
       *
       * @return the index number
       */
      public int getPoolIndex() {
          return workQueue.getPoolIndex();
      }
  
      /**
       * Initializes internal state after construction but before
       * processing any tasks. If you override this method, you must
       * invoke {@code super.onStart()} at the beginning of the method.
       * Initialization requires care: Most fields must have legal
       * default values, to ensure that attempted accesses from other
       * threads work correctly even before this thread starts
       * processing tasks.
       */
      protected void onStart() {
      }
  
      /**
       * Performs cleanup associated with termination of this worker
       * thread.  If you override this method, you must invoke
       * {@code super.onTermination} at the end of the overridden method.
       *
       * @param exception the exception causing this thread to abort due
       * to an unrecoverable error, or {@code null} if completed normally
       */
      protected void onTermination(Throwable exception) {
      }
  
      /**
       * This method is required to be public, but should never be
       * called explicitly. It performs the main run loop to execute
       * {@link ForkJoinTask}s.
       */
      public void run() {
          if (workQueue.array == null) { // only run once
              Throwable exception = null;
              try {
                  onStart();
                  pool.runWorker(workQueue);
              } catch (Throwable ex) {
                  exception = ex;
              } finally {
                  try {
                      onTermination(exception);
                  } catch (Throwable ex) {
                      if (exception == null)
                          exception = ex;
                  } finally {
                      pool.deregisterWorker(this, exception);
                  }
              }
          }
      }
  
      /**
       * Erases ThreadLocals by nulling out Thread maps.
       */
      final void eraseThreadLocals() {
          U.putObject(this, THREADLOCALS, null);
          U.putObject(this, INHERITABLETHREADLOCALS, null);
      }
  
      /**
       * Non-public hook method for InnocuousForkJoinWorkerThread.
       */
      void afterTopLevelExec() {
      }
  
      // Set up to allow setting thread fields in constructor
      private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
      private static final long THREADLOCALS;
      private static final long INHERITABLETHREADLOCALS;
      private static final long INHERITEDACCESSCONTROLCONTEXT;
      static {
          try {
              THREADLOCALS = U.objectFieldOffset
                  (Thread.class.getDeclaredField("threadLocals"));
              INHERITABLETHREADLOCALS = U.objectFieldOffset
                  (Thread.class.getDeclaredField("inheritableThreadLocals"));
              INHERITEDACCESSCONTROLCONTEXT = U.objectFieldOffset
                  (Thread.class.getDeclaredField("inheritedAccessControlContext"));
          } catch (ReflectiveOperationException e) {
              throw new Error(e);
          }
      }
  
      /**
       * A worker thread that has no permissions, is not a member of any
       * user-defined ThreadGroup, and erases all ThreadLocals after
       * running each top-level task.
       */
      static final class InnocuousForkJoinWorkerThread extends ForkJoinWorkerThread {
          /** The ThreadGroup for all InnocuousForkJoinWorkerThreads */
          private static final ThreadGroup innocuousThreadGroup =
              createThreadGroup();
  
          /** An AccessControlContext supporting no privileges */
          private static final AccessControlContext INNOCUOUS_ACC =
              new AccessControlContext(
                  new ProtectionDomain[] {
                      new ProtectionDomain(null, null)
                  });
  
          InnocuousForkJoinWorkerThread(ForkJoinPool pool) {
              super(pool, innocuousThreadGroup, INNOCUOUS_ACC);
          }
  
          @Override // to erase ThreadLocals
          void afterTopLevelExec() {
              eraseThreadLocals();
          }
  
          @Override // to always report system loader
          public ClassLoader getContextClassLoader() {
              return ClassLoader.getSystemClassLoader();
          }
  
          @Override // to silently fail
          public void setUncaughtExceptionHandler(UncaughtExceptionHandler x) { }
  
          @Override // paranoically
          public void setContextClassLoader(ClassLoader cl) {
              throw new SecurityException("setContextClassLoader");
          }
  
          /**
           * Returns a new group with the system ThreadGroup (the
           * topmost, parent-less group) as parent.  Uses Unsafe to
           * traverse Thread.group and ThreadGroup.parent fields.
           */
          private static ThreadGroup createThreadGroup() {
              try {
                  sun.misc.Unsafe u = sun.misc.Unsafe.getUnsafe();
                  long tg = u.objectFieldOffset
                      (Thread.class.getDeclaredField("group"));
                  long gp = u.objectFieldOffset
                      (ThreadGroup.class.getDeclaredField("parent"));
                  ThreadGroup group = (ThreadGroup)
                      u.getObject(Thread.currentThread(), tg);
                  while (group != null) {
                      ThreadGroup parent = (ThreadGroup)u.getObject(group, gp);
                      if (parent == null)
                          return new ThreadGroup(group,
                                                 "InnocuousForkJoinWorkerThreadGroup");
                      group = parent;
                  }
              } catch (ReflectiveOperationException e) {
                  throw new Error(e);
              }
              // fall through if null as cannot-happen safeguard
              throw new Error("Cannot create ThreadGroup");
          }
      }
  
  }
  