/* 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., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 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 = SecurityManager.current;
    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
