aboutsummaryrefslogtreecommitdiff
path: root/libjava/java/lang/ThreadGroup.java
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/java/lang/ThreadGroup.java')
-rw-r--r--libjava/java/lang/ThreadGroup.java406
1 files changed, 406 insertions, 0 deletions
diff --git a/libjava/java/lang/ThreadGroup.java b/libjava/java/lang/ThreadGroup.java
new file mode 100644
index 0000000..1aa1a9a
--- /dev/null
+++ b/libjava/java/lang/ThreadGroup.java
@@ -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;
+}