OSDN Git Service

* java/lang/Thread.java (stop): No longer synchronized.
[pf3gnuchains/gcc-fork.git] / libjava / java / lang / Thread.java
1 // Thread.java - Thread class.
2
3 /* Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation
4
5    This file is part of libgcj.
6
7 This software is copyrighted work licensed under the terms of the
8 Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
9 details.  */
10
11 package java.lang;
12
13 /**
14  * @author Tom Tromey <tromey@cygnus.com>
15  * @date August 24, 1998 
16  */
17
18 /* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
19  * "The Java Language Specification", ISBN 0-201-63451-1
20  * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
21  * Status:  Believed complete to version 1.3, with caveats. We do not 
22  *          implement the deprecated (and dangerous) stop, suspend, and resume
23  *          methods. Security implementation is not complete.
24  */
25
26 public class Thread implements Runnable
27 {
28   public final static int MAX_PRIORITY = 10;
29   public final static int MIN_PRIORITY = 1;
30   public final static int NORM_PRIORITY = 5;
31
32   public static int activeCount ()
33   {
34     return currentThread().getThreadGroup().activeCount();
35   }
36
37   public final void checkAccess ()
38   {
39     SecurityManager s = System.getSecurityManager();
40     if (s != null)
41       s.checkAccess(this);
42   }
43
44   public native int countStackFrames ();
45   public static native Thread currentThread ();
46   public native void destroy ();
47   
48   public static void dumpStack ()
49   {
50     (new Exception ("Stack trace")).printStackTrace ();
51   }
52
53   public static int enumerate (Thread[] threads)
54   {
55     return currentThread().group.enumerate(threads);
56   }
57
58   public final String getName ()
59   {
60     return name;
61   }
62
63   public final int getPriority ()
64   {
65     return priority;
66   }
67
68   public final ThreadGroup getThreadGroup ()
69   {
70     return group;
71   }
72
73   public native void interrupt ();
74
75   public static boolean interrupted ()
76   {
77     return currentThread().isInterrupted (true);
78   }
79
80   // Check the threads interrupted status. Note that this does not clear the
81   // thread's interrupted status (per JDK 1.2 online API documentation).
82   public boolean isInterrupted ()
83   {
84     return interrupt_flag;
85   }
86
87   public final boolean isAlive ()
88   {
89     return alive_flag;
90   }
91
92   public final boolean isDaemon ()
93   {
94     return daemon_flag;
95   }
96
97   public final void join () throws InterruptedException
98   {
99     join (0, 0);
100   }
101
102   public final void join (long timeout) throws InterruptedException
103   {
104     join (timeout, 0);
105   }
106
107   public final native void join (long timeout, int nanos)
108     throws InterruptedException;
109
110   public final native void resume ();
111
112   private final native void finish_ ();
113
114   // Check the thread's interrupted status. If clear_flag is true, the 
115   // thread's interrupted status is also cleared.
116   private boolean isInterrupted (boolean clear_flag)
117   {
118     boolean r = interrupt_flag;
119     if (clear_flag && r)
120       {
121         // Only clear the flag if we saw it as set. Otherwise this could 
122         // potentially cause us to miss an interrupt in a race condition, 
123         // because this method is not synchronized.
124         interrupt_flag = false;
125       }
126     return r;
127   }
128   
129   public void run ()
130   {
131     if (runnable != null)
132       runnable.run();
133   }
134
135   public final void setDaemon (boolean status)
136   {
137     checkAccess ();
138     if (isAlive ())
139       throw new IllegalThreadStateException ();
140     daemon_flag = status;
141   }
142
143   public synchronized ClassLoader getContextClassLoader()
144   {
145     if (context_class_loader == null)
146       context_class_loader = ClassLoader.getSystemClassLoader ();
147
148     SecurityManager s = System.getSecurityManager();
149     // FIXME: we can't currently find the caller's class loader.
150     ClassLoader callers = null;
151     if (s != null && callers != null)
152       {
153         // See if the caller's class loader is the same as or an
154         // ancestor of this thread's class loader.
155         while (callers != null && callers != context_class_loader)
156           {
157             // FIXME: should use some internal version of getParent
158             // that avoids security checks.
159             callers = callers.getParent ();
160           }
161
162         if (callers != context_class_loader)
163           s.checkPermission (new RuntimePermission ("getClassLoader"));
164       }
165
166     return context_class_loader;
167   }
168
169   public synchronized void setContextClassLoader(ClassLoader cl)
170   {
171     SecurityManager s = System.getSecurityManager ();
172     if (s != null)
173       s.checkPermission (new RuntimePermission ("setContextClassLoader"));
174     context_class_loader = cl;
175   }
176
177   public final void setName (String n)
178   {
179     checkAccess ();
180     // The Class Libraries book says ``threadName cannot be null''.  I
181     // take this to mean NullPointerException.
182     if (n == null)
183       throw new NullPointerException ();
184     name = n;
185   }
186
187   public final native void setPriority (int newPriority);
188
189   public static void sleep (long timeout) throws InterruptedException
190   {
191     sleep (timeout, 0);
192   }
193
194   public static native void sleep (long timeout, int nanos)
195     throws InterruptedException;
196   public native void start ();
197
198   public final void stop ()
199   {
200     // Argument doesn't matter, because this is no longer
201     // supported.
202     stop (null);
203   }
204
205   public final native void stop (Throwable e);
206   public final native void suspend ();
207
208   private final native void initialize_native ();
209
210   private final native static String gen_name ();
211
212   public Thread (ThreadGroup g, Runnable r, String n)
213   {
214     this (currentThread (), g, r, n);
215
216     // The Class Libraries book says ``threadName cannot be null''.  I
217     // take this to mean NullPointerException.
218     if (n == null)
219       throw new NullPointerException ();
220   }
221
222   private Thread (Thread current, ThreadGroup g, Runnable r, String n)
223   {
224     if (g == null)
225       {
226         // If CURRENT is null, then we are bootstrapping the first thread. 
227         // Use ThreadGroup.root, the main threadgroup.
228         if (current == null)
229           group = ThreadGroup.root;
230         else
231           group = current.getThreadGroup();
232       }
233     else
234       group = g;
235       
236     data = null;
237     interrupt_flag = false;
238     alive_flag = false;
239     startable_flag = true;
240
241     if (current != null)
242       {
243         group.checkAccess();
244
245         daemon_flag = current.isDaemon();
246         int gmax = group.getMaxPriority();
247         int pri = current.getPriority();
248         priority = (gmax < pri ? gmax : pri);
249         context_class_loader = current.context_class_loader;
250         InheritableThreadLocal.newChildThread(this);
251       }
252     else
253       {
254         daemon_flag = false;
255         priority = NORM_PRIORITY;
256       }
257
258     name = n;
259     group.addThread(this);
260     runnable = r;
261
262     initialize_native ();
263   }
264
265   public Thread ()
266   {
267     this (null, null, gen_name ());
268   }
269
270   public Thread (Runnable r)
271   {
272     this (null, r, gen_name ());
273   }
274
275   public Thread (String n)
276   {
277     this (null, null, n);
278   }
279
280   public Thread (ThreadGroup g, Runnable r)
281   {
282     this (g, r, gen_name ());
283   }
284
285   public Thread (ThreadGroup g, String n)
286   {
287     this (g, null, n);
288   }
289
290   public Thread (Runnable r, String n)
291   {
292     this (null, r, n);
293   }
294
295   public String toString ()
296   {
297     return "Thread[" + name + "," + priority + "," + 
298       (group == null ? "" : group.getName()) + "]";
299   }
300
301   public static native void yield ();
302
303   // Private data.
304   private ThreadGroup group;
305   private String name;
306   private Runnable runnable;
307   private int priority;
308   private boolean daemon_flag;
309   boolean interrupt_flag;
310   private boolean alive_flag;
311   private boolean startable_flag;
312   private ClassLoader context_class_loader;
313
314   // Our native data - points to an instance of struct natThread.
315   private Object data;
316 }