19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package sun.misc;
27
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 ManagedLocalsThread {
39 private static final Unsafe UNSAFE;
40 private static final ThreadGroup INNOCUOUSTHREADGROUP;
41 private static final AccessControlContext ACC;
42 private static final long INHERITEDACCESSCONTROLCONTEXT;
43 private static final long CONTEXTCLASSLOADER;
44
45 private static final AtomicInteger threadNumber = new AtomicInteger(1);
46
47 public InnocuousThread(Runnable target) {
48 this(INNOCUOUSTHREADGROUP, target,
49 "InnocuousThread-" + threadNumber.getAndIncrement());
50 }
51
52 public InnocuousThread(Runnable target, String name) {
53 this(INNOCUOUSTHREADGROUP, target, name);
54 }
55
56 public InnocuousThread(ThreadGroup group, Runnable target, String name) {
57 super(group, target, name);
58 UNSAFE.putOrderedObject(this, INHERITEDACCESSCONTROLCONTEXT, ACC);
59 UNSAFE.putOrderedObject(this, CONTEXTCLASSLOADER, ClassLoader.getSystemClassLoader());
75
76 // ensure run method is run only once
77 private volatile boolean hasRun;
78
79 @Override
80 public void run() {
81 if (Thread.currentThread() == this && !hasRun) {
82 hasRun = true;
83 super.run();
84 }
85 }
86
87 // Use Unsafe to access Thread group and ThreadGroup parent fields
88 static {
89 try {
90 ACC = new AccessControlContext(new ProtectionDomain[] {
91 new ProtectionDomain(null, null)
92 });
93
94 // Find and use topmost ThreadGroup as parent of new group
95 UNSAFE = Unsafe.getUnsafe();
96 Class<?> tk = Thread.class;
97 Class<?> gk = ThreadGroup.class;
98
99 INHERITEDACCESSCONTROLCONTEXT = UNSAFE.objectFieldOffset
100 (tk.getDeclaredField("inheritedAccessControlContext"));
101 CONTEXTCLASSLOADER = UNSAFE.objectFieldOffset
102 (tk.getDeclaredField("contextClassLoader"));
103
104 long tg = UNSAFE.objectFieldOffset(tk.getDeclaredField("group"));
105 long gp = UNSAFE.objectFieldOffset(gk.getDeclaredField("parent"));
106 ThreadGroup group = (ThreadGroup)
107 UNSAFE.getObject(Thread.currentThread(), tg);
108
109 while (group != null) {
110 ThreadGroup parent = (ThreadGroup)UNSAFE.getObject(group, gp);
111 if (parent == null)
112 break;
113 group = parent;
114 }
115 final ThreadGroup root = group;
|
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package sun.misc;
27
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 ManagedLocalsThread {
39 private static final jdk.internal.misc.Unsafe UNSAFE;
40 private static final ThreadGroup INNOCUOUSTHREADGROUP;
41 private static final AccessControlContext ACC;
42 private static final long INHERITEDACCESSCONTROLCONTEXT;
43 private static final long CONTEXTCLASSLOADER;
44
45 private static final AtomicInteger threadNumber = new AtomicInteger(1);
46
47 public InnocuousThread(Runnable target) {
48 this(INNOCUOUSTHREADGROUP, target,
49 "InnocuousThread-" + threadNumber.getAndIncrement());
50 }
51
52 public InnocuousThread(Runnable target, String name) {
53 this(INNOCUOUSTHREADGROUP, target, name);
54 }
55
56 public InnocuousThread(ThreadGroup group, Runnable target, String name) {
57 super(group, target, name);
58 UNSAFE.putOrderedObject(this, INHERITEDACCESSCONTROLCONTEXT, ACC);
59 UNSAFE.putOrderedObject(this, CONTEXTCLASSLOADER, ClassLoader.getSystemClassLoader());
75
76 // ensure run method is run only once
77 private volatile boolean hasRun;
78
79 @Override
80 public void run() {
81 if (Thread.currentThread() == this && !hasRun) {
82 hasRun = true;
83 super.run();
84 }
85 }
86
87 // Use Unsafe to access Thread group and ThreadGroup parent fields
88 static {
89 try {
90 ACC = new AccessControlContext(new ProtectionDomain[] {
91 new ProtectionDomain(null, null)
92 });
93
94 // Find and use topmost ThreadGroup as parent of new group
95 UNSAFE = jdk.internal.misc.Unsafe.getUnsafe();
96 Class<?> tk = Thread.class;
97 Class<?> gk = ThreadGroup.class;
98
99 INHERITEDACCESSCONTROLCONTEXT = UNSAFE.objectFieldOffset
100 (tk.getDeclaredField("inheritedAccessControlContext"));
101 CONTEXTCLASSLOADER = UNSAFE.objectFieldOffset
102 (tk.getDeclaredField("contextClassLoader"));
103
104 long tg = UNSAFE.objectFieldOffset(tk.getDeclaredField("group"));
105 long gp = UNSAFE.objectFieldOffset(gk.getDeclaredField("parent"));
106 ThreadGroup group = (ThreadGroup)
107 UNSAFE.getObject(Thread.currentThread(), tg);
108
109 while (group != null) {
110 ThreadGroup parent = (ThreadGroup)UNSAFE.getObject(group, gp);
111 if (parent == null)
112 break;
113 group = parent;
114 }
115 final ThreadGroup root = group;
|