/* 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.lang.Thread.UncaughtExceptionHandler;
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 implements UncaughtExceptionHandler
{
  /** 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. */
  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 (Thread.getDefaultUncaughtExceptionHandler() != null)
      Thread.getDefaultUncaughtExceptionHandler().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);
      }
  }

  /*
   * Helper method for the VM. Find a Thread by its Id.
   *
   * @param id The Thread Id.
   * @return Thread object or null if thread doesn't exist.
   */
  static Thread getThreadFromId(long id)
  {
    return root.getThreadFromIdImpl(id);
  }

  private Thread getThreadFromIdImpl(long id)
  {
    synchronized (threads)
      {
        for (int i = 0; i < threads.size(); i++)
          {
            Thread t = (Thread) threads.get(i);
            if (t.getId() == id)
              return t;
          }
      }
    Vector groups = this.groups;
    if (groups != null)
      {
        synchronized (groups)
          {
            for (int i = 0; i < groups.size(); i++)
              {
                ThreadGroup g = (ThreadGroup) groups.get(i);
                Thread t = g.getThreadFromIdImpl(id);
                if (t != null)
                  return t;
              }
          }
      }
    return null;
  }
} // class ThreadGroup
