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() {
|
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, true);
56 }
57
58 public InnocuousThread(Runnable target, String name, boolean hasTCCL) {
59 this(INNOCUOUSTHREADGROUP, target, name, hasTCCL);
60 }
61
62 public InnocuousThread(ThreadGroup group, Runnable target, String name) {
63 this(group, target, name, true);
64 }
65
66 public InnocuousThread(ThreadGroup group, Runnable target, String name, boolean hasTCCL) {
67 super(group, target, name, 0L, false);
68 UNSAFE.putOrderedObject(this, INHERITEDACCESSCONTROLCONTEXT, ACC);
69 if (hasTCCL)
70 UNSAFE.putOrderedObject(this, CONTEXTCLASSLOADER, ClassLoader.getSystemClassLoader());
71 else
72 UNSAFE.putOrderedObject(this, CONTEXTCLASSLOADER, null);
73 }
74
75 @Override
76 public void setUncaughtExceptionHandler(UncaughtExceptionHandler x) {
77 // silently fail
78 }
79
80 @Override
81 public void setContextClassLoader(ClassLoader cl) {
82 // Allow clearing of the TCCL to remove the reference to the system classloader.
83 if (cl == null)
84 super.setContextClassLoader(null);
85 else
86 throw new SecurityException("setContextClassLoader");
87 }
88
89 /**
90 * Drops all thread locals (and inherited thread locals).
91 */
92 public final void eraseThreadLocals() {
|