/* java.lang.ThreadGroup
   Copyright (C) 1998, 2000, 2001 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
 
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.

As a special exception, if you link this library with other files to
produce an executable, this library does not by itself cause the
resulting executable to be covered by the GNU General Public License.
This exception does not however invalidate any other reasons why the
executable file might be covered by the GNU General Public License. */
 
package java.lang;

import java.util.Vector;
import java.util.Enumeration;

/* 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 from http://www.javasoft.com.
 * Status:  Complete for 1.2.  Some parts from the JDK 1.0 spec only are
 * not implemented. 
 */
 
/**
 * ThreadGroup allows you to group Threads together.  There is a
 * hierarchy of ThreadGroups, and only the initial ThreadGroup has
 * no parent.  A Thread may access information about its own
 * ThreadGroup, but not its parents or others outside the tree.
 *
 * @author John Keiser
 * @author Tom Tromey
 * @author Bryce McKinlay
 * @version 1.2.0
 * @since JDK1.0
 */

public class ThreadGroup
{
  /* The Initial, top-level ThreadGroup. */
  static ThreadGroup root = new ThreadGroup();
  /* This flag is set if an uncaught exception occurs. The runtime should 
  check this and exit with an error status if it is set. */
  static boolean had_uncaught_exception = false;

  private ThreadGroup parent;
  private String name;
  private Vector threads = new Vector();
  private Vector groups = new Vector();
  private boolean daemon_flag = false;
  private int maxpri = Thread.MAX_PRIORITY;

  private ThreadGroup()
  {
    name = "main";    
  }

  /** Create a new ThreadGroup using the given name and the
   *  current thread's ThreadGroup as a parent.
   *  @param name the name to use for the ThreadGroup.
   */
  public ThreadGroup(String name)
  {
    this (Thread.currentThread().getThreadGroup(), name);
  }

  /** Create a new ThreadGroup using the given name and
   *  parent group.
   *  @param name the name to use for the ThreadGroup.
   *  @param parent the ThreadGroup to use as a parent.
   *  @exception NullPointerException if parent is null.
   *  @exception SecurityException if you cannot change
   *             the intended parent group.
   */
  public ThreadGroup(ThreadGroup parent, String name)
  {
    parent.checkAccess();
    this.parent = parent;
    if (parent.isDestroyed())
      throw new IllegalArgumentException ();
    this.name = name;
    maxpri = parent.maxpri;
    daemon_flag = parent.daemon_flag;
    parent.addGroup(this);
  }

  /** Get the name of this ThreadGroup.
   *  @return the name of this ThreadGroup.
   */
  public final String getName()
  {
    return name;
  }

  /** Get the parent of this ThreadGroup.
   *  @return the parent of this ThreadGroup.
   */
  public final ThreadGroup getParent()
  {
    return parent;
  }

  /** Set the maximum priority for Threads in this ThreadGroup. setMaxPriority
   *  can only be used to reduce the current maximum. If maxpri
   *  is greater than the current Maximum, the current value is not changed.
   *  Calling this does not effect threads already in this ThreadGroup.
   *  @param maxpri the new maximum priority for this ThreadGroup.
   *  @exception SecurityException if you cannoy modify this ThreadGroup.
   */
  public final synchronized void setMaxPriority(int maxpri)
  {
    checkAccess();
    if (maxpri < this.maxpri
        && maxpri >= Thread.MIN_PRIORITY
	&& maxpri <= Thread.MAX_PRIORITY)
      {
	this.maxpri = maxpri;        
      }  
  }

  /** Get the maximum priority of Threads in this ThreadGroup.
   *  @return the maximum priority of Threads in this ThreadGroup.
   */
  public final int getMaxPriority()
  {
    return maxpri;
  }

  /** Set whether this ThreadGroup is a daemon group.  A daemon
   *  group will be destroyed when its last thread is stopped and
   *  its last thread group is destroyed.
   *  @specnote The Java API docs indicate that the group is destroyed
   * 		when either of those happen, but that doesn't make
   * 		sense.
   *  @param daemon whether this ThreadGroup should be a daemon group.
   *  @exception SecurityException if you cannoy modify this ThreadGroup.
   */
  public final void setDaemon (boolean daemon)
  {
    checkAccess();
    daemon_flag = daemon;
  }
   
  /** Tell whether this ThreadGroup is a daemon group.  A daemon
    * group will be destroyed when its last thread is stopped and
    * its last thread group is destroyed.
    * @specnote The Java API docs indicate that the group is destroyed
    *		when either of those happen, but that doesn't make
    *		sense.
    * @return whether this ThreadGroup is a daemon group.
    */
  public final boolean isDaemon()
  {
    return daemon_flag;
  }

  /** Tell whether this ThreadGroup has been destroyed or not.
    * @return whether this ThreadGroup has been destroyed or not.
    */
  public synchronized boolean isDestroyed()
  {
    return parent == null && this != root;
  }

  /** Check whether this ThreadGroup is an ancestor of the
    * specified ThreadGroup, or if they are the same.
    *
    * @param g the group to test on.
    * @return whether this ThreadGroup is a parent of the
    *	      specified group.
    */
  public final boolean parentOf(ThreadGroup tg)
  {
    while (tg != null)
      {
        if (tg == this)
          return true;
        tg = tg.parent;
      }
    return false;
  }

  /** Return the total number of active threads in this ThreadGroup
    * and all its descendants.<P>
    *
    * This cannot return an exact number, since the status of threads
    * may change after they were counted.  But it should be pretty
    * close.<P>
    *
    * @return the number of active threads in this ThreadGroup and
    *	      its descendants.
    * @specnote it isn't clear what the definition of an "Active" thread is.
    *           Current JDKs regard a thread as active if has been
    *           started and not finished.  We implement this behaviour.
    *           There is a JDC bug, <A HREF="http://developer.java.sun.com/developer/bugParade/bugs/4089701.html">
    *           4089701</A>, regarding this issue.
    *           
    */
  public synchronized int activeCount()
  {
    int total = 0;
    for (int i = 0; i < threads.size(); ++i)
      {
	if (((Thread) threads.elementAt(i)).isAlive ())
	  ++total;
      }

    for (int i=0; i < groups.size(); i++)
      {
        ThreadGroup g = (ThreadGroup) groups.elementAt(i);
        total += g.activeCount();
      }
    return total;
  }

  /** Get the number of active groups in this ThreadGroup.  This group
    * itself is not included in the count.
    * @specnote it is unclear what exactly constitutes an
    *		active ThreadGroup.  Currently we assume that
    *		all sub-groups are active, per current JDKs.
    * @return the number of active groups in this ThreadGroup.
    */
  public synchronized int activeGroupCount()
  {
    int total = groups.size();
    for (int i=0; i < groups.size(); i++)
      {
	ThreadGroup g = (ThreadGroup) groups.elementAt(i);
	total += g.activeGroupCount();
      }
    return total;
  }

  /** Copy all of the active Threads from this ThreadGroup and
    * its descendants into the specified array.  If the array is
    * not big enough to hold all the Threads, extra Threads will
    * simply not be copied.
    *
    * @param threads the array to put the threads into.
    * @return the number of threads put into the array.
    */
  public int enumerate(Thread[] threads)
  {
    return enumerate(threads, 0, true);
  }

  /** Copy all of the active Threads from this ThreadGroup and,
    * if desired, from its descendants, into the specified array.
    * If the array is not big enough to hold all the Threads,
    * extra Threads will simply not be copied.
    *
    * @param threads the array to put the threads into.
    * @param useDescendants whether to count Threads in this
    *	     ThreadGroup's descendants or not.
    * @return the number of threads put into the array.
    */
  public int enumerate(Thread[] threads, boolean useDescendants)
  {
    return enumerate(threads, 0, useDescendants);
  }

  // This actually implements enumerate.
  private synchronized int enumerate(Thread[] list, int next_index, 
				     boolean recurse)
  {
    Enumeration e = threads.elements();
    while (e.hasMoreElements() && next_index < list.length)
      {
	Thread t = (Thread) e.nextElement();
	if (t.isAlive ())
	  list[next_index++] = t;
      }
    if (recurse && next_index != list.length)
      {
	e = groups.elements();
	while (e.hasMoreElements() && next_index < list.length)
	  {
	    ThreadGroup g = (ThreadGroup) e.nextElement();
	    next_index = g.enumerate(list, next_index, true);
	  }
      }
    return next_index;
  }

  /** Copy all active ThreadGroups that are descendants of this
    * ThreadGroup into the specified array.  If the array is not
    * large enough to hold all active ThreadGroups, extra
    * ThreadGroups simply will not be copied.
    *
    * @param groups the array to put the ThreadGroups into.
    * @return the number of ThreadGroups copied into the array.
    */
  public int enumerate(ThreadGroup[] groups)
  {
    return enumerate(groups, 0, true);
  }

  /** Copy all active ThreadGroups that are children of this
    * ThreadGroup into the specified array, and if desired, also
    * copy all active descendants into the array.  If the array
    * is not large enough to hold all active ThreadGroups, extra
    * ThreadGroups simply will not be copied.
    *
    * @param groups the array to put the ThreadGroups into.
    * @param recurse whether to include all descendants
    *	     of this ThreadGroup's children in determining
    *	     activeness.
    * @return the number of ThreadGroups copied into the array.
    */
  public int enumerate(ThreadGroup[] groups, boolean recurse)
  {
    return enumerate(groups, 0, recurse);
  }

  // This actually implements enumerate.
  private synchronized int enumerate (ThreadGroup[] list, int next_index, 
				      boolean recurse)
  {
    Enumeration e = groups.elements();
    while (e.hasMoreElements() && next_index < list.length)
      {
	ThreadGroup g = (ThreadGroup) e.nextElement();
	list[next_index++] = g;
	if (recurse && next_index != list.length)
	  next_index = g.enumerate(list, next_index, true);
      }
    return next_index;
  }

  /** Interrupt all Threads in this ThreadGroup and its sub-groups.
    * @exception SecurityException if you cannot modify this
    *		 ThreadGroup or any of its Threads or children
    *		 ThreadGroups.
    * @since JDK1.2
    */
  public final synchronized void interrupt()
  {
    checkAccess();
    for (int i=0; i < threads.size(); i++)
      {
        Thread t = (Thread) threads.elementAt(i);
        t.interrupt();
      }
    for (int i=0; i < groups.size(); i++)
      {
        ThreadGroup tg = (ThreadGroup) groups.elementAt(i);
        tg.interrupt();
      }
  }

  /** Stop all Threads in this ThreadGroup and its descendants.
    * @exception SecurityException if you cannot modify this
    *		 ThreadGroup or any of its Threads or children
    *		 ThreadGroups.
    * @deprecated This method calls Thread.stop(), which is dangerous.
    */
  public final synchronized void stop()
  {
    checkAccess();
    for (int i=0; i<threads.size(); i++)
      {
        Thread t = (Thread) threads.elementAt(i);
	t.stop();
      }
    for (int i=0; i < groups.size(); i++)
      {
        ThreadGroup tg = (ThreadGroup) groups.elementAt(i);
        tg.stop();
      }
  }

  /** Suspend all Threads in this ThreadGroup and its descendants.
    * @exception SecurityException if you cannot modify this
    *		 ThreadGroup or any of its Threads or children
    *		 ThreadGroups.
    * @deprecated This method calls Thread.suspend(), which is dangerous.
    */
  public final synchronized void suspend()
  {
    checkAccess();
    for (int i=0; i<threads.size(); i++)
      {
        Thread t = (Thread) threads.elementAt(i);
        t.suspend();
      }
    for (int i=0; i < groups.size(); i++)
      {
        ThreadGroup tg = (ThreadGroup) groups.elementAt(i);
        tg.suspend();
      }
  }

  /** Resume all Threads in this ThreadGroup and its descendants.
    * @exception SecurityException if you cannot modify this
    *		 ThreadGroup or any of its Threads or children
    *		 ThreadGroups.
    * @deprecated This method relies on Thread.suspend(), which is dangerous.
    */
  public final synchronized void resume()
  {
    checkAccess();
    for (int i=0; i < threads.size(); i++)
      {
        Thread t = (Thread) threads.elementAt(i);
	t.resume();
      }
    for (int i=0; i < groups.size(); i++)
      {
        ThreadGroup tg = (ThreadGroup) groups.elementAt(i);
        tg.resume();
      }
  }

  // This is a helper that is used to implement the destroy method.
  private synchronized void checkDestroy ()
  {
    if (! threads.isEmpty())
      throw new IllegalThreadStateException ("ThreadGroup has threads");
    for (int i=0; i < groups.size(); i++)
      {
        ThreadGroup tg = (ThreadGroup) groups.elementAt(i);
	tg.checkDestroy();
      }
  }

  /** Destroy this ThreadGroup.  There can be no Threads in it,
    * and none of its descendants (sub-groups) may have Threads in them.
    * All its descendants will be destroyed as well.
    * @exception IllegalThreadStateException if the ThreadGroup or
    *		 its descendants have Threads remaining in them, or
    *		 if the ThreadGroup in question is already destroyed.
    * @exception SecurityException if you cannot modify this
    *		 ThreadGroup or any of its descendants.
    */
  public final synchronized void destroy()
  {
    checkAccess();
    if (isDestroyed())
      throw new IllegalThreadStateException("Already destroyed.");
    checkDestroy ();
    if (parent != null)
      parent.removeGroup(this);
    parent = null;

    for (int i=0; i < groups.size(); i++)
      {
        ThreadGroup tg = (ThreadGroup) groups.elementAt(i);
	tg.destroy();
      }
  }
  
