/* ThreadGroup -- a group of Threads
   Copyright (C) 1998, 2000, 2001, 2002, 2005  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.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */

package java.lang;

import java.util.Vector;

/**
 * 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
 * @author Eric Blake (ebb9@email.byu.edu)
 * @see Thread
 * @since 1.0
 * @status updated to 1.4
 */
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;

  /** The parent thread group. */
  private final ThreadGroup parent;

  /** The group name, non-null. */
  final String name;

  /** The threads in the group. */
  private final Vector threads = new Vector();

  /** Child thread groups, or null when this group is destroyed. */
  private Vector groups = new Vector();

  /** If all threads in the group are daemons. */
  private boolean daemon_flag = false;

  /** The maximum group priority. */
  private int maxpri;

  /**
   * Hidden constructor to build the root node.
   */
  private ThreadGroup()
  {
    name = "main";
    parent = null;
    maxpri = Thread.MAX_PRIORITY;
  }

  /**
   * Create a new ThreadGroup using the given name and the current thread's
   * ThreadGroup as a parent. There may be a security check,
   * <code>checkAccess</code>.
   *
   * @param name the name to use for the ThreadGroup
   * @throws SecurityException if the current thread cannot create a group
   * @see #checkAccess()
   */
  public ThreadGroup(String name)
  {
    this(Thread.currentThread().group, name);
  }

  /**
   * Create a new ThreadGroup using the given name and parent group. The new
   * group inherits the maximum priority and daemon status of its parent
   * group. There may be a security check, <code>checkAccess</code>.
   *
   * @param name the name to use for the ThreadGroup
   * @param parent the ThreadGroup to use as a parent
   * @throws NullPointerException if parent is null
   * @throws SecurityException if the current thread cannot create a group
   * @throws IllegalThreadStateException if the parent is destroyed
   * @see #checkAccess()
   */
  public ThreadGroup(ThreadGroup parent, String name)
  {
    parent.checkAccess();
    this.parent = parent;
    this.name = name;
    maxpri = parent.maxpri;
    daemon_flag = parent.daemon_flag;
    synchronized (parent)
      {
        if (parent.groups == null)
          throw new IllegalThreadStateException();
        parent.groups.add(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. If the parent is not null, there
   * may be a security check, <code>checkAccess</code>.
   *
   * @return the parent of this ThreadGroup
   * @throws SecurityException if permission is denied
   */
  public final ThreadGroup getParent()
  {
    if (parent != null)
      parent.checkAccess();
    return parent;
  }

  /**
   * Get the maximum priority of Threads in this ThreadGroup. Threads created
   * after this call in this group may not exceed this priority.
   *
   * @return the maximum priority of Threads in this ThreadGroup
   */
  public final int getMaxPriority()
  {
    return maxpri;
  }

  /**
   * Tell whether this ThreadGroup is a daemon group.  A daemon group will
   * be automatically destroyed when its last thread is stopped and
   * its last thread group is destroyed.
   *
   * @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
   * @since 1.1
   */
  public synchronized boolean isDestroyed()
  {
    return groups == null;
  }

  /**
   * 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. There may be a security check, <code>checkAccess</code>.
   *
   * @param daemon whether this ThreadGroup should be a daemon group
   * @throws SecurityException if you cannot modify this ThreadGroup
   * @see #checkAccess()
   */
  public final void setDaemon(boolean daemon)
  {
    checkAccess();
    daemon_flag = daemon;
  }

  /**
   * 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 of the parent group, the current value is not
   * changed. Otherwise, all groups which belong to this have their priority
   * adjusted as well. Calling this does not affect threads already in this
   * ThreadGroup. There may be a security check, <code>checkAccess</code>.
   *
   * @param maxpri the new maximum priority for this ThreadGroup
   * @throws SecurityException if you cannot modify this ThreadGroup
   * @see #getMaxPriority()
   * @see #checkAccess()
   */
  public final synchronized void setMaxPriority(int maxpri)
  {
    checkAccess();
    if (maxpri < Thread.MIN_PRIORITY || maxpri > Thread.MAX_PRIORITY)
      return;
    if (parent != null && maxpri > parent.maxpri)
      maxpri = parent.maxpri;
    this.maxpri = maxpri;
    if (groups == null)
      return;
    int i = groups.size();
    while (--i >= 0)
      ((ThreadGroup) groups.get(i)).setMaxPriority(maxpri);
  }

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

  /**
   * Find out if the current Thread can modify this ThreadGroup. This passes
   * the check on to <code>SecurityManager.checkAccess(this)</code>.
   *
   * @throws SecurityException if the current Thread cannot modify this
   *         ThreadGroup
   * @see SecurityManager#checkAccess(ThreadGroup)
   */
  public final void checkAccess()
  {
    // Bypass System.getSecurityManager, for bootstrap efficiency.
    SecurityManager sm = Runtime.securityManager;
    if (sm != null)
      sm.checkAccess(this);
  }

  /**
   * Return an estimate of the total number of active threads in this
   * ThreadGroup and all its descendants. This cannot return an exact number,
   * since the status of threads may change after they were counted; but it
   * should be pretty close. Based on a JDC bug,
   * <a href="http://developer.java.sun.com/developer/bugParade/bugs/4089701.html">
   * 4089701</a>, we take active to mean isAlive().
   *
   * @return count of active threads in this ThreadGroup and its descendants
   */
  public int activeCount()
  {
    int total = 0;
    if (groups == null)
      return total;
    int i = threads.size();
    while (--i >= 0)
      if (((Thread) threads.get(i)).isAlive())
        total++;
    i = groups.size();
    while (--i >= 0)
      total += ((ThreadGroup) groups.get(i)).activeCount();
    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. There may be a
   * security check, <code>checkAccess</code>.
   *
   * @param array the array to put the threads into
   * @return the number of threads put into the array
   * @throws SecurityException if permission was denied
   * @throws NullPointerException if array is null
   * @throws ArrayStoreException if a thread does not fit in the array
   * @see #activeCount()
   * @see #checkAccess()
   * @see #enumerate(Thread[], boolean)
   */
  public int enumerate(Thread[] array)
  {
    return enumerate(array, 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.
   * There may be a security check, <code>checkAccess</code>.
   *
   * @param array the array to put the threads into
   * @param recurse whether to recurse into descendent ThreadGroups
   * @return the number of threads put into the array
   * @throws SecurityException if permission was denied
   * @throws NullPointerException if array is null
   * @throws ArrayStoreException if a thread does not fit in the array
   * @see #activeCount()
   * @see #checkAccess()
   */
  public int enumerate(Thread[] array, boolean recurse)
  {
    return enumerate(array, 0, recurse);
  }

  /**
   * Get the number of active groups in this ThreadGroup.  This group itself
   * is not included in the count. A sub-group is active if it has not been
   * destroyed. This cannot return an exact number, since the status of
   * threads may change after they were counted; but it should be pretty close.
   *
   * @return the number of active groups in this ThreadGroup
   */
  public int activeGroupCount()
  {
    if (groups == null)
      return 0;
    int total = groups.size();
    int i = total;
    while (--i >= 0)
      total += ((ThreadGroup) groups.get(i)).activeGroupCount();
    return total;
  }

  /**
   * 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. There
   * may be a security check, <code>checkAccess</code>.
   *
   * @param array the array to put the ThreadGroups into
   * @return the number of ThreadGroups copied into the array
   * @throws SecurityException if permission was denied
   * @throws NullPointerException if array is null
   * @throws ArrayStoreException if a group does not fit in the array
   * @see #activeCount()
   * @see #checkAccess()
   * @see #enumerate(ThreadGroup[], boolean)
   */
  public int enumerate(ThreadGroup[] array)
  {
    return enumerate(array, 0, true);
  }

  /**
   * Copy all active ThreadGroups that are children of this ThreadGroup into
   * the specified array, and if desired, also all descendents.  If the array
   * is not large enough to hold all active ThreadGroups, extra ThreadGroups
   * simply will not be copied. There may be a security check,
   * <code>checkAccess</code>.
   *
   * @param array the array to put the ThreadGroups into
   * @param recurse whether to recurse into descendent ThreadGroups
   * @return the number of ThreadGroups copied into the array
   * @throws SecurityException if permission was denied
   * @throws NullPointerException if array is null
   * @throws ArrayStoreException if a group does not fit in the array
   * @see #activeCount()
   * @see #checkAccess()
   */
  public int enumerate(ThreadGroup[] array, boolean recurse)
  {
    return enumerate(array, 0, recurse);
  }

  /**
   * Stop all Threads in this ThreadGroup and its descendants.
   *
   * <p>This is inherently unsafe, as it can interrupt synchronized blocks and
   * leave data in bad states.  Hence, there is a security check:
   * <code>checkAccess()</code>, followed by further checks on each thread
   * being stopped.
   *
   * @throws SecurityException if permission is denied
   * @see #checkAccess()
   * @see Thread#stop(Throwable)
   * @deprecated unsafe operation, try not to use
   */
  public final synchronized void stop()
  {
    checkAccess();
    if (groups == null)
      return;
    int i = threads.size();
    while (--i >= 0)
      ((Thread) threads.get(i)).stop();
    i = groups.size();
    while (--i >= 0)
      ((ThreadGroup) groups.get(i)).stop();
  }

  /**
   * Interrupt all Threads in this ThreadGroup and its sub-groups. There may
   * be a security check, <code>checkAccess</code>.
   *
   * @throws SecurityException if permission is denied
   * @see #checkAccess()
   * @see Thread#interrupt()
   * @since 1.2
   */
  public final synchronized void interrupt()
  {
    checkAccess();
    if (groups == null)
      return;
    int i = threads.size();
    while (--i >= 0)
      ((Thread) threads.get(i)).interrupt();
    i = groups.size();
    while (--i >= 0)
      ((ThreadGroup) groups.get(i)).interrupt();
  }

  /**
   * Suspend all Threads in this ThreadGroup and its descendants.
   *
   * <p>This is inherently unsafe, as suspended threads still hold locks,
   * which can lead to deadlock.  Hence, there is a security check:
   * <code>checkAccess()</code>, followed by further checks on each thread
   * being suspended.
   *
   * @throws SecurityException if permission is denied
   * @see #checkAccess()
   * @see Thread#suspend()
   * @deprecated unsafe operation, try not to use
   */
  public final synchronized void suspend()
  {
    checkAccess();
    if (groups == null)
      return;
    int i = threads.size();
    while (--i >= 0)
      ((Thread) threads.get(i)).suspend();
    i = groups.size();
    while (--i >= 0)
      ((ThreadGroup) groups.get(i)).suspend();
  }

  /**
   * Resume all suspended Threads in this ThreadGroup and its descendants.
   * To mirror suspend(), there is a security check:
   * <code>checkAccess()</code>, followed by further checks on each thread
   * being resumed.
   *
   * @throws SecurityException if permission is denied
   * @see #checkAccess()
   * @see Thread#suspend()
   * @deprecated pointless, since suspend is deprecated
   */
  public final synchronized void resume()
  {
    checkAccess();
    if (groups == null)
      return;
    int i = threads.size();
    while (--i >= 0)
      ((Thread) threads.get(i)).resume();
    i = groups.size();
    while (--i >= 0)
      ((ThreadGroup) groups.get(i)).resume();
  }

  /**
   * Destroy this ThreadGroup.  The group must be empty, meaning that all
   * threads and sub-groups have completed execution. Daemon groups are
   * destroyed automatically. There may be a security check,
   * <code>checkAccess</code>.
   *
   * @throws IllegalThreadStateException if the ThreadGroup is not empty, or
   *         was previously destroyed
   * @throws SecurityException if permission is denied
   * @see #checkAccess()
   */
  public final synchronized void destroy()
  {
    checkAccess();
    if (! threads.isEmpty() || groups == null)
      throw new IllegalThreadStateException();
    int i = groups.size();
    while (--i >= 0)
      ((ThreadGroup) groups.get(i)).destroy();
    groups = null;
    if (parent != null)
      parent.removeGroup(this);
  }

  /**
   * Print out information about this ThreadGroup to System.out. This is
   * meant for debugging purposes. <b>WARNING:</b> This method is not secure,
   * and can print the name of threads to standard out even when you cannot
   * otherwise get at such threads.
   */
  public void list()
  {
    list("");
  }

  /**
   * When a Thread in this ThreadGroup does not catch an exception, the
   * virtual machine calls this method. The default implementation simply
   * passes the call to the parent; then in top ThreadGroup, it will
   * ignore ThreadDeath and print the stack trace of any other throwable.
   * Override this method if you want to handle the exception in a different
   * manner.
   *
   * @param thread the thread that exited
   * @param t the uncaught throwable
   * @throws NullPointerException if t is null
   * @see ThreadDeath
   * @see System#err
   * @see Throwable#printStackTrace()
   */
  public void uncaughtException(Thread thread, Throwable t)
  {
    if (parent != null)
      parent.uncaughtException(thread, t);
    else if (! (t instanceof ThreadDeath))
      {
        if (t == null)
          throw new NullPointerException();
        had_uncaught_exception = true;
        try
          {
            if (thread != null)
              System.err.print("Exception in thread \"" + thread.name + "\" ");
            t.printStackTrace(System.err);
          }
        catch (Throwable x)
          {
            // This means that something is badly screwed up with the runtime,
            // or perhaps someone overloaded the Throwable.printStackTrace to
            // die. In any case, try to deal with it gracefully.
            try
              {
                System.err.println(t);
                System.err.println("*** Got " + x
                                   + " while trying to print stack trace.");
              }
            catch (Throwable x2)
              {
                // Here, someone may have overloaded t.toString() or
                // x.toString() to die. Give up all hope; we can't even chain
                // the exception, because the chain would likewise die.
                System.err.println("*** Catastrophic failure while handling "
                                   + "uncaught exception.");
                throw new InternalError();
              }
          }
      }
  }

  /**
   * Originally intended to tell the VM whether it may suspend Threads in
   * low memory situations, this method was never implemented by Sun, and
   * is hence a no-op.
   *
   * @param allow whether to allow low-memory thread suspension; ignored
   * @return false
   * @since 1.1
   * @deprecated pointless, since suspend is deprecated
   */
  public boolean allowThreadSuspension(boolean allow)
  {
    return false;
  }

  /**
   * Return a human-readable String representing this ThreadGroup. The format
   * of the string is:<br>
   * <code>getClass().getName() + "[name=" + getName() + ",maxpri="
   * + getMaxPriority() + ']'</code>.
   *
   * @return a human-readable String representing this ThreadGroup
   */
  public String toString()
  {
    return getClass().getName() + "[name=" + name + ",maxpri=" + maxpri + ']';
  }

  /**
   * Implements enumerate.
   *
   * @param list the array to put the threads into
   * @param next the next open slot in the array
   * @param recurse whether to recurse into descendent ThreadGroups
   * @return the number of threads put into the array
   * @throws SecurityException if permission was denied
   * @throws NullPointerException if list is null
   * @throws ArrayStoreException if a thread does not fit in the array
   * @see #enumerate(Thread[])
   * @see #enumerate(Thread[], boolean)
   */
  private int enumerate(Thread[] list, int next, boolean recurse)
  {
    checkAccess();
    if (groups == null)
      return next;
    int i = threads.size();
    while (--i >= 0 && next < list.length)
      {
        Thread t = (Thread) threads.get(i);
        if (t.isAlive())
          list[next++] = t;
      }
    if (recurse)
      {
        i = groups.size();
        while (--i >= 0 && next < list.length)
          {
            ThreadGroup g = (ThreadGroup) groups.get(i);
            next = g.enumerate(list, next, true);
          }
      }
    return next;
  }

  /**
   * Implements enumerate.
   *
   * @param list the array to put the groups into
   * @param next the next open slot in the array
   * @param recurse whether to recurse into descendent ThreadGroups
   * @return the number of groups put into the array
   * @throws SecurityException if permission was denied
   * @throws NullPointerException if list is null
   * @throws ArrayStoreException if a group does not fit in the array
   * @see #enumerate(ThreadGroup[])
   * @see #enumerate(ThreadGroup[], boolean)
   */
  private int enumerate(ThreadGroup[] list, int next, boolean recurse)
  {
    checkAccess();
    if (groups == null)
      return next;
    int i = groups.size();
    while (--i >= 0 && next < list.length)
      {
        ThreadGroup g = (ThreadGroup) groups.get(i);
        list[next++] = g;
        if (recurse && next != list.length)
          next = g.enumerate(list, next, true);
      }
    return next;
  }

  /**
   * Implements list.
   *
   * @param indentation the current level of indentation
   * @see #list()
   */
  private void list(String indentation)
  {
    if (groups == null)
      return;
    System.out.println(indentation + this);
    indentation += "    ";
    int i = threads.size();
    while (--i >= 0)
      System.out.println(indentation + threads.get(i));
    i = groups.size();
    while (--i >= 0)
      ((ThreadGroup) groups.get(i)).list(indentation);
  }

  /**
   * Add a thread to the group. Called by Thread constructors.
   *
   * @param t the thread to add, non-null
   * @throws IllegalThreadStateException if the group is destroyed
   */
  final synchronized void addThread(Thread t)
  {
    if (groups == null)
      throw new IllegalThreadStateException("ThreadGroup is destroyed");
    threads.add(t);
  }

  /**
   * Called by the VM to remove a thread that has died.
   *
   * @param t the thread to remove, non-null
   * @XXX A ThreadListener to call this might be nice.
   */
  final synchronized void removeThread(Thread t)
  {
    if (groups == null)
      return;
    threads.remove(t);
    t.group = null;
    // 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.
        groups = null;
        if (parent != null)
          parent.removeGroup(this);
      }
  }

  /**
   * Called when a group is destroyed, to remove it from its parent.
   *
   * @param g the destroyed group, non-null
   */
  final synchronized void removeGroup(ThreadGroup g)
  {
    groups.remove(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.
        groups = null;
        if (parent != null)
          parent.removeGroup(this);
      }
  }
} // class ThreadGroup
