Initial revision
From-SVN: r26263
This commit is contained in:
parent
140fa895c6
commit
ee9dd3721b
370 changed files with 173494 additions and 0 deletions
406
libjava/java/lang/ThreadGroup.java
Normal file
406
libjava/java/lang/ThreadGroup.java
Normal file
|
@ -0,0 +1,406 @@
|
|||
// ThreadGroup.java - ThreadGroup class.
|
||||
|
||||
/* Copyright (C) 1998, 1999 Cygnus Solutions
|
||||
|
||||
This file is part of libgcj.
|
||||
|
||||
This software is copyrighted work licensed under the terms of the
|
||||
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
|
||||
details. */
|
||||
|
||||
package java.lang;
|
||||
|
||||
import java.util.Enumeration;
|
||||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
* @author Tom Tromey <tromey@cygnus.com>
|
||||
* @date August 25, 1998
|
||||
*/
|
||||
|
||||
/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
|
||||
* "The Java Language Specification", ISBN 0-201-63451-1
|
||||
* plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
|
||||
* Status: Complete for 1.1. Parts from the JDK 1.0 spec only are
|
||||
* not implemented. Parts of the 1.2 spec are also not implemented.
|
||||
*/
|
||||
|
||||
public class ThreadGroup
|
||||
{
|
||||
public int activeCount ()
|
||||
{
|
||||
int ac = threads.size();
|
||||
Enumeration e = groups.elements();
|
||||
while (e.hasMoreElements())
|
||||
{
|
||||
ThreadGroup g = (ThreadGroup) e.nextElement();
|
||||
ac += g.activeCount();
|
||||
}
|
||||
return ac;
|
||||
}
|
||||
|
||||
public int activeGroupCount ()
|
||||
{
|
||||
int ac = groups.size();
|
||||
Enumeration e = groups.elements();
|
||||
while (e.hasMoreElements())
|
||||
{
|
||||
ThreadGroup g = (ThreadGroup) e.nextElement();
|
||||
ac += g.activeGroupCount();
|
||||
}
|
||||
return ac;
|
||||
}
|
||||
|
||||
// Deprecated in 1.2.
|
||||
public boolean allowThreadSuspension (boolean allow)
|
||||
{
|
||||
// There is no way for a Java program to determine whether this
|
||||
// has any effect whatsoever. We don't need it.
|
||||
return true;
|
||||
}
|
||||
|
||||
public final void checkAccess ()
|
||||
{
|
||||
SecurityManager s = System.getSecurityManager();
|
||||
if (s != null)
|
||||
s.checkAccess(this);
|
||||
}
|
||||
|
||||
// This is called to remove a ThreadGroup from our internal list.
|
||||
private final void remove (ThreadGroup g)
|
||||
{
|
||||
groups.removeElement(g);
|
||||
if (daemon_flag && groups.size() == 0 && threads.size() == 0)
|
||||
{
|
||||
// We inline destroy to avoid the access check.
|
||||
destroyed_flag = true;
|
||||
if (parent != null)
|
||||
parent.remove(this);
|
||||
}
|
||||
}
|
||||
|
||||
// This is called by the Thread code to remove a Thread from our
|
||||
// internal list. FIXME: currently, it isn't called at all. There
|
||||
// doesn't appear to be any way to remove a Thread from a
|
||||
// ThreadGroup (except the unimplemented destroy method).
|
||||
final void remove (Thread t)
|
||||
{
|
||||
threads.removeElement(t);
|
||||
if (daemon_flag && groups.size() == 0 && threads.size() == 0)
|
||||
{
|
||||
// We inline destroy to avoid the access check.
|
||||
destroyed_flag = true;
|
||||
if (parent != null)
|
||||
parent.remove(this);
|
||||
}
|
||||
}
|
||||
|
||||
// This is called by the Thread code to add a Thread to our internal
|
||||
// list.
|
||||
final void add (Thread t)
|
||||
{
|
||||
if (destroyed_flag)
|
||||
throw new IllegalThreadStateException ();
|
||||
|
||||
threads.addElement(t);
|
||||
}
|
||||
|
||||
// This is a helper that is used to implement the destroy method.
|
||||
private final boolean canDestroy ()
|
||||
{
|
||||
if (! threads.isEmpty())
|
||||
return false;
|
||||
Enumeration e = groups.elements();
|
||||
while (e.hasMoreElements())
|
||||
{
|
||||
ThreadGroup g = (ThreadGroup) e.nextElement();
|
||||
if (! g.canDestroy())
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public final void destroy ()
|
||||
{
|
||||
checkAccess ();
|
||||
if (! canDestroy ())
|
||||
throw new IllegalThreadStateException ();
|
||||
destroyed_flag = true;
|
||||
if (parent != null)
|
||||
parent.remove(this);
|
||||
}
|
||||
|
||||
// This actually implements enumerate.
|
||||
private final int enumerate (Thread[] ts, int next_index, boolean recurse)
|
||||
{
|
||||
Enumeration e = threads.elements();
|
||||
while (e.hasMoreElements() && next_index < ts.length)
|
||||
ts[next_index++] = (Thread) e.nextElement();
|
||||
if (recurse && next_index != ts.length)
|
||||
{
|
||||
e = groups.elements();
|
||||
while (e.hasMoreElements() && next_index < ts.length)
|
||||
{
|
||||
ThreadGroup g = (ThreadGroup) e.nextElement();
|
||||
next_index = g.enumerate(ts, next_index, true);
|
||||
}
|
||||
}
|
||||
return next_index;
|
||||
}
|
||||
|
||||
public int enumerate (Thread[] ts)
|
||||
{
|
||||
return enumerate (ts, 0, true);
|
||||
}
|
||||
|
||||
public int enumerate (Thread[] ts, boolean recurse)
|
||||
{
|
||||
return enumerate (ts, 0, recurse);
|
||||
}
|
||||
|
||||
// This actually implements enumerate.
|
||||
private final int enumerate (ThreadGroup[] ts, int next_index,
|
||||
boolean recurse)
|
||||
{
|
||||
Enumeration e = groups.elements();
|
||||
while (e.hasMoreElements() && next_index < ts.length)
|
||||
{
|
||||
ThreadGroup g = (ThreadGroup) e.nextElement();
|
||||
ts[next_index++] = g;
|
||||
if (recurse && next_index != ts.length)
|
||||
next_index = g.enumerate(ts, next_index, true);
|
||||
}
|
||||
return next_index;
|
||||
}
|
||||
|
||||
public int enumerate (ThreadGroup[] gs)
|
||||
{
|
||||
return enumerate (gs, 0, true);
|
||||
}
|
||||
|
||||
public int enumerate (ThreadGroup[] gs, boolean recurse)
|
||||
{
|
||||
return enumerate (gs, 0, recurse);
|
||||
}
|
||||
|
||||
public final int getMaxPriority ()
|
||||
{
|
||||
return maxpri;
|
||||
}
|
||||
|
||||
public final String getName ()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
public final ThreadGroup getParent ()
|
||||
{
|
||||
return parent;
|
||||
}
|
||||
|
||||
// JDK 1.2.
|
||||
// public void interrupt ();
|
||||
|
||||
public final boolean isDaemon ()
|
||||
{
|
||||
return daemon_flag;
|
||||
}
|
||||
|
||||
public synchronized boolean isDestroyed ()
|
||||
{
|
||||
return destroyed_flag;
|
||||
}
|
||||
|
||||
private final void list (String indentation)
|
||||
{
|
||||
System.out.print(indentation);
|
||||
System.out.println(toString ());
|
||||
String sub = indentation + " ";
|
||||
Enumeration e = threads.elements();
|
||||
while (e.hasMoreElements())
|
||||
{
|
||||
Thread t = (Thread) e.nextElement();
|
||||
System.out.print(sub);
|
||||
System.out.println(t.toString());
|
||||
}
|
||||
e = groups.elements();
|
||||
while (e.hasMoreElements())
|
||||
{
|
||||
ThreadGroup g = (ThreadGroup) e.nextElement();
|
||||
g.list(sub);
|
||||
}
|
||||
}
|
||||
|
||||
public void list ()
|
||||
{
|
||||
list ("");
|
||||
}
|
||||
|
||||
public final boolean parentOf (ThreadGroup g)
|
||||
{
|
||||
while (g != null)
|
||||
{
|
||||
if (this == g)
|
||||
return true;
|
||||
g = g.parent;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Deprecated in 1.2.
|
||||
public final void resume ()
|
||||
{
|
||||
checkAccess ();
|
||||
Enumeration e = threads.elements();
|
||||
while (e.hasMoreElements())
|
||||
{
|
||||
Thread t = (Thread) e.nextElement();
|
||||
t.resume();
|
||||
}
|
||||
e = groups.elements();
|
||||
while (e.hasMoreElements())
|
||||
{
|
||||
ThreadGroup g = (ThreadGroup) e.nextElement();
|
||||
g.resume();
|
||||
}
|
||||
}
|
||||
|
||||
public final void setDaemon (boolean daemon)
|
||||
{
|
||||
checkAccess ();
|
||||
daemon_flag = daemon;
|
||||
// FIXME: the docs don't say you are supposed to do this. But
|
||||
// they don't say you aren't, either.
|
||||
if (groups.size() == 0 && threads.size() == 0)
|
||||
destroy ();
|
||||
}
|
||||
|
||||
public final void setMaxPriority (int pri)
|
||||
{
|
||||
checkAccess ();
|
||||
|
||||
// FIXME: JDK 1.2 behaviour is different: if the newMaxPriority
|
||||
// argument is < MIN_PRIORITY or > MAX_PRIORITY an
|
||||
// IllegalArgumentException should be thrown.
|
||||
if (pri >= Thread.MIN_PRIORITY && pri <= maxpri)
|
||||
{
|
||||
maxpri = pri;
|
||||
|
||||
Enumeration e = groups.elements();
|
||||
while (e.hasMoreElements())
|
||||
{
|
||||
ThreadGroup g = (ThreadGroup) e.nextElement();
|
||||
g.setMaxPriority (maxpri);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Deprecated in 1.2.
|
||||
public final void stop ()
|
||||
{
|
||||
checkAccess ();
|
||||
Enumeration e = threads.elements();
|
||||
while (e.hasMoreElements())
|
||||
{
|
||||
Thread t = (Thread) e.nextElement();
|
||||
t.stop();
|
||||
}
|
||||
e = groups.elements();
|
||||
while (e.hasMoreElements())
|
||||
{
|
||||
ThreadGroup g = (ThreadGroup) e.nextElement();
|
||||
g.stop();
|
||||
}
|
||||
}
|
||||
|
||||
// Deprecated in 1.2.
|
||||
public final void suspend ()
|
||||
{
|
||||
checkAccess ();
|
||||
Enumeration e = threads.elements();
|
||||
while (e.hasMoreElements())
|
||||
{
|
||||
Thread t = (Thread) e.nextElement();
|
||||
t.suspend();
|
||||
}
|
||||
e = groups.elements();
|
||||
while (e.hasMoreElements())
|
||||
{
|
||||
ThreadGroup g = (ThreadGroup) e.nextElement();
|
||||
g.suspend();
|
||||
}
|
||||
}
|
||||
|
||||
// This constructor appears in the Class Libraries book but in
|
||||
// neither the Language Spec nor the 1.2 docs.
|
||||
public ThreadGroup ()
|
||||
{
|
||||
this (Thread.currentThread().getThreadGroup(), null);
|
||||
}
|
||||
|
||||
public ThreadGroup (String n)
|
||||
{
|
||||
this (Thread.currentThread().getThreadGroup(), n);
|
||||
}
|
||||
|
||||
public ThreadGroup (ThreadGroup p, String n)
|
||||
{
|
||||
checkAccess ();
|
||||
if (p == null)
|
||||
throw new NullPointerException ();
|
||||
if (p.destroyed_flag)
|
||||
throw new IllegalArgumentException ();
|
||||
|
||||
parent = p;
|
||||
name = n;
|
||||
maxpri = p.maxpri;
|
||||
threads = new Vector ();
|
||||
groups = new Vector ();
|
||||
daemon_flag = p.daemon_flag;
|
||||
destroyed_flag = false;
|
||||
p.groups.addElement(this);
|
||||
}
|
||||
|
||||
// This is the constructor that is used when creating the very first
|
||||
// ThreadGroup. We have an arbitrary argument here just to
|
||||
// differentiate this constructor from the others.
|
||||
private ThreadGroup (int dummy)
|
||||
{
|
||||
parent = null;
|
||||
name = "main";
|
||||
maxpri = Thread.MAX_PRIORITY;
|
||||
threads = new Vector ();
|
||||
groups = new Vector ();
|
||||
daemon_flag = false;
|
||||
destroyed_flag = false;
|
||||
}
|
||||
|
||||
public String toString ()
|
||||
{
|
||||
// Language Spec and Class Libraries book disagree a bit here. We
|
||||
// follow the Spec, but add "ThreadGroup" per the book. We
|
||||
// include "java.lang" based on the list() example in the Class
|
||||
// Libraries book.
|
||||
return "java.lang.ThreadGroup[name=" + name + ",maxpri=" + maxpri + "]";
|
||||
}
|
||||
|
||||
public void uncaughtException (Thread thread, Throwable e)
|
||||
{
|
||||
// FIXME: in 1.2, this has different semantics. In particular if
|
||||
// this group has a parent, the exception is passed upwards and
|
||||
// not processed locally.
|
||||
if (! (e instanceof ThreadDeath))
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// Private data.
|
||||
private ThreadGroup parent;
|
||||
private String name;
|
||||
private int maxpri;
|
||||
private Vector threads;
|
||||
private Vector groups;
|
||||
private boolean daemon_flag;
|
||||
private boolean destroyed_flag;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue