// 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;
}