  /** Print out information about this ThreadGroup to System.out.
    */
  public void list()
  {
    list("");
  }

  private synchronized void list(String indentation)
  {
    System.out.print(indentation);
    System.out.println(toString ());
    String sub = indentation + "    ";
    for (int i=0; i < threads.size(); i++)
      {
        Thread t = (Thread) threads.elementAt(i);
	System.out.print(sub);
	System.out.println(t.toString());
      }
    for (int i=0; i < groups.size(); i++)
      {
        ThreadGroup tg = (ThreadGroup) groups.elementAt(i);
	tg.list(sub);
      }
  }

  /** When a Thread in this ThreadGroup does not catch an exception,
    * this method of the ThreadGroup is called.<P>
    *
    * ThreadGroup's implementation does the following:<BR>
    * <OL>
    * <LI>If there is a parent ThreadGroup, call uncaughtException()
    *	  in the parent.</LI>
    * <LI>If the Throwable passed is a ThreadDeath, don't do
    *	  anything.</LI>
    * <LI>Otherwise, call <CODE>exception.printStackTrace().</CODE></LI>
    * </OL>
    *
    * @param thread the thread that exited.
    * @param exception the uncaught exception.
    */
  public void uncaughtException(Thread thread, Throwable t)
  {
    if (parent != null)
      parent.uncaughtException (thread, t);
    else if (! (t instanceof ThreadDeath))
      {
        if (thread != null)
          System.err.print ("Exception in thread \""
			    + thread.getName() + "\" ");
	try
	  {
	    t.printStackTrace(System.err);
	  }
	catch (Throwable x)
	  {
	    // This means that something is badly screwed up with the runtime,
	    // or perhaps someone is messing with the SecurityManager. In any
	    // case, try to deal with it gracefully.
	    System.err.println(t);
	    System.err.println("*** Got " + x.toString() + 
			       " while trying to print stack trace");
	  }
	had_uncaught_exception = true;
      }
  }

  /** Tell the VM whether it may suspend Threads in low memory
    * situations.
    * @deprecated This method is unimplemented, because it would rely on
    *		  suspend(), which is deprecated. There is no way for a Java
    *		  program to determine whether this has any effect whatsoever,
    *		  so we don't need it.
    * @return false
    */
  public boolean allowThreadSuspension(boolean allow)
  {
    return false;
  }

  /** Get a human-readable representation of this ThreadGroup.
    * @return a String representing this ThreadGroup.
    * @specnote 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.
    */
  public String toString ()
  {
    return "java.lang.ThreadGroup[name=" + name + 
           ",maxpri=" + maxpri + "]";
  }

  /** Find out if the current Thread can modify this ThreadGroup.
    * Calls the current SecurityManager's checkAccess() method to
    * find out.  If there is none, it assumes everything's OK.
    * @exception SecurityException if the current Thread cannot
    *		 modify this ThreadGroup.
    */
  public final void checkAccess()
  {
    SecurityManager sm = System.getSecurityManager();
    if (sm != null)
      sm.checkAccess(this);
  }

  // This is called to add a Thread to our internal list.
  final synchronized void addThread(Thread t)
  {
    if (isDestroyed())
      throw new IllegalThreadStateException ("ThreadGroup is destroyed");
  
    threads.addElement(t);
  }

  // This is called to remove a Thread from our internal list.
  final synchronized void removeThread(Thread t)
  {
    if (isDestroyed())
      throw new IllegalThreadStateException ();
  
    threads.removeElement(t);
    // Daemon groups are automatically destroyed when all their threads die.
    if (daemon_flag && groups.size() == 0 && threads.size() == 0)
      {
	// We inline destroy to avoid the access check.
	if (parent != null)
	  parent.removeGroup(this);
	parent = null;
      }
  }

  // This is called to add a ThreadGroup to our internal list.
  final synchronized void addGroup(ThreadGroup g)
  {
    groups.addElement(g);
  }

  // This is called to remove a ThreadGroup from our internal list.
  final synchronized void removeGroup(ThreadGroup g)
  {
    groups.removeElement(g);
    // Daemon groups are automatically destroyed when all their threads die.
    if (daemon_flag && groups.size() == 0 && threads.size() == 0)
      {
	// We inline destroy to avoid the access check.
	if (parent != null)
	  parent.removeGroup(this);
	parent = null;
      }
  }
}
