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 }
|