// Thread.java - Thread class.
-/* Copyright (C) 1998, 1999, 2000 Red Hat, Inc.
+/* Copyright (C) 1998, 1999, 2000 Free Software Foundation
This file is part of libgcj.
package java.lang;
-import gnu.gcj.RawData;
-
/**
* @author Tom Tromey <tromey@cygnus.com>
* @date August 24, 1998
public native int countStackFrames ();
public static native Thread currentThread ();
public native void destroy ();
- public static native void dumpStack ();
+
+ public static void dumpStack ()
+ {
+ (new Exception ("Stack trace")).printStackTrace ();
+ }
public static int enumerate (Thread[] threads)
{
public static boolean interrupted ()
{
- return currentThread().isInterrupted_();
+ return currentThread().isInterrupted (true);
}
- // FIXME: it seems to me that this should be synchronized.
// Check the threads interrupted status. Note that this does not clear the
- // threads interrupted status (per JDK 1.2 online API documentation).
+ // thread's interrupted status (per JDK 1.2 online API documentation).
public boolean isInterrupted ()
{
return interrupt_flag;
public final native void resume ();
// This method exists only to avoid a warning from the C++ compiler.
- private static final native void run__ (Object obj);
- private native final void finish_ ();
+ private static final native void run_ (Object obj);
+ private final native void finish_ ();
- // Convenience method to check and clear the thread's interrupted status.
- private boolean isInterrupted_ ()
+ // Check the thread's interrupted status. If clear_flag is true, the
+ // thread's interrupted status is also cleared.
+ private boolean isInterrupted (boolean clear_flag)
{
boolean r = interrupt_flag;
- interrupt_flag = false;
- return r;
- }
-
- private final void run_ ()
- {
- try
- {
- run ();
- }
- catch (Throwable e)
+ if (clear_flag && r)
{
- // Uncaught exceptions are forwarded to the ThreadGroup. If
- // this results in an uncaught exception, that is ignored.
- try
- {
- group.uncaughtException(this, e);
- }
- catch (Throwable f)
- {
- // Nothing.
- }
+ // Only clear the flag if we saw it as set. Otherwise this could
+ // potentially cause us to miss an interrupt in a race condition,
+ // because this method is not synchronized.
+ interrupt_flag = false;
}
- finish_ ();
+ return r;
}
-
+
public void run ()
{
if (runnable != null)
public Thread (ThreadGroup g, Runnable r, String n)
{
- // Note that CURRENT can be null when we are creating the very
- // first thread. That's why we check it below.
Thread current = currentThread ();
-
- if (g != null)
+
+ if (g == null)
{
- // If CURRENT is null, then we are creating the first thread.
- // In this case we don't do the security check.
- if (current != null)
- g.checkAccess();
+ // If CURRENT is null, then we are bootstrapping the first thread.
+ // Use ThreadGroup.root, the main threadgroup.
+ if (current == null)
+ group = ThreadGroup.root;
+ else
+ group = current.getThreadGroup();
}
else
- g = current.getThreadGroup();
+ group = g;
+
+ group.checkAccess();
// The Class Libraries book says ``threadName cannot be null''. I
// take this to mean NullPointerException.
throw new NullPointerException ();
name = n;
- group = g;
- g.add(this);
+ group.addThread(this);
runnable = r;
data = null;
interrupt_flag = false;
alive_flag = false;
+ startable_flag = true;
+
if (current != null)
{
daemon_flag = current.isDaemon();
- priority = current.getPriority();
+ int gmax = group.getMaxPriority();
+ int pri = current.getPriority();
+ priority = (gmax < pri ? gmax : pri);
}
else
{
public String toString ()
{
- return "Thread[" + name + "," + priority + "," + group.getName() + "]";
+ return "Thread[" + name + "," + priority + "," +
+ (group == null ? "" : group.getName()) + "]";
}
public static native void yield ();
private boolean daemon_flag;
private boolean interrupt_flag;
private boolean alive_flag;
+ private boolean startable_flag;
// Our native data.
- private RawData data;
+ private Object data;
// Next thread number to assign.
private static int nextThreadNumber = 0;