/* * Copyright 2000-2005 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Sun designates this * particular file as subject to the "Classpath" exception as provided * by Sun in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */ package sun.rmi.runtime; import java.security.AccessController; import java.security.PrivilegedAction; import sun.security.util.SecurityConstants; /** * A PrivilegedAction for creating a new thread conveniently with an * AccessController.doPrivileged construct. * * All constructors allow the choice of the Runnable for the new * thread to execute, the name of the new thread (which will be * prefixed with "RMI "), and whether or not it will be a daemon * thread. * * The new thread may be created in the system thread group (the root * of the thread group tree) or an internally created non-system * thread group, as specified at construction of this class. * * The new thread will have the system class loader as its initial * context class loader (that is, its context class loader will NOT be * inherited from the current thread). * * @author Peter Jones **/ public final class NewThreadAction implements PrivilegedAction<Thread> { /** cached reference to the system (root) thread group */ static final ThreadGroup systemThreadGroup = AccessController.doPrivileged(new PrivilegedAction<ThreadGroup>() { public ThreadGroup run() { ThreadGroup group = Thread.currentThread().getThreadGroup(); ThreadGroup parent; while ((parent = group.getParent()) != null) { group = parent; } return group; } }); /** * special child of the system thread group for running tasks that * may execute user code, so that the security policy for threads in * the system thread group will not apply */ static final ThreadGroup userThreadGroup = AccessController.doPrivileged(new PrivilegedAction<ThreadGroup>() { public ThreadGroup run() { return new ThreadGroup(systemThreadGroup, "RMI Runtime"); } }); private final ThreadGroup group; private final Runnable runnable; private final String name; private final boolean daemon; NewThreadAction(ThreadGroup group, Runnable runnable, String name, boolean daemon) { this.group = group; this.runnable = runnable; this.name = name; this.daemon = daemon; } /** * Creates an action that will create a new thread in the * system thread group. * * @param runnable the Runnable for the new thread to execute * * @param name the name of the new thread * * @param daemon if true, new thread will be a daemon thread; * if false, new thread will not be a daemon thread */ public NewThreadAction(Runnable runnable, String name, boolean daemon) { this(systemThreadGroup, runnable, name, daemon); } /** * Creates an action that will create a new thread. * * @param runnable the Runnable for the new thread to execute * * @param name the name of the new thread * * @param daemon if true, new thread will be a daemon thread; * if false, new thread will not be a daemon thread * * @param user if true, thread will be created in a non-system * thread group; if false, thread will be created in the system * thread group */ public NewThreadAction(Runnable runnable, String name, boolean daemon, boolean user) { this(user ? userThreadGroup : systemThreadGroup, runnable, name, daemon); } public Thread run() { SecurityManager sm = System.getSecurityManager(); if (sm != null) { sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION); } Thread t = new Thread(group, runnable, "RMI " + name); t.setContextClassLoader(ClassLoader.getSystemClassLoader()); t.setDaemon(daemon); return t; } }