src/java.base/share/classes/java/util/concurrent/ForkJoinWorkerThread.java

Print this page
rev 12972 : 8140606: Update library code to use internal Unsafe
Reviewed-by: duke


 168                 }
 169             }
 170         }
 171     }
 172 
 173     /**
 174      * Erases ThreadLocals by nulling out Thread maps.
 175      */
 176     final void eraseThreadLocals() {
 177         U.putObject(this, THREADLOCALS, null);
 178         U.putObject(this, INHERITABLETHREADLOCALS, null);
 179     }
 180 
 181     /**
 182      * Non-public hook method for InnocuousForkJoinWorkerThread.
 183      */
 184     void afterTopLevelExec() {
 185     }
 186 
 187     // Set up to allow setting thread fields in constructor
 188     private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
 189     private static final long THREADLOCALS;
 190     private static final long INHERITABLETHREADLOCALS;
 191     private static final long INHERITEDACCESSCONTROLCONTEXT;
 192     static {
 193         try {
 194             THREADLOCALS = U.objectFieldOffset
 195                 (Thread.class.getDeclaredField("threadLocals"));
 196             INHERITABLETHREADLOCALS = U.objectFieldOffset
 197                 (Thread.class.getDeclaredField("inheritableThreadLocals"));
 198             INHERITEDACCESSCONTROLCONTEXT = U.objectFieldOffset
 199                 (Thread.class.getDeclaredField("inheritedAccessControlContext"));
 200         } catch (ReflectiveOperationException e) {
 201             throw new Error(e);
 202         }
 203     }
 204 
 205     /**
 206      * A worker thread that has no permissions, is not a member of any
 207      * user-defined ThreadGroup, and erases all ThreadLocals after
 208      * running each top-level task.


 231         @Override // to always report system loader
 232         public ClassLoader getContextClassLoader() {
 233             return ClassLoader.getSystemClassLoader();
 234         }
 235 
 236         @Override // to silently fail
 237         public void setUncaughtExceptionHandler(UncaughtExceptionHandler x) { }
 238 
 239         @Override // paranoically
 240         public void setContextClassLoader(ClassLoader cl) {
 241             throw new SecurityException("setContextClassLoader");
 242         }
 243 
 244         /**
 245          * Returns a new group with the system ThreadGroup (the
 246          * topmost, parent-less group) as parent.  Uses Unsafe to
 247          * traverse Thread.group and ThreadGroup.parent fields.
 248          */
 249         private static ThreadGroup createThreadGroup() {
 250             try {
 251                 sun.misc.Unsafe u = sun.misc.Unsafe.getUnsafe();
 252                 long tg = u.objectFieldOffset
 253                     (Thread.class.getDeclaredField("group"));
 254                 long gp = u.objectFieldOffset
 255                     (ThreadGroup.class.getDeclaredField("parent"));
 256                 ThreadGroup group = (ThreadGroup)
 257                     u.getObject(Thread.currentThread(), tg);
 258                 while (group != null) {
 259                     ThreadGroup parent = (ThreadGroup)u.getObject(group, gp);
 260                     if (parent == null)
 261                         return new ThreadGroup(group,
 262                                                "InnocuousForkJoinWorkerThreadGroup");
 263                     group = parent;
 264                 }
 265             } catch (ReflectiveOperationException e) {
 266                 throw new Error(e);
 267             }
 268             // fall through if null as cannot-happen safeguard
 269             throw new Error("Cannot create ThreadGroup");
 270         }
 271     }


 168                 }
 169             }
 170         }
 171     }
 172 
 173     /**
 174      * Erases ThreadLocals by nulling out Thread maps.
 175      */
 176     final void eraseThreadLocals() {
 177         U.putObject(this, THREADLOCALS, null);
 178         U.putObject(this, INHERITABLETHREADLOCALS, null);
 179     }
 180 
 181     /**
 182      * Non-public hook method for InnocuousForkJoinWorkerThread.
 183      */
 184     void afterTopLevelExec() {
 185     }
 186 
 187     // Set up to allow setting thread fields in constructor
 188     private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
 189     private static final long THREADLOCALS;
 190     private static final long INHERITABLETHREADLOCALS;
 191     private static final long INHERITEDACCESSCONTROLCONTEXT;
 192     static {
 193         try {
 194             THREADLOCALS = U.objectFieldOffset
 195                 (Thread.class.getDeclaredField("threadLocals"));
 196             INHERITABLETHREADLOCALS = U.objectFieldOffset
 197                 (Thread.class.getDeclaredField("inheritableThreadLocals"));
 198             INHERITEDACCESSCONTROLCONTEXT = U.objectFieldOffset
 199                 (Thread.class.getDeclaredField("inheritedAccessControlContext"));
 200         } catch (ReflectiveOperationException e) {
 201             throw new Error(e);
 202         }
 203     }
 204 
 205     /**
 206      * A worker thread that has no permissions, is not a member of any
 207      * user-defined ThreadGroup, and erases all ThreadLocals after
 208      * running each top-level task.


 231         @Override // to always report system loader
 232         public ClassLoader getContextClassLoader() {
 233             return ClassLoader.getSystemClassLoader();
 234         }
 235 
 236         @Override // to silently fail
 237         public void setUncaughtExceptionHandler(UncaughtExceptionHandler x) { }
 238 
 239         @Override // paranoically
 240         public void setContextClassLoader(ClassLoader cl) {
 241             throw new SecurityException("setContextClassLoader");
 242         }
 243 
 244         /**
 245          * Returns a new group with the system ThreadGroup (the
 246          * topmost, parent-less group) as parent.  Uses Unsafe to
 247          * traverse Thread.group and ThreadGroup.parent fields.
 248          */
 249         private static ThreadGroup createThreadGroup() {
 250             try {
 251                 jdk.internal.misc.Unsafe u = jdk.internal.misc.Unsafe.getUnsafe();
 252                 long tg = u.objectFieldOffset
 253                     (Thread.class.getDeclaredField("group"));
 254                 long gp = u.objectFieldOffset
 255                     (ThreadGroup.class.getDeclaredField("parent"));
 256                 ThreadGroup group = (ThreadGroup)
 257                     u.getObject(Thread.currentThread(), tg);
 258                 while (group != null) {
 259                     ThreadGroup parent = (ThreadGroup)u.getObject(group, gp);
 260                     if (parent == null)
 261                         return new ThreadGroup(group,
 262                                                "InnocuousForkJoinWorkerThreadGroup");
 263                     group = parent;
 264                 }
 265             } catch (ReflectiveOperationException e) {
 266                 throw new Error(e);
 267             }
 268             // fall through if null as cannot-happen safeguard
 269             throw new Error("Cannot create ThreadGroup");
 270         }
 271     }