// Thread.java - Thread class.

/* Copyright (C) 1998, 1999, 2000  Free Software Foundation

   This file is part of libgcj.

This software is copyrighted work licensed under the terms of the
Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
details.  */

package java.lang;

/**
 * @author Tom Tromey <tromey@cygnus.com>
 * @date August 24, 1998 
 */

/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
 * "The Java Language Specification", ISBN 0-201-63451-1
 * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
 * Status:  Believed complete to version 1.3, with caveats. We do not 
 *          implement the deprecated (and dangerous) stop, suspend, and resume
 *          methods. Security implementation is not complete.
 */

public class Thread implements Runnable
{
  public final static int MAX_PRIORITY = 10;
  public final static int MIN_PRIORITY = 1;
  public final static int NORM_PRIORITY = 5;

  public static int activeCount ()
  {
    return currentThread().getThreadGroup().activeCount();
  }

  public final void checkAccess ()
  {
    SecurityManager s = System.getSecurityManager();
    if (s != null)
      s.checkAccess(this);
  }

  public native int countStackFrames ();
  public static native Thread currentThread ();
  public native void destroy ();
  
  public static void dumpStack ()
  {
    (new Exception ("Stack trace")).printStackTrace ();
  }

  public static int enumerate (Thread[] threads)
  {
    return currentThread().group.enumerate(threads);
  }

  public final String getName ()
  {
    return name;
  }

  public final int getPriority ()
  {
    return priority;
  }

  public final ThreadGroup getThreadGroup ()
  {
    return group;
  }

  public native void interrupt ();

  public static boolean interrupted ()
  {
    return currentThread().isInterrupted (true);
  }

  // Check the threads interrupted status. Note that this does not clear the
  // thread's interrupted status (per JDK 1.2 online API documentation).
  public boolean isInterrupted ()
  {
    return interrupt_flag;
  }

  public final boolean isAlive ()
  {
    return alive_flag;
  }

  public final boolean isDaemon ()
  {
    return daemon_flag;
  }

  public final void join () throws InterruptedException
  {
    join (0, 0);
  }

  public final void join (long timeout) throws InterruptedException
  {
    join (timeout, 0);
  }

  public final native void join (long timeout, int nanos)
    throws InterruptedException;

  public final native void resume ();

  // This method exists only to avoid a warning from the C++ compiler.
  private static final native void run_ (Object obj);
  private final native void finish_ ();

  // Check the thread's interrupted status. If clear_flag is true, the 
  // thread's interrupted status is also cleared.
  private boolean isInterrupted (boolean clear_flag)
  {
    boolean r = interrupt_flag;
    if (clear_flag && r)
      {
	// Only clear the flag if we saw it as set. Otherwise this could 
	// potentially cause us to miss an interrupt in a race condition, 
	// because this method is not synchronized.
	interrupt_flag = false;
      }
    return r;
  }
  
  public void run ()
  {
    if (runnable != null)
      runnable.run();
  }

  public final void setDaemon (boolean status)
  {
    checkAccess ();
    if (isAlive ())
      throw new IllegalThreadStateException ();
    daemon_flag = status;
  }

  public synchronized ClassLoader getContextClassLoader()
  {
    if (context_class_loader == null)
      context_class_loader = ClassLoader.getSystemClassLoader ();

    SecurityManager s = System.getSecurityManager();
    // FIXME: we can't currently find the caller's class loader.
    ClassLoader callers = null;
    if (s != null && callers != null)
      {
	// See if the caller's class loader is the same as or an
	// ancestor of this thread's class loader.
	while (callers != null && callers != context_class_loader)
	  {
	    // FIXME: should use some internal version of getParent
	    // that avoids security checks.
	    callers = callers.getParent ();
	  }

	if (callers != context_class_loader)
	  s.checkPermission (new RuntimePermission ("getClassLoader"));
      }

    return context_class_loader;
  }

  public synchronized void setContextClassLoader(ClassLoader cl)
  {
    SecurityManager s = System.getSecurityManager ();
    if (s != null)
      s.checkPermission (new RuntimePermission ("setContextClassLoader"));
    context_class_loader = cl;
  }

  public final void setName (String n)
  {
    checkAccess ();
    // The Class Libraries book says ``threadName cannot be null''.  I
    // take this to mean NullPointerException.
    if (n == null)
      throw new NullPointerException ();
    name = n;
  }

  public final native void setPriority (int newPriority);

  public static void sleep (long timeout) throws InterruptedException
  {
    sleep (timeout, 0);
  }

  public static native void sleep (long timeout, int nanos)
    throws InterruptedException;
  public synchronized native void start ();

  public final void stop ()
  {
    // Argument doesn't matter, because this is no longer
    // supported.
    stop (null);
  }

  public final synchronized native void stop (Throwable e);
  public final native void suspend ();

  private final native void initialize_native ();

  private final synchronized static String gen_name ()
  {
    String n;
    n = "Thread-" + nextThreadNumber;
    ++nextThreadNumber;
    return n;
  }

  public Thread (ThreadGroup g, Runnable r, String n)
  {
    Thread current = currentThread ();
          
    if (g == null)
      {
	// If CURRENT is null, then we are bootstrapping the first thread. 
	// Use ThreadGroup.root, the main threadgroup.
	if (current == null)
	  group = ThreadGroup.root;
	else
	  group = current.getThreadGroup();
      }
    else
      group = g;
      
    group.checkAccess();

    // The Class Libraries book says ``threadName cannot be null''.  I
    // take this to mean NullPointerException.
    if (n == null)
      throw new NullPointerException ();

    name = n;
    group.addThread(this);
    runnable = r;

    data = null;
    interrupt_flag = false;
    alive_flag = false;
    startable_flag = true;

    if (current != null)
      {
	daemon_flag = current.isDaemon();
        int gmax = group.getMaxPriority();
	int pri = current.getPriority();
	priority = (gmax < pri ? gmax : pri);
	context_class_loader = current.context_class_loader;
      }
    else
      {
	daemon_flag = false;
	priority = NORM_PRIORITY;
      }

    initialize_native ();
  }

  public Thread ()
  {
    this (null, null, gen_name ());
  }

  public Thread (Runnable r)
  {
    this (null, r, gen_name ());
  }

  public Thread (String n)
  {
    this (null, null, n);
  }

  public Thread (ThreadGroup g, Runnable r)
  {
    this (g, r, gen_name ());
  }

  public Thread (ThreadGroup g, String n)
  {
    this (g, null, n);
  }

  public Thread (Runnable r, String n)
  {
    this (null, r, n);
  }

  public String toString ()
  {
    return "Thread[" + name + "," + priority + "," + 
      (group == null ? "" : group.getName()) + "]";
  }

  public static native void yield ();

  // Private data.
  private ThreadGroup group;
  private String name;
  private Runnable runnable;
  private int priority;
  private boolean daemon_flag;
  boolean interrupt_flag;
  private boolean alive_flag;
  private boolean startable_flag;
  private ClassLoader context_class_loader;

  // Our native data.
  private Object data;

  // Next thread number to assign.
  private static int nextThreadNumber = 0;
}
