1 /*
  2  * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.  Oracle designates this
  8  * particular file as subject to the "Classpath" exception as provided
  9  * by Oracle in the LICENSE file that accompanied this code.
 10  *
 11  * This code is distributed in the hope that it will be useful, but WITHOUT
 12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 14  * version 2 for more details (a copy is included in the LICENSE file that
 15  * accompanied this code).
 16  *
 17  * You should have received a copy of the GNU General Public License version
 18  * 2 along with this work; if not, write to the Free Software Foundation,
 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.rmi.runtime;
 27 
 28 import java.security.AccessController;
 29 import java.security.PrivilegedAction;
 30 import sun.security.util.SecurityConstants;
 31 
 32 /**
 33  * A PrivilegedAction for creating a new thread conveniently with an
 34  * AccessController.doPrivileged construct.
 35  *
 36  * All constructors allow the choice of the Runnable for the new
 37  * thread to execute, the name of the new thread (which will be
 38  * prefixed with "RMI "), and whether or not it will be a daemon
 39  * thread.
 40  *
 41  * The new thread may be created in the system thread group (the root
 42  * of the thread group tree) or an internally created non-system
 43  * thread group, as specified at construction of this class.
 44  *
 45  * The new thread will have the system class loader as its initial
 46  * context class loader (that is, its context class loader will NOT be
 47  * inherited from the current thread).
 48  *
 49  * @author      Peter Jones
 50  **/
 51 public final class NewThreadAction implements PrivilegedAction<Thread> {
 52 
 53     /** cached reference to the system (root) thread group */
 54     @SuppressWarnings("removal")
 55     static final ThreadGroup systemThreadGroup =
 56         AccessController.doPrivileged(new PrivilegedAction<ThreadGroup>() {
 57             public ThreadGroup run() {

 58                 ThreadGroup group = Thread.currentThread().getThreadGroup();
 59                 ThreadGroup parent;
 60                 while ((parent = group.getParent()) != null) {
 61                     group = parent;
 62                 }
 63                 return group;
 64             }
 65         });
 66 
 67     /**
 68      * special child of the system thread group for running tasks that
 69      * may execute user code, so that the security policy for threads in
 70      * the system thread group will not apply
 71      */
 72     @SuppressWarnings("removal")
 73     static final ThreadGroup userThreadGroup =
 74         AccessController.doPrivileged(new PrivilegedAction<ThreadGroup>() {
 75             public ThreadGroup run() {
 76                 return new ThreadGroup(systemThreadGroup, "RMI Runtime");
 77             }
 78         });
 79 
 80     private final ThreadGroup group;
 81     private final Runnable runnable;
 82     private final String name;
 83     private final boolean daemon;
 84 
 85     NewThreadAction(ThreadGroup group, Runnable runnable,
 86                     String name, boolean daemon)
 87     {
 88         this.group = group;
 89         this.runnable = runnable;
 90         this.name = name;
 91         this.daemon = daemon;
 92     }
 93 
 94     /**
 95      * Creates an action that will create a new thread in the
 96      * system thread group.
 97      *
 98      * @param   runnable the Runnable for the new thread to execute
 99      *
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, boolean daemon) {
106         this(systemThreadGroup, runnable, name, daemon);
107     }
108 
109     /**
110      * Creates an action that will create a new thread.
111      *
112      * @param   runnable the Runnable for the new thread to execute
113      *
114      * @param   name the name of the new thread
115      *
116      * @param   daemon if true, new thread will be a daemon thread;
117      * if false, new thread will not be a daemon thread
118      *
119      * @param   user if true, thread will be created in a non-system
120      * thread group; if false, thread will be created in the system
121      * thread group
122      */
123     public NewThreadAction(Runnable runnable, String name, boolean daemon,
124                            boolean user)
125     {
126         this(user ? userThreadGroup : systemThreadGroup,
127              runnable, name, daemon);
128     }
129 
130     public Thread run() {
131         @SuppressWarnings("removal")
132         SecurityManager sm = System.getSecurityManager();
133         if (sm != null) {
134             sm.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 }
--- EOF ---