28 import java.security.AccessControlContext; 29 import java.security.AccessController; 30 import java.security.ProtectionDomain; 31 import java.security.PrivilegedAction; 32 import java.util.concurrent.atomic.AtomicInteger; 33 34 /** 35 * A thread that has no permissions, is not a member of any user-defined 36 * ThreadGroup and supports the ability to erase ThreadLocals. 37 */ 38 public final class InnocuousThread extends Thread { 39 private static final jdk.internal.misc.Unsafe UNSAFE; 40 private static final long THREAD_LOCALS; 41 private static final long INHERITABLE_THREAD_LOCALS; 42 private static final ThreadGroup INNOCUOUSTHREADGROUP; 43 private static final AccessControlContext ACC; 44 private static final long INHERITEDACCESSCONTROLCONTEXT; 45 private static final long CONTEXTCLASSLOADER; 46 47 private static final AtomicInteger threadNumber = new AtomicInteger(1); 48 49 public InnocuousThread(Runnable target) { 50 this(INNOCUOUSTHREADGROUP, target, 51 "InnocuousThread-" + threadNumber.getAndIncrement()); 52 } 53 54 public InnocuousThread(Runnable target, String name) { 55 this(INNOCUOUSTHREADGROUP, target, name); 56 } 57 58 public InnocuousThread(ThreadGroup group, Runnable target, String name) { 59 super(group, target, name, 0L, false); 60 UNSAFE.putOrderedObject(this, INHERITEDACCESSCONTROLCONTEXT, ACC); 61 UNSAFE.putOrderedObject(this, CONTEXTCLASSLOADER, ClassLoader.getSystemClassLoader()); 62 } 63 64 @Override 65 public void setUncaughtExceptionHandler(UncaughtExceptionHandler x) { 66 // silently fail 67 } 68 69 @Override 70 public void setContextClassLoader(ClassLoader cl) { 71 // Allow clearing of the TCCL to remove the reference to the system classloader. 72 if (cl == null) 73 super.setContextClassLoader(null); 74 else 75 throw new SecurityException("setContextClassLoader"); 76 } 77 78 /** 79 * Drops all thread locals (and inherited thread locals). 80 */ 81 public final void eraseThreadLocals() { | 28 import java.security.AccessControlContext; 29 import java.security.AccessController; 30 import java.security.ProtectionDomain; 31 import java.security.PrivilegedAction; 32 import java.util.concurrent.atomic.AtomicInteger; 33 34 /** 35 * A thread that has no permissions, is not a member of any user-defined 36 * ThreadGroup and supports the ability to erase ThreadLocals. 37 */ 38 public final class InnocuousThread extends Thread { 39 private static final jdk.internal.misc.Unsafe UNSAFE; 40 private static final long THREAD_LOCALS; 41 private static final long INHERITABLE_THREAD_LOCALS; 42 private static final ThreadGroup INNOCUOUSTHREADGROUP; 43 private static final AccessControlContext ACC; 44 private static final long INHERITEDACCESSCONTROLCONTEXT; 45 private static final long CONTEXTCLASSLOADER; 46 47 private static final AtomicInteger threadNumber = new AtomicInteger(1); 48 private static String newName() { 49 return "InnocuousThread-" + threadNumber.getAndIncrement(); 50 } 51 52 /** 53 * Returns a new InnocuousThread with an auto-generated thread name 54 * and its context class loader is set to the system class loader. 55 */ 56 public static Thread newThread(Runnable target) { 57 return newThread(newName(), target); 58 } 59 60 /** 61 * Returns a new InnocuousThread with its context class loader 62 * set to the system class loader. 63 */ 64 public static Thread newThread(String name, Runnable target) { 65 return new InnocuousThread(INNOCUOUSTHREADGROUP, 66 target, 67 name, 68 ClassLoader.getSystemClassLoader()); 69 } 70 71 /** 72 * Returns a new InnocuousThread with an auto-generated thread name. 73 * Its context class loader is set to null. 74 */ 75 public static Thread newSystemThread(Runnable target) { 76 return newSystemThread(newName(), target); 77 } 78 79 /** 80 * Returns a new InnocuousThread with null context class loader. 81 */ 82 public static Thread newSystemThread(String name, Runnable target) { 83 return new InnocuousThread(INNOCUOUSTHREADGROUP, 84 target, name, null); 85 } 86 87 private InnocuousThread(ThreadGroup group, Runnable target, String name, ClassLoader tccl) { 88 super(group, target, name, 0L, false); 89 UNSAFE.putOrderedObject(this, INHERITEDACCESSCONTROLCONTEXT, ACC); 90 UNSAFE.putOrderedObject(this, CONTEXTCLASSLOADER, tccl); 91 } 92 93 @Override 94 public void setUncaughtExceptionHandler(UncaughtExceptionHandler x) { 95 // silently fail 96 } 97 98 @Override 99 public void setContextClassLoader(ClassLoader cl) { 100 // Allow clearing of the TCCL to remove the reference to the system classloader. 101 if (cl == null) 102 super.setContextClassLoader(null); 103 else 104 throw new SecurityException("setContextClassLoader"); 105 } 106 107 /** 108 * Drops all thread locals (and inherited thread locals). 109 */ 110 public final void eraseThreadLocals() { |