8048210: More Enhancements to InnocuousThread and friends
Reviewed-by: alanb, pchelko, jbachorik
--- a/jdk/src/java.base/share/classes/sun/misc/InnocuousThread.java Wed Jun 18 10:44:24 2014 +0100
+++ b/jdk/src/java.base/share/classes/sun/misc/InnocuousThread.java Thu Jun 26 14:49:23 2014 +0100
@@ -34,16 +34,13 @@
/**
* A thread that has no permissions, is not a member of any user-defined
* ThreadGroup and supports the ability to erase ThreadLocals.
- *
- * @implNote Based on the implementation of InnocuousForkJoinWorkerThread.
*/
-public final class InnocuousThread extends Thread {
+public final class InnocuousThread extends ManagedLocalsThread {
private static final Unsafe UNSAFE;
private static final ThreadGroup INNOCUOUSTHREADGROUP;
private static final AccessControlContext ACC;
- private static final long THREADLOCALS;
- private static final long INHERITABLETHREADLOCALS;
private static final long INHERITEDACCESSCONTROLCONTEXT;
+ private static final long CONTEXTCLASSLOADER;
private static final AtomicInteger threadNumber = new AtomicInteger(1);
@@ -56,18 +53,10 @@
this(INNOCUOUSTHREADGROUP, target, name);
}
- private InnocuousThread(ThreadGroup group, Runnable target, String name) {
+ public InnocuousThread(ThreadGroup group, Runnable target, String name) {
super(group, target, name);
UNSAFE.putOrderedObject(this, INHERITEDACCESSCONTROLCONTEXT, ACC);
- eraseThreadLocals();
- }
-
- // always report system class loader, or null
- private ClassLoader contextClassLoader = ClassLoader.getSystemClassLoader();
-
- @Override
- public ClassLoader getContextClassLoader() {
- return contextClassLoader;
+ UNSAFE.putOrderedObject(this, CONTEXTCLASSLOADER, ClassLoader.getSystemClassLoader());
}
@Override
@@ -77,8 +66,9 @@
@Override
public void setContextClassLoader(ClassLoader cl) {
+ // Allow clearing of the TCCL to remove the reference to the system classloader.
if (cl == null)
- contextClassLoader = null;
+ super.setContextClassLoader(null);
else
throw new SecurityException("setContextClassLoader");
}
@@ -94,14 +84,6 @@
}
}
- /**
- * Drops all thread locals (and inherited thread locals).
- */
- public void eraseThreadLocals() {
- UNSAFE.putObject(this, THREADLOCALS, null);
- UNSAFE.putObject(this, INHERITABLETHREADLOCALS, null);
- }
-
// Use Unsafe to access Thread group and ThreadGroup parent fields
static {
try {
@@ -114,12 +96,10 @@
Class<?> tk = Thread.class;
Class<?> gk = ThreadGroup.class;
- THREADLOCALS = UNSAFE.objectFieldOffset
- (tk.getDeclaredField("threadLocals"));
- INHERITABLETHREADLOCALS = UNSAFE.objectFieldOffset
- (tk.getDeclaredField("inheritableThreadLocals"));
INHERITEDACCESSCONTROLCONTEXT = UNSAFE.objectFieldOffset
(tk.getDeclaredField("inheritedAccessControlContext"));
+ CONTEXTCLASSLOADER = UNSAFE.objectFieldOffset
+ (tk.getDeclaredField("contextClassLoader"));
long tg = UNSAFE.objectFieldOffset(tk.getDeclaredField("group"));
long gp = UNSAFE.objectFieldOffset(gk.getDeclaredField("parent"));
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/sun/misc/ManagedLocalsThread.java Thu Jun 26 14:49:23 2014 +0100
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * 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.
+ */
+
+package sun.misc;
+
+/**
+ * A thread that has it's thread locals, and inheritable thread
+ * locals erased on construction.
+ */
+public class ManagedLocalsThread extends Thread {
+ private static final Unsafe UNSAFE;
+ private static final long THREAD_LOCALS;
+ private static final long INHERITABLE_THREAD_LOCALS;
+
+ public ManagedLocalsThread(Runnable target) {
+ super(target);
+ eraseThreadLocals();
+ }
+
+ public ManagedLocalsThread(Runnable target, String name) {
+ super(target, name);
+ eraseThreadLocals();
+ }
+
+ public ManagedLocalsThread(ThreadGroup group, Runnable target, String name) {
+ super(group, target, name);
+ eraseThreadLocals();
+ }
+
+ /**
+ * Drops all thread locals (and inherited thread locals).
+ */
+ public final void eraseThreadLocals() {
+ UNSAFE.putObject(this, THREAD_LOCALS, null);
+ UNSAFE.putObject(this, INHERITABLE_THREAD_LOCALS, null);
+ }
+
+ static {
+ UNSAFE = Unsafe.getUnsafe();
+ Class<?> t = Thread.class;
+ try {
+ THREAD_LOCALS = UNSAFE.objectFieldOffset
+ (t.getDeclaredField("threadLocals"));
+ INHERITABLE_THREAD_LOCALS = UNSAFE.objectFieldOffset
+ (t.getDeclaredField("inheritableThreadLocals"));
+ } catch (Exception e) {
+ throw new Error(e);
+ }
+ }
+}
+