001: /*
002: * Copyright 2000-2005 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package sun.rmi.runtime;
027:
028: import java.security.AccessController;
029: import java.security.PrivilegedAction;
030: import sun.security.util.SecurityConstants;
031:
032: /**
033: * A PrivilegedAction for creating a new thread conveniently with an
034: * AccessController.doPrivileged construct.
035: *
036: * All constructors allow the choice of the Runnable for the new
037: * thread to execute, the name of the new thread (which will be
038: * prefixed with "RMI "), and whether or not it will be a daemon
039: * thread.
040: *
041: * The new thread may be created in the system thread group (the root
042: * of the thread group tree) or an internally created non-system
043: * thread group, as specified at construction of this class.
044: *
045: * The new thread will have the system class loader as its initial
046: * context class loader (that is, its context class loader will NOT be
047: * inherited from the current thread).
048: *
049: * @author Peter Jones
050: * @version 1.14, 07/05/05
051: **/
052: public final class NewThreadAction implements PrivilegedAction<Thread> {
053:
054: /** cached reference to the system (root) thread group */
055: static final ThreadGroup systemThreadGroup = AccessController
056: .doPrivileged(new PrivilegedAction<ThreadGroup>() {
057: public ThreadGroup run() {
058: ThreadGroup group = Thread.currentThread()
059: .getThreadGroup();
060: ThreadGroup parent;
061: while ((parent = group.getParent()) != null) {
062: group = parent;
063: }
064: return group;
065: }
066: });
067:
068: /**
069: * special child of the system thread group for running tasks that
070: * may execute user code, so that the security policy for threads in
071: * the system thread group will not apply
072: */
073: static final ThreadGroup userThreadGroup = AccessController
074: .doPrivileged(new PrivilegedAction<ThreadGroup>() {
075: public ThreadGroup run() {
076: return new ThreadGroup(systemThreadGroup,
077: "RMI Runtime");
078: }
079: });
080:
081: private final ThreadGroup group;
082: private final Runnable runnable;
083: private final String name;
084: private final boolean daemon;
085:
086: NewThreadAction(ThreadGroup group, Runnable runnable, String name,
087: boolean daemon) {
088: this .group = group;
089: this .runnable = runnable;
090: this .name = name;
091: this .daemon = daemon;
092: }
093:
094: /**
095: * Creates an action that will create a new thread in the
096: * system thread group.
097: *
098: * @param runnable the Runnable for the new thread to execute
099: *
100: * @param name the name of the new thread
101: *
102: * @param daemon if true, new thread will be a daemon thread;
103: * if false, new thread will not be a daemon thread
104: */
105: public NewThreadAction(Runnable runnable, String name,
106: boolean daemon) {
107: this (systemThreadGroup, runnable, name, daemon);
108: }
109:
110: /**
111: * Creates an action that will create a new thread.
112: *
113: * @param runnable the Runnable for the new thread to execute
114: *
115: * @param name the name of the new thread
116: *
117: * @param daemon if true, new thread will be a daemon thread;
118: * if false, new thread will not be a daemon thread
119: *
120: * @param user if true, thread will be created in a non-system
121: * thread group; if false, thread will be created in the system
122: * thread group
123: */
124: public NewThreadAction(Runnable runnable, String name,
125: boolean daemon, boolean user) {
126: this (user ? userThreadGroup : systemThreadGroup, runnable,
127: name, daemon);
128: }
129:
130: public Thread run() {
131: SecurityManager sm = System.getSecurityManager();
132: if (sm != null) {
133: sm
134: .checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
135: }
136: Thread t = new Thread(group, runnable, "RMI " + name);
137: t.setContextClassLoader(ClassLoader.getSystemClassLoader());
138: t.setDaemon(daemon);
139: return t;
140: }
141: }
|