mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			407 lines
		
	
	
		
			9.4 KiB
		
	
	
	
		
			Java
		
	
	
	
			
		
		
	
	
			407 lines
		
	
	
		
			9.4 KiB
		
	
	
	
		
			Java
		
	
	
	
// 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;
 | 
						|
}
 |