8044187: Enhancements to InnocuousThread
authorchegar
Wed, 18 Jun 2014 10:44:24 +0100
changeset 29903 b21ed6c8bc3f
parent 29901 7288f904fbe8
child 29904 d5f909aa26bc
8044187: Enhancements to InnocuousThread Reviewed-by: alanb
jdk/src/java.base/share/classes/sun/misc/InnocuousThread.java
--- a/jdk/src/java.base/share/classes/sun/misc/InnocuousThread.java	Tue Apr 14 13:02:23 2015 -0700
+++ b/jdk/src/java.base/share/classes/sun/misc/InnocuousThread.java	Wed Jun 18 10:44:24 2014 +0100
@@ -26,7 +26,10 @@
 package sun.misc;
 
 import java.security.AccessControlContext;
+import java.security.AccessController;
 import java.security.ProtectionDomain;
+import java.security.PrivilegedAction;
+import java.util.concurrent.atomic.AtomicInteger;
 
 /**
  * A thread that has no permissions, is not a member of any user-defined
@@ -36,22 +39,35 @@
  */
 public final class InnocuousThread extends Thread {
     private static final Unsafe UNSAFE;
-    private static final ThreadGroup THREADGROUP;
+    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 AtomicInteger threadNumber = new AtomicInteger(1);
+
     public InnocuousThread(Runnable target) {
-        super(THREADGROUP, target, "anInnocuousThread");
+        this(INNOCUOUSTHREADGROUP, target,
+             "InnocuousThread-" + threadNumber.getAndIncrement());
+    }
+
+    public InnocuousThread(Runnable target, String name) {
+        this(INNOCUOUSTHREADGROUP, target, name);
+    }
+
+    private 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() {
-        // always report system class loader
-        return ClassLoader.getSystemClassLoader();
+        return contextClassLoader;
     }
 
     @Override
@@ -61,7 +77,10 @@
 
     @Override
     public void setContextClassLoader(ClassLoader cl) {
-        throw new SecurityException("setContextClassLoader");
+        if (cl == null)
+            contextClassLoader = null;
+        else
+            throw new SecurityException("setContextClassLoader");
     }
 
     // ensure run method is run only once
@@ -113,7 +132,10 @@
                     break;
                 group = parent;
             }
-            THREADGROUP = new ThreadGroup(group, "InnocuousThreadGroup");
+            final ThreadGroup root = group;
+            INNOCUOUSTHREADGROUP = AccessController.doPrivileged(
+                (PrivilegedAction<ThreadGroup>) () ->
+                    { return new ThreadGroup(root, "InnocuousThreadGroup"); });
         } catch (Exception e) {
             throw new Error(e);
         }