|
From: <ls...@us...> - 2009-04-02 19:01:08
|
Revision: 5210
http://jnode.svn.sourceforge.net/jnode/?rev=5210&view=rev
Author: lsantha
Date: 2009-04-02 19:01:01 +0000 (Thu, 02 Apr 2009)
Log Message:
-----------
Separating jnode os code from classlib.
Modified Paths:
--------------
trunk/all/conf/openjdk-annotations.properties
trunk/core/src/core/org/jnode/debugger/DebuggerUtils.java
trunk/core/src/core/org/jnode/debugger/ThreadListState.java
trunk/core/src/core/org/jnode/debugger/ThreadState.java
trunk/core/src/core/org/jnode/vm/isolate/VmIsolate.java
trunk/core/src/core/org/jnode/vm/scheduler/IRQThread.java
trunk/core/src/openjdk/vm/java/lang/reflect/NativeProxy.java
trunk/core/src/openjdk/vm/sun/misc/NativeUnsafe.java
trunk/core/src/test/org/jnode/test/core/StackView.java
trunk/shell/src/shell/org/jnode/shell/command/ThreadCommand.java
Added Paths:
-----------
trunk/core/src/classpath/java/java/lang/ClassLoader.java
trunk/core/src/classpath/java/java/lang/Thread.java
trunk/core/src/classpath/vm/java/lang/NativeClassLoader.java
trunk/core/src/classpath/vm/java/lang/NativeThread.java
trunk/core/src/classpath/vm/java/lang/ThreadHelper.java
Removed Paths:
-------------
trunk/core/src/classpath/vm/java/lang/ClassLoader.java
trunk/core/src/classpath/vm/java/lang/Thread.java
Modified: trunk/all/conf/openjdk-annotations.properties
===================================================================
--- trunk/all/conf/openjdk-annotations.properties 2009-04-01 18:57:30 UTC (rev 5209)
+++ trunk/all/conf/openjdk-annotations.properties 2009-04-02 19:01:01 UTC (rev 5210)
@@ -9,6 +9,7 @@
java/awt/image/DataBuffer.class=SharedStatics
java/awt/KeyboardFocusManager.class=SharedStatics
java/awt/Toolkit.class=SharedStatics
+java/lang/Thread.class=SharedStatics
java/lang/ThreadLocal.class=SharedStatics
java/lang/Throwable.class=MagicPermission
java/net/InetAddress.class=SharedStatics
Copied: trunk/core/src/classpath/java/java/lang/ClassLoader.java (from rev 5209, trunk/core/src/classpath/vm/java/lang/ClassLoader.java)
===================================================================
--- trunk/core/src/classpath/java/java/lang/ClassLoader.java (rev 0)
+++ trunk/core/src/classpath/java/java/lang/ClassLoader.java 2009-04-02 19:01:01 UTC (rev 5210)
@@ -0,0 +1,950 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2003-2009 JNode.org
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; If not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+package java.lang;
+
+import gnu.classpath.SystemProperties;
+import gnu.java.util.EmptyEnumeration;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.nio.ByteBuffer;
+import java.security.AccessController;
+import java.security.CodeSource;
+import java.security.PermissionCollection;
+import java.security.Policy;
+import java.security.PrivilegedAction;
+import java.security.ProtectionDomain;
+import java.security.cert.Certificate;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import sun.reflect.Reflection;
+
+public abstract class ClassLoader {
+
+ private final ClassLoader parent;
+
+ //this is always a VmClassLoaderInstance
+ final Object vmClassLoader;
+
+ private ProtectionDomain defaultProtectionDomain;
+
+ /**
+ * All packages defined by this classloader. It is not private in order to
+ * allow native code (and trusted subclasses) access to this field.
+ */
+ final HashMap<String, Package> definedPackages = new HashMap<String, Package>();
+
+ /**
+ * The desired assertion status of classes loaded by this loader, if not
+ * overridden by package or class instructions.
+ */
+ // Package visible for use by Class.
+ boolean defaultAssertionStatus = VMClassLoader.defaultAssertionStatus();
+
+ /**
+ * The map of package assertion status overrides, or null if no package
+ * overrides have been specified yet. The values of the map should be
+ * Boolean.TRUE or Boolean.FALSE, and the unnamed package is represented by
+ * the null key. This map must be synchronized on this instance.
+ */
+ // Package visible for use by Class.
+ Map<String, Boolean> packageAssertionStatus;
+
+ /**
+ * The map of class assertion status overrides, or null if no class
+ * overrides have been specified yet. The values of the map should be
+ * Boolean.TRUE or Boolean.FALSE. This map must be synchronized on this
+ * instance.
+ */
+ // Package visible for use by Class.
+ Map<String, Boolean> classAssertionStatus;
+
+ static class StaticData {
+ /**
+ * The System Class Loader (a.k.a. Application Class Loader). The one
+ * returned by ClassLoader.getSystemClassLoader.
+ */
+ static final ClassLoader systemClassLoader = VMClassLoader
+ .getSystemClassLoader();
+ static {
+ // Find out if we have to install a default security manager. Note
+ // that
+ // this is done here because we potentially need the system class
+ // loader
+ // to load the security manager and note also that we don't need the
+ // security manager until the system class loader is created.
+ // If the runtime chooses to use a class loader that doesn't have
+ // the
+ // system class loader as its parent, it is responsible for setting
+ // up a security manager before doing so.
+ String secman = SystemProperties
+ .getProperty("java.security.manager");
+ if (secman != null && SecurityManager.current == null) {
+ if (secman.equals("") || secman.equals("default")) {
+ SecurityManager.current = new SecurityManager();
+ } else {
+ try {
+ Class< ? > cl = Class.forName(secman, false,
+ StaticData.systemClassLoader);
+ SecurityManager.current = (SecurityManager) cl
+ .newInstance();
+ } catch (Exception x) {
+ throw (InternalError) new InternalError(
+ "Unable to create SecurityManager")
+ .initCause(x);
+ }
+ }
+ }
+ }
+
+ /**
+ * The default protection domain, used when defining a class with a null
+ * parameter for the domain.
+ */
+ static final ProtectionDomain defaultProtectionDomain;
+ static {
+ final CodeSource cs = new CodeSource(null, (Certificate[])null);
+ PermissionCollection perm = AccessController
+ .doPrivileged(new PrivilegedAction<PermissionCollection>() {
+ public PermissionCollection run() {
+ return Policy.getPolicy().getPermissions(cs);
+ }
+ });
+ defaultProtectionDomain = new ProtectionDomain(cs, perm);
+ }
+
+ /**
+ * The command-line state of the package assertion status overrides.
+ * This map is never modified, so it does not need to be synchronized.
+ */
+ // Package visible for use by Class.
+ static final Map<String, Boolean> systemPackageAssertionStatus = VMClassLoader
+ .packageAssertionStatus();
+
+ /**
+ * The command-line state of the class assertion status overrides. This
+ * map is never modified, so it does not need to be synchronized.
+ */
+ // Package visible for use by Class.
+ static final Map<String, Boolean> systemClassAssertionStatus = VMClassLoader
+ .classAssertionStatus();
+ }
+
+ /**
+ * Create a new ClassLoader with the specified parent. The parent will be
+ * consulted when a class or resource is requested through
+ * <code>loadClass()</code> or <code>getResource()</code>. Only when
+ * the parent classloader cannot provide the requested class or resource the
+ * <code>findClass()</code> or <code>findResource()</code> method of
+ * this classloader will be called. There may be a security check for
+ * <code>checkCreateClassLoader</code>.
+ *
+ * @param parent
+ * the classloader's parent
+ * @throws SecurityException
+ * if the security check fails
+ * @since 1.2
+ */
+ protected ClassLoader(ClassLoader parent) {
+ /* May we create a new classloader? */
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkCreateClassLoader();
+ }
+ this.parent = parent;
+ this.vmClassLoader = createVmJavaClassLoader0(this);
+ }
+
+ private static native Object createVmJavaClassLoader0(ClassLoader instance);
+
+ /**
+ * Create a new instance
+ *
+ */
+ protected ClassLoader() {
+ this(getSystemClassLoader());
+ }
+
+ /**
+ * Create a new classloader wrapped around a given VmClassLoader.
+ *
+ * @param vmClassLoader
+ */
+ protected ClassLoader(Object vmClassLoader, int discriminator) {
+ /* May we create a new classloader? */
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkCreateClassLoader();
+ }
+ if (vmClassLoader == null) {
+ throw new IllegalArgumentException("vmClassLoader cannot be null");
+ }
+ checkArg0(vmClassLoader);
+ this.parent = null;
+ this.vmClassLoader = vmClassLoader;
+ }
+
+ private static native void checkArg0(Object vmClassLoader);
+
+ /**
+ * Create a new classloader wrapped around a given VmClassLoader,
+ * with a given parent loader.
+ *
+ * @param vmClassLoader
+ */
+ protected ClassLoader(ClassLoader parent, Object vmClassLoader) {
+ /* May we create a new classloader? */
+ checkArgs0(vmClassLoader);
+ this.parent = parent;
+ this.vmClassLoader = vmClassLoader;
+ }
+
+ private static native void checkArgs0(Object vmClassLoader);
+
+ /**
+ * Gets the VmClassLoader that is used by this classloader.
+ * This method requires special permission.
+ * @return
+ */
+ public final Object getVmClassLoader() {
+ return getVmClassLoader0();
+ }
+
+ private native Object getVmClassLoader0();
+
+ /**
+ * Load and resolve a class with a given name.
+ *
+ * @param name
+ * @return Class
+ * @throws ClassNotFoundException
+ */
+ public Class loadClass(String name) throws ClassNotFoundException {
+ // return vmClassLoader.loadClass(name, true).asClass();
+ return loadClass(name, true);
+ }
+
+ /**
+ * Load and optionally resolve a class with a given name.
+ *
+ * @param name
+ * @param resolve
+ * @return Class
+ * @throws ClassNotFoundException
+ */
+ protected Class loadClass(String name, boolean resolve)
+ throws ClassNotFoundException {
+
+ /* Have we already loaded this class? */
+ final Class cls = findLoadedClass(name);
+ if (cls != null) {
+ return cls;
+ }
+
+ /* Can the class been loaded by a parent? */
+ try {
+ if ((parent == null) || skipParentLoader(name)) {
+ return loadClass0(name, resolve);
+ } else {
+ return parent.loadClass(name, resolve);
+ }
+ } catch (ClassNotFoundException e) {
+ // e.printStackTrace();
+ }
+ /* Still not found, we have to do it ourself. */
+ final Class c = findClass(name);
+ if (resolve) {
+ resolveClass(c);
+ }
+ return c;
+ }
+
+ private static native Class loadClass0(String name, boolean resolve) throws ClassNotFoundException;
+
+ /**
+ * Define a byte-array of class data into a loaded class.
+ *
+ * @param data
+ * @param offset
+ * @param length
+ * @return Class
+ * @deprecated Replaced by {@link #defineClass(String, byte[], int, int)}
+ */
+ protected final Class defineClass(byte[] data, int offset, int length) {
+ return defineClass(null, data, offset, length, null);
+ }
+
+ /**
+ * Define a byte-array of class data into a loaded class.
+ *
+ * @param name
+ * @param data
+ * @param offset
+ * @param length
+ * @return Class
+ */
+ protected final Class defineClass(String name, byte[] data, int offset,
+ int length) {
+ return defineClass(name, data, offset, length, null);
+ }
+
+ /**
+ * Defines a new package and creates a Package object. The package should be
+ * defined before any class in the package is defined with
+ * <code>defineClass()</code>. The package should not yet be defined
+ * before in this classloader or in one of its parents (which means that
+ * <code>getPackage()</code> should return <code>null</code>). All
+ * parameters except the <code>name</code> of the package may be
+ * <code>null</code>.
+ *
+ * <p>
+ * Subclasses should call this method from their <code>findClass()</code>
+ * implementation before calling <code>defineClass()</code> on a Class in
+ * a not yet defined Package (which can be checked by calling
+ * <code>getPackage()</code>).
+ *
+ * @param name
+ * the name of the Package
+ * @param specTitle
+ * the name of the specification
+ * @param specVendor
+ * the name of the specification designer
+ * @param specVersion
+ * the version of this specification
+ * @param implTitle
+ * the name of the implementation
+ * @param implVendor
+ * the vendor that wrote this implementation
+ * @param implVersion
+ * the version of this implementation
+ * @param sealed
+ * if sealed the origin of the package classes
+ * @return the Package object for the specified package
+ * @throws IllegalArgumentException
+ * if the package name is null or it was already defined by this
+ * classloader or one of its parents
+ * @see Package
+ * @since 1.2
+ */
+ protected Package definePackage(String name, String specTitle,
+ String specVendor, String specVersion, String implTitle,
+ String implVendor, String implVersion, URL sealed) {
+ if (getPackage(name) != null)
+ throw new IllegalArgumentException("Package " + name
+ + " already defined");
+ Package p = new Package(name, specTitle, specVendor, specVersion,
+ implTitle, implVendor, implVersion, sealed, this);
+ synchronized (definedPackages) {
+ definedPackages.put(name, p);
+ }
+ return p;
+ }
+
+ /**
+ * Define a byte-array of class data into a loaded class.
+ *
+ * @param name
+ * @param data
+ * @param offset
+ * @param length
+ * @param protDomain
+ * @return Class
+ */
+ protected final Class defineClass(String name, byte[] data, int offset,
+ int length, ProtectionDomain protDomain) {
+ if (data == null) {
+ throw new NullPointerException();
+ }
+ if (offset < 0 || length < 0 || (offset + length) > data.length) {
+ throw new IndexOutOfBoundsException();
+ }
+ if (protDomain == null) {
+
+ protDomain = AccessController
+ .doPrivileged(new PrivilegedAction<ProtectionDomain>() {
+
+ public ProtectionDomain run() {
+ return getDefaultProtectionDomain();
+ }
+ });
+ }
+ return defineClass0(name, data, offset, length, protDomain);
+ }
+
+ private native Class defineClass0(String name, byte[] data, int offset, int length, ProtectionDomain protDomain);
+
+ /**
+ * Define a byte-array of class data into a loaded class.
+ *
+ * @param name
+ * @param data
+ * @param protDomain
+ * @return Class
+ */
+ protected final Class defineClass(String name, ByteBuffer data, ProtectionDomain protDomain) {
+ if (data == null) {
+ throw new NullPointerException();
+ }
+ if (protDomain == null) {
+ protDomain = AccessController.doPrivileged(
+ new PrivilegedAction<ProtectionDomain>() {
+ public ProtectionDomain run() {
+ return getDefaultProtectionDomain();
+ }
+ });
+ }
+ return defineClass0(name, data, protDomain);
+ }
+
+ private native Class defineClass0(String name, ByteBuffer data, ProtectionDomain protDomain);
+
+ private ProtectionDomain getDefaultProtectionDomain() {
+ if (defaultProtectionDomain == null) {
+ final CodeSource cs = new CodeSource(null, (Certificate[])null);
+ defaultProtectionDomain = new ProtectionDomain(cs, Policy
+ .getPolicy().getPermissions(cs));
+ }
+ return defaultProtectionDomain;
+ }
+
+ /**
+ * Resolve all references in the given class.
+ *
+ * @param c
+ */
+ protected final void resolveClass(Class c) {
+ if (c == null) {
+ throw new NullPointerException();
+ }
+ }
+
+ /**
+ * Finds the class with the given name if it had been previously loaded
+ * through this class loader.
+ *
+ * @param name
+ * @return the Class object, or null if the class has not been loaded
+ */
+ protected native final Class findLoadedClass(String name);
+
+ /**
+ * Finds the specified class. This method should be overridden by class
+ * loader implementations that follow the new delegation model for loading
+ * classes, and will be called by the loadClass method after checking the
+ * parent class loader for the requested class. The default implementation
+ * throws ClassNotFoundException.
+ *
+ * @param name
+ * @return Class
+ * @throws ClassNotFoundException
+ */
+ protected Class findClass(String name) throws ClassNotFoundException {
+ throw new ClassNotFoundException(name);
+ }
+
+ /**
+ * Find a system class.
+ *
+ * @param name
+ * @return Class
+ * @throws ClassNotFoundException
+ */
+ protected final Class findSystemClass(String name)
+ throws ClassNotFoundException {
+ if (name == null) {
+ throw new NullPointerException();
+ } else {
+ return loadClass0(name, true);
+ }
+ }
+
+ /**
+ * Gets a system resource as stream by name.
+ *
+ * @param name
+ * @return InputStream
+ */
+ public static final InputStream getSystemResourceAsStream(String name) {
+ try {
+ return getSystemResourceAsStream0(name);
+ } catch (IOException ex) {
+ return null;
+ }
+ }
+
+ private static native InputStream getSystemResourceAsStream0(String name) throws IOException;
+
+ /**
+ * Gets a resource as stream by name.
+ *
+ * @param name
+ * @return InputStream
+ */
+ public InputStream getResourceAsStream(String name) {
+ URL url = getResource(name);
+ if (url != null) {
+ try {
+ return url.openStream();
+ } catch (IOException ex) {
+ // Syslog.debug("Cannot load resource " + name, ex);
+ return null;
+ }
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Gets a URL to a system resource by name.
+ *
+ * @param name
+ * @return URL
+ */
+ public static final URL getSystemResource(String name) {
+ try {
+ if (name.startsWith("/")) {
+ return new URL("system://" + name);
+ } else {
+ return new URL("system:///" + name);
+ }
+ } catch (MalformedURLException ex) {
+ ex.printStackTrace();
+ return null;
+ }
+ }
+
+ /**
+ * Gets an URL to a resource by name.
+ *
+ * @param name
+ * @return URL
+ */
+ public URL getResource(String name) {
+ URL result = null;
+
+ if (parent == null) {
+ if (resourceExists0(name)) {
+ try {
+ if (name.startsWith("/")) {
+ result = new URL("system://" + name);
+ } else {
+ result = new URL("system:///" + name);
+ }
+ } catch (MalformedURLException ex) {
+ ex.printStackTrace();
+ result = null;
+ }
+ }
+ } else {
+ result = parent.getResource(name);
+ }
+
+ if (result == null) {
+ result = findResource(name);
+ }
+ return result;
+ }
+
+ private native boolean resourceExists0(String name);
+
+ public Enumeration getResources(String name) throws IOException {
+ final List<URL> urls = new ArrayList<URL>();
+ getResourcesImpl(name, urls);
+
+ return new Enumeration<URL>()
+ {
+ private Iterator<URL> it = urls.iterator();
+
+ public boolean hasMoreElements() {
+ return it.hasNext();
+ }
+
+ public URL nextElement() {
+ return it.next();
+ }
+ };
+ }
+
+ protected boolean getResourcesImpl(String name, List<URL> urls) throws IOException {
+ URL result = null;
+ if (parent == null) {
+ if (resourceExists0(name)) {
+ try {
+ if (name.startsWith("/")) {
+ //todo: adjust the rt.jar path to match the future configurations
+ //todo: one possibility is ${java.home}/lib/rt.jar
+ result = new URL("jar:file:/jifs/lib/rt.jar!" + name);
+ //result = new URL("system://" + name);
+ } else {
+ //todo: adjust the rt.jar path to match the future configurations
+ //todo: one possibility is ${java.home}/lib/rt.jar
+ result = new URL("jar:file:/jifs/lib/rt.jar!/" + name);
+ //result = new URL("system:///" + name);
+ }
+ } catch (MalformedURLException ex) {
+ ex.printStackTrace();
+ result = null;
+ }
+ if(result != null)
+ {
+ if(!urls.contains(result)) urls.add(result);
+ }
+ }
+ } else {
+ parent.getResourcesImpl(name, urls);
+ }
+
+ if (result == null) {
+ result = findResource(name);
+ if(result != null)
+ {
+ if(!urls.contains(result)) urls.add(result);
+ }
+ }
+
+ return (result != null);
+ }
+
+ /**
+ * Finds the resource with the given name. Class loader implementations
+ * should override this method to specify where to find resources.
+ *
+ * @param name
+ * @return URL
+ */
+ protected URL findResource(String name) {
+ return null;
+ }
+
+ /**
+ * Called whenever all locations of a named resource are needed.
+ * It is called by <code>getResources()</code> after it has called
+ * <code>parent.getResources()</code>. The results are combined by
+ * the <code>getResources()</code> method.
+ *
+ * <p>The default implementation always returns an empty Enumeration.
+ * Subclasses should override it when they can provide an Enumeration of
+ * URLs (possibly just one element) to the named resource.
+ * The first URL of the Enumeration should be the same as the one
+ * returned by <code>findResource</code>.
+ *
+ * @param name the name of the resource to be found
+ * @return a possibly empty Enumeration of URLs to the named resource
+ * @throws IOException if I/O errors occur in the process
+ * @since 1.2
+ */
+ protected Enumeration findResources(String name) throws IOException
+ {
+ return EmptyEnumeration.getInstance();
+ }
+
+
+ /**
+ * Returns the Package object for the requested package name. It returns
+ * null when the package is not defined by this classloader or one of its
+ * parents.
+ *
+ * @param name
+ * the package name to find
+ * @return the package, if defined
+ * @since 1.2
+ */
+ protected Package getPackage(String name) {
+ Package p;
+ if (parent == null) {
+ p = VMClassLoader.getPackage(name);
+ } else {
+ p = parent.getPackage(name);
+ }
+
+ if (p == null) {
+ synchronized (definedPackages) {
+ p = definedPackages.get(name);
+ }
+ }
+ return p;
+ }
+
+ /**
+ * Returns all Package objects defined by this classloader and its parents.
+ *
+ * @return an array of all defined packages
+ * @since 1.2
+ */
+ protected Package[] getPackages() {
+ // Get all our packages.
+ Package[] packages;
+ synchronized (definedPackages) {
+ packages = new Package[definedPackages.size()];
+ definedPackages.values().toArray(packages);
+ }
+
+ // If we have a parent get all packages defined by our parents.
+ Package[] parentPackages;
+ if (parent == null)
+ parentPackages = VMClassLoader.getPackages();
+ else
+ parentPackages = parent.getPackages();
+
+ Package[] allPackages = new Package[parentPackages.length
+ + packages.length];
+ System.arraycopy(parentPackages, 0, allPackages, 0,
+ parentPackages.length);
+ System.arraycopy(packages, 0, allPackages, parentPackages.length,
+ packages.length);
+ return allPackages;
+ }
+
+ /**
+ * Avoid trying to load the given class via its parent classloader?
+ *
+ * @param name
+ * @return {@code true} if the parent classloader should be skipped.
+ */
+ public boolean skipParentLoader(String name) {
+ return false;
+ }
+
+ /**
+ * Gets the system classloader.
+ *
+ * @return ClassLoader
+ */
+ public static native ClassLoader getSystemClassLoader();
+
+ public static Enumeration getSystemResources(String name)
+ throws IOException {
+ return EmptyEnumeration.getInstance();
+ }
+
+ /**
+ * @return
+ */
+ public ClassLoader getParent() {
+ return parent;
+ }
+
+ /**
+ * Called by <code>Runtime.loadLibrary()</code> to get an absolute path to
+ * a (system specific) library that was requested by a class loaded by this
+ * classloader. The default implementation returns <code>null</code>. It
+ * should be implemented by subclasses when they have a way to find the
+ * absolute path to a library. If this method returns null the library is
+ * searched for in the default locations (the directories listed in the
+ * <code>java.library.path</code> system property).
+ *
+ * @param name
+ * the (system specific) name of the requested library
+ * @return the full pathname to the requested library, or null
+ * @see Runtime#loadLibrary(String)
+ * @since 1.2
+ */
+ protected String findLibrary(String name) {
+ return null;
+ }
+
+ /**
+ * Sets the signers of a class. This should be invoked after defining a
+ * class.
+ *
+ * @param clazz
+ * The class object.
+ * @param signers
+ * The signers.
+ */
+ protected final void setSigners(Class clazz, Object[] signers) {
+ // TODO implement me
+ }
+
+ /**
+ * Set the default assertion status for classes loaded by this classloader,
+ * used unless overridden by a package or class request.
+ *
+ * @param enabled
+ * true to set the default to enabled
+ * @see #setClassAssertionStatus(String, boolean)
+ * @see #setPackageAssertionStatus(String, boolean)
+ * @see #clearAssertionStatus()
+ * @since 1.4
+ */
+ public void setDefaultAssertionStatus(boolean enabled) {
+ defaultAssertionStatus = enabled;
+ }
+
+ /**
+ * Set the default assertion status for packages, used unless overridden by
+ * a class request. This default also covers subpackages, unless they are
+ * also specified. The unnamed package should use null for the name.
+ *
+ * @param name
+ * the package (and subpackages) to affect
+ * @param enabled
+ * true to set the default to enabled
+ * @see #setDefaultAssertionStatus(boolean)
+ * @see #setClassAssertionStatus(String, boolean)
+ * @see #clearAssertionStatus()
+ * @since 1.4
+ */
+ public synchronized void setPackageAssertionStatus(String name,
+ boolean enabled) {
+ if (packageAssertionStatus == null)
+ packageAssertionStatus = new HashMap<String, Boolean>(
+ StaticData.systemPackageAssertionStatus);
+ packageAssertionStatus.put(name, Boolean.valueOf(enabled));
+ }
+
+ /**
+ * Set the default assertion status for a class. This only affects the
+ * status of top-level classes, any other string is harmless.
+ *
+ * @param name
+ * the class to affect
+ * @param enabled
+ * true to set the default to enabled
+ * @throws NullPointerException
+ * if name is null
+ * @see #setDefaultAssertionStatus(boolean)
+ * @see #setPackageAssertionStatus(String, boolean)
+ * @see #clearAssertionStatus()
+ * @since 1.4
+ */
+ public synchronized void setClassAssertionStatus(String name,
+ boolean enabled) {
+ if (classAssertionStatus == null)
+ classAssertionStatus = new HashMap<String, Boolean>(
+ StaticData.systemClassAssertionStatus);
+ // The toString() hack catches null, as required.
+ classAssertionStatus.put(name.toString(), Boolean.valueOf(enabled));
+ }
+
+ /**
+ * Resets the default assertion status of this classloader, its packages and
+ * classes, all to false. This allows overriding defaults inherited from the
+ * command line.
+ *
+ * @see #setDefaultAssertionStatus(boolean)
+ * @see #setClassAssertionStatus(String, boolean)
+ * @see #setPackageAssertionStatus(String, boolean)
+ * @since 1.4
+ */
+ public synchronized void clearAssertionStatus() {
+ defaultAssertionStatus = false;
+ packageAssertionStatus = null;
+ classAssertionStatus = null;
+ }
+
+ //jnod+openjdk
+ // Returns the invoker's class loader, or null if none.
+ // NOTE: This must always be invoked when there is exactly one intervening
+ // frame from the core libraries on the stack between this method's
+ // invocation and the desired invoker.
+ static ClassLoader getCallerClassLoader() {
+ // NOTE use of more generic Reflection.getCallerClass()
+ Class caller = Reflection.getCallerClass(3);
+ // This can be null if the VM is requesting it
+ if (caller == null) {
+ return null;
+ }
+ // Circumvent security check since this is package-private
+ return caller.getClassLoader0();
+ }
+
+ // Returns true if the specified class loader can be found in this class
+ // loader's delegation chain.
+ boolean isAncestor(ClassLoader cl) {
+ ClassLoader acl = this;
+ do {
+ acl = acl.parent;
+ if (cl == acl) {
+ return true;
+ }
+ } while (acl != null);
+ return false;
+ }
+
+/**
+ * Returns the assertion status that would be assigned to the specified
+ * class if it were to be initialized at the time this method is invoked.
+ * If the named class has had its assertion status set, the most recent
+ * setting will be returned; otherwise, if any package default assertion
+ * status pertains to this class, the most recent setting for the most
+ * specific pertinent package default assertion status is returned;
+ * otherwise, this class loader's default assertion status is returned.
+ * </p>
+ *
+ * @param className
+ * The fully qualified class name of the class whose desired
+ * assertion status is being queried.
+ *
+ * @return The desired assertion status of the specified class.
+ *
+ * @see #setClassAssertionStatus(String, boolean)
+ * @see #setPackageAssertionStatus(String, boolean)
+ * @see #setDefaultAssertionStatus(boolean)
+ *
+ * @since 1.4
+ */
+ synchronized boolean desiredAssertionStatus(String className) {
+ Boolean result;
+
+ // assert classAssertionStatus != null;
+ // assert packageAssertionStatus != null;
+
+ // Check for a class entry
+ result = (Boolean)classAssertionStatus.get(className);
+ if (result != null)
+ return result.booleanValue();
+
+ // Check for most specific package entry
+ int dotIndex = className.lastIndexOf(".");
+ if (dotIndex < 0) { // default package
+ result = (Boolean)packageAssertionStatus.get(null);
+ if (result != null)
+ return result.booleanValue();
+ }
+ while(dotIndex > 0) {
+ className = className.substring(0, dotIndex);
+ result = (Boolean)packageAssertionStatus.get(className);
+ if (result != null)
+ return result.booleanValue();
+ dotIndex = className.lastIndexOf(".", dotIndex-1);
+ }
+
+ // Return the classloader default
+ return defaultAssertionStatus;
+ }
+
+ {
+ packageAssertionStatus = new HashMap();
+ }
+
+ public static void loadLibrary(Class fromClass, String libname, boolean b) {
+ //do nothing
+ }
+
+}
Property changes on: trunk/core/src/classpath/java/java/lang/ClassLoader.java
___________________________________________________________________
Added: svn:keywords
+ Author Date Id Revision
Added: svn:eol-style
+ native
Copied: trunk/core/src/classpath/java/java/lang/Thread.java (from rev 5209, trunk/core/src/classpath/vm/java/lang/Thread.java)
===================================================================
--- trunk/core/src/classpath/java/java/lang/Thread.java (rev 0)
+++ trunk/core/src/classpath/java/java/lang/Thread.java 2009-04-02 19:01:01 UTC (rev 5210)
@@ -0,0 +1,1390 @@
+/* Thread -- an independent thread of executable code
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ Free Software Foundation
+
+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.Map;
+import java.util.HashMap;
+
+
+import sun.security.util.SecurityConstants;
+import sun.nio.ch.Interruptible;
+
+/* 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.4, with caveats. We do not
+* implement the deprecated (and dangerous) stop, suspend, and resume
+* methods. Security implementation is not complete.
+*/
+
+/**
+ * Thread represents a single thread of execution in the VM. When an
+ * application VM starts up, it creates a non-daemon Thread which calls the
+ * main() method of a particular class. There may be other Threads running,
+ * such as the garbage collection thread.
+ *
+ * <p>Threads have names to identify them. These names are not necessarily
+ * unique. Every Thread has a priority, as well, which tells the VM which
+ * Threads should get more running time. New threads inherit the priority
+ * and daemon status of the parent thread, by default.
+ *
+ * <p>There are two methods of creating a Thread: you may subclass Thread and
+ * implement the <code>run()</code> method, at which point you may start the
+ * Thread by calling its <code>start()</code> method, or you may implement
+ * <code>Runnable</code> in the class you want to use and then call new
+ * <code>Thread(your_obj).start()</code>.
+ *
+ * <p>The virtual machine runs until all non-daemon threads have died (either
+ * by returning from the run() method as invoked by start(), or by throwing
+ * an uncaught exception); or until <code>System.exit</code> is called with
+ * adequate permissions.
+ *
+ * <p>It is unclear at what point a Thread should be added to a ThreadGroup,
+ * and at what point it should be removed. Should it be inserted when it
+ * starts, or when it is created? Should it be removed when it is suspended
+ * or interrupted? The only thing that is clear is that the Thread should be
+ * removed when it is stopped.
+ *
+ * @author Tom Tromey
+ * @author John Keiser
+ * @author Eric Blake (eb...@em...)
+ * @author Andrew John Hughes (gnu...@me...)
+ * @see Runnable
+ * @see Runtime#exit(int)
+ * @see #run()
+ * @see #start()
+ * @see ThreadLocal
+ * @since 1.0
+ */
+public class Thread implements Runnable
+{
+ /** The minimum priority for a Thread. */
+ public static final int MIN_PRIORITY = 1;
+
+ /** The priority a Thread gets by default. */
+ public static final int NORM_PRIORITY = 5;
+
+ /** The maximum priority for a Thread. */
+ public static final int MAX_PRIORITY = 10;
+
+ private static final String NONAME = "Thread";
+
+ /** The VM thread implementing this thread */
+ final Object vmThread;
+
+ /** The group this thread belongs to.
+ *
+ */
+ ThreadGroup group;
+
+ /** The object to run(), null if this is the target. */
+ final Runnable runnable;
+
+ /** The name of this thread */
+ String name;
+
+ /** Is this a daemon thread? */
+ private boolean daemon;
+
+ /** The context classloader of this thread */
+ private ClassLoader contextClassLoader;
+
+ /** The thread in which I was created */
+ private final Thread parent;
+
+ /** The default exception handler. */
+ private static UncaughtExceptionHandler defaultHandler;
+
+ /* ThreadLocal values pertaining to this thread. This map is maintained
+ * by the ThreadLocal class. */
+ ThreadLocal.ThreadLocalMap threadLocals = null;
+
+ /*
+ * InheritableThreadLocal values pertaining to this thread. This map is
+ * maintained by the InheritableThreadLocal class.
+ */
+ ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;
+
+ /** The uncaught exception handler. */
+ UncaughtExceptionHandler exceptionHandler;
+
+ /**
+ * Name and number of threads created. Used only for generating unique names.
+ *
+ * @see java.lang.Thread#autoName(String)
+ */
+ private static final HashMap<String, Integer> nameMap = new HashMap<String, Integer>();
+
+ /**
+ * Allocates a new <code>Thread</code> object. This constructor has
+ * the same effect as <code>Thread(null, null,</code>
+ * <i>gname</i><code>)</code>, where <b><i>gname</i></b> is
+ * a newly generated name. Automatically generated names are of the
+ * form <code>"Thread-"+</code><i>n</i>, where <i>n</i> is an integer.
+ * <p>
+ * Threads created this way must have overridden their
+ * <code>run()</code> method to actually do anything. An example
+ * illustrating this method being used follows:
+ * <p><blockquote><pre>
+ * import java.lang.*;
+ *
+ * class plain01 implements Runnable {
+ * String name;
+ * plain01() {
+ * name = null;
+ * }
+ * plain01(String s) {
+ * name = s;
+ * }
+ * public void run() {
+ * if (name == null)
+ * System.out.println("A new thread created");
+ * else
+ * System.out.println("A new thread with name " + name +
+ * " created");
+ * }
+ * }
+ * class threadtest01 {
+ * public static void main(String args[] ) {
+ * int failed = 0 ;
+ *
+ * <b>Thread t1 = new Thread();</b>
+ * if (t1 != null)
+ * System.out.println("new Thread() succeed");
+ * else {
+ * System.out.println("new Thread() failed");
+ * failed++;
+ * }
+ * }
+ * }
+ * </pre></blockquote>
+ *
+ * @see java.lang.Thread#Thread(java.lang.ThreadGroup,
+ * java.lang.Runnable, java.lang.String)
+ */
+ public Thread()
+ {
+ this(null, null, NONAME);
+ }
+
+ /**
+ * Allocates a new <code>Thread</code> object. This constructor has
+ * the same effect as <code>Thread(null, target,</code>
+ * <i>gname</i><code>)</code>, where <i>gname</i> is
+ * a newly generated name. Automatically generated names are of the
+ * form <code>"Thread-"+</code><i>n</i>, where <i>n</i> is an integer.
+ *
+ * @param target the object whose <code>run</code> method is called.
+ * @see java.lang.Thread#Thread(java.lang.ThreadGroup,
+ * java.lang.Runnable, java.lang.String)
+ */
+ public Thread(Runnable target)
+ {
+ this(null, target, NONAME);
+ }
+
+ /**
+ * Allocates a new <code>Thread</code> object. This constructor has
+ * the same effect as <code>Thread(null, null, name)</code>.
+ *
+ * @param name the name of the new thread.
+ * @see java.lang.Thread#Thread(java.lang.ThreadGroup,
+ * java.lang.Runnable, java.lang.String)
+ */
+ public Thread(String name)
+ {
+ this(null, null, name);
+ }
+
+ /**
+ * Allocates a new <code>Thread</code> object. This constructor has
+ * the same effect as <code>Thread(group, target,</code>
+ * <i>gname</i><code>)</code>, where <i>gname</i> is
+ * a newly generated name. Automatically generated names are of the
+ * form <code>"Thread-"+</code><i>n</i>, where <i>n</i> is an integer.
+ *
+ * @param group the group to put the Thread into
+ * @param target the Runnable object to execute
+ * @throws SecurityException if this thread cannot access <code>group</code>
+ * @throws IllegalThreadStateException if group is destroyed
+ * @see #Thread(ThreadGroup, Runnable, String)
+ */
+ public Thread(ThreadGroup group, Runnable target)
+ {
+ this(group, target, NONAME);
+ }
+
+ /**
+ * Allocates a new <code>Thread</code> object. This constructor has
+ * the same effect as <code>Thread(group, null, name)</code>
+ *
+ * @param group the group to put the Thread into
+ * @param name the name for the Thread
+ * @throws NullPointerException if name is null
+ * @throws SecurityException if this thread cannot access <code>group</code>
+ * @throws IllegalThreadStateException if group is destroyed
+ * @see #Thread(ThreadGroup, Runnable, String)
+ */
+ public Thread(ThreadGroup group, String name)
+ {
+ this(group, null, name);
+ }
+
+ /**
+ * Allocates a new <code>Thread</code> object. This constructor has
+ * the same effect as <code>Thread(null, target, name)</code>.
+ *
+ * @param target the Runnable object to execute
+ * @param name the name for the Thread
+ * @throws NullPointerException if name is null
+ * @see #Thread(ThreadGroup, Runnable, String)
+ */
+ public Thread(Runnable target, String name)
+ {
+ this(null, target, name);
+ }
+
+ /**
+ * Allocate a new Thread object, with the specified ThreadGroup and name, and
+ * using the specified Runnable object's <code>run()</code> method to
+ * execute. If the Runnable object is null, <code>this</code> (which is
+ * a Runnable) is used instead.
+ *
+ * <p>If the ThreadGroup is null, the security manager is checked. If a
+ * manager exists and returns a non-null object for
+ * <code>getThreadGroup</code>, that group is used; otherwise the group
+ * of the creating thread is used. Note that the security manager calls
+ * <code>checkAccess</code> if the ThreadGroup is not null.
+ *
+ * <p>The new Thread will inherit its creator's priority and daemon status.
+ * These can be changed with <code>setPriority</code> and
+ * <code>setDaemon</code>.
+ *
+ * @param group the group to put the Thread into
+ * @param target the Runnable object to execute
+ * @param name the name for the Thread
+ * @throws NullPointerException if name is null
+ * @throws SecurityException if this thread cannot access <code>group</code>
+ * @throws IllegalThreadStateException if group is destroyed
+ * @see Runnable#run()
+ * @see #run()
+ * @see #setDaemon(boolean)
+ * @see #setPriority(int)
+ * @see SecurityManager#checkAccess(ThreadGroup)
+ * @see ThreadGroup#checkAccess()
+ */
+ public Thread(ThreadGroup group, Runnable target, String name)
+ {
+ Thread current = currentThread();
+
+ if (group != null) {
+ group.checkAccess();
+ } else {
+ group = current.getThreadGroup();
+ }
+
+ if (group == null) {
+ throw new InternalError("Live thread has invalid group: " + name);
+ }
+
+ group.addUnstarted();
+
+ this.group = group;
+ this.runnable = target;
+ this.name = autoName(name);
+ this.parent = current;
+
+ this.daemon = current.isDaemon();
+
+ this.vmThread = createVmThread0(current);
+ setPriority(current.getPriority());
+ updateName0();
+
+
+ if (parent.inheritableThreadLocals != null)
+ this.inheritableThreadLocals = ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
+ }
+
+ private native Object createVmThread0(Thread current);
+
+ /**
+ * Allocate a new Thread object, as if by
+ * <code>Thread(group, null, name)</code>, and give it the specified stack
+ * size, in bytes. The stack size is <b>highly platform independent</b>,
+ * and the virtual machine is free to round up or down, or ignore it
+ * completely. A higher value might let you go longer before a
+ * <code>StackOverflowError</code>, while a lower value might let you go
+ * longer before an <code>OutOfMemoryError</code>. Or, it may do absolutely
+ * nothing! So be careful, and expect to need to tune this value if your
+ * virtual machine even supports it.
+ *
+ * @param group the group to put the Thread into
+ * @param target the Runnable object to execute
+ * @param name the name for the Thread
+ * @param size the stack size, in bytes; 0 to be ignored
+ * @throws NullPointerException if name is null
+ * @throws SecurityException if this thread cannot access <code>group</code>
+ * @throws IllegalThreadStateException if group is destroyed
+ * @since 1.4
+ */
+ public Thread(ThreadGroup group, Runnable target, String name, long size)
+ {
+ Thread current = currentThread();
+
+ if (group != null) {
+ group.checkAccess();
+ } else {
+ group = current.getThreadGroup();
+ }
+
+ if (group == null) {
+ throw new InternalError("Live thread has invalid group: " + name);
+ }
+
+ group.addUnstarted();
+
+ this.group = group;
+ this.runnable = target;
+ this.name = autoName(name);
+ this.parent = current;
+
+ this.daemon = current.isDaemon();
+
+ this.vmThread = createVmThread0(current);
+ setPriority(current.getPriority());
+ updateName0();
+
+
+ if (parent.inheritableThreadLocals != null)
+ this.inheritableThreadLocals = ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
+ }
+
+ /**
+ * Create a new instance with a given group as containing group, a runnable
+ * as thread runner and a given name.
+ *
+ * @param group
+ * @param target
+ * @param name
+ */
+ protected Thread(ThreadGroup group, Runnable target, String name, Object isolatedStatics) {
+ /*
+ if (!(this instanceof IsolateThread)) {
+ throw new SecurityException("Constructor can only be called from IsolateThread");
+ }
+ */
+ if (!(this.getClass().getName().startsWith("org.jnode.vm.isolate"))) {
+ throw new SecurityException("Constructor can only be called from IsolateThread");
+ }
+ if (group == null) {
+ throw new InternalError("Isolate thread has invalid group: " + name);
+ }
+
+ group.addUnstarted();
+
+ this.group = group;
+ this.runnable = target;
+ this.name = autoName(name);
+ this.parent = null;
+ this.daemon = false;
+
+ this.vmThread = createVmThread1(isolatedStatics);
+ setPriority(this.getPriority());
+ updateName0();
+
+ //todo review it: should thread locals be inherited accorss isolates? Probably not...
+ ThreadLocal.ThreadLocalMap parentLocals = currentThread().inheritableThreadLocals;
+ if (parentLocals != null)
+ this.inheritableThreadLocals = ThreadLocal.createInheritedMap(parentLocals);
+ }
+
+ private native Object createVmThread1(Object isolatedStatics);
+
+ /**
+ * Create a new thread from a given VmThread. Only used for the main thread.
+ *
+ * @param vmThread
+ * @throws IllegalArgumentException
+ * If the given vmThread is not the root thread or the given
+ * vmThread already has an associated java thread.
+ */
+ public Thread(Object vmThread) throws IllegalArgumentException {
+ checkArg0(vmThread);
+ this.vmThread = vmThread;
+ this.group = ROOT_GROUP;
+ this.group.addUnstarted();
+ this.name = autoName("System");
+ this.runnable = null;
+ this.parent = null;
+ updateName0();
+ }
+
+ private static native void checkArg0(Object vmThread);
+
+ private native void updateName0();
+ /**
+ * Get the number of active threads in the current Thread's ThreadGroup.
+ * This implementation calls
+ * <code>currentThread().getThreadGroup().activeCount()</code>.
+ *
+ * @return the number of active threads in the current ThreadGroup
+ * @see ThreadGroup#activeCount()
+ */
+ public static int activeCount()
+ {
+ return currentThread().getThreadGroup().activeCount();
+ }
+
+ /**
+ * Check whether the current Thread is allowed to modify this Thread. This
+ * passes the check on to <code>SecurityManager.checkAccess(this)</code>.
+ *
+ * @throws SecurityException if the current Thread cannot modify this Thread
+ * @see SecurityManager#checkAccess(Thread)
+ */
+ public final void checkAccess()
+ {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkAccess(this);
+ }
+ }
+
+ /**
+ * Count the number of stack frames in this Thread. The Thread in question
+ * must be suspended when this occurs.
+ *
+ * @return the number of stack frames in this Thread
+ * @throws IllegalThreadStateException if this Thread is not suspended
+ * @deprecated pointless, since suspend is deprecated
+ */
+ public native int countStackFrames();
+
+ /**
+ * Get the currently executing Thread. In the situation that the
+ * currently running thread was created by native code and doesn't
+ * have an associated Thread object yet, a new Thread object is
+ * constructed and associated with the native thread.
+ *
+ * @return the currently executing Thread
+ */
+ public static native Thread currentThread();
+
+ /**
+ * Originally intended to destroy this thread, this method was never
+ * implemented by Sun, and is hence a no-op.
+ *
+ * @deprecated This method was originally intended to simply destroy
+ * the thread without performing any form of cleanup operation.
+ * However, it was never implemented. It is now deprecated
+ * for the same reason as <code>suspend()</code>,
+ * <code>stop()</code> and <code>resume()</code>; namely,
+ * it is prone to deadlocks. If a thread is destroyed while
+ * it still maintains a lock on a resource, then this resource
+ * will remain locked and any attempts by other threads to
+ * access the resource will result in a deadlock. Thus, even
+ * an implemented version of this method would be still be
+ * deprecated, due to its unsafe nature.
+ * @throws NoSuchMethodError as this method was never implemented.
+ */
+ public native void destroy();
+
+ /**
+ * Print a stack trace of the current thread to stderr using the same
+ * format as Throwable's printStackTrace() method.
+ *
+ * @see Throwable#printStackTrace()
+ */
+ public static void dumpStack()
+ {
+ new Throwable().printStackTrace();
+ }
+
+ /**
+ * Copy every active thread in the current Thread's ThreadGroup into the
+ * array. Extra threads are silently ignored. This implementation calls
+ * <code>getThreadGroup().enumerate(array)</code>, which may have a
+ * security check, <code>checkAccess(group)</code>.
+ *
+ * @param array the array to place the Threads into
+ * @return the number of Threads placed into the array
+ * @throws NullPointerException if array is null
+ * @throws SecurityException if you cannot access the ThreadGroup
+ * @see ThreadGroup#enumerate(Thread[])
+ * @see #activeCount()
+ * @see SecurityManager#checkAccess(ThreadGroup)
+ */
+ public static int enumerate(Thread[] array)
+ {
+ return currentThread().group.enumerate(array);
+ }
+
+ /**
+ * Get this Thread's name.
+ *
+ * @return this Thread's name
+ */
+ public final String getName()
+ {
+ return name;
+ }
+
+ /**
+ * Get this Thread's priority.
+ *
+ * @return the Thread's priority
+ */
+ public native final int getPriority();
+
+ /**
+ * Get the ThreadGroup this Thread belongs to. If the thread has died, this
+ * returns null.
+ *
+ * @return this Thread's ThreadGroup
+ */
+ public final ThreadGroup getThreadGroup()
+ {
+ return isAlive() ? group : null;
+ }
+
+ /**
+ * Checks whether the current thread holds the monitor on a given object.
+ * This allows you to do <code>assert Thread.holdsLock(obj)</code>.
+ *
+ * @param obj the object to test lock ownership on.
+ * @return true if the current thread is currently synchronized on obj
+ * @throws NullPointerException if obj is null
+ * @since 1.4
+ */
+ public static native boolean holdsLock(Object obj);
+
+ /**
+ * Interrupt this Thread. First, there is a security check,
+ * <code>checkAccess</code>. Then, depending on the current state of the
+ * thread, various actions take place:
+ *
+ * <p>If the thread is waiting because of {@link #wait()},
+ * {@link #sleep(long)}, or {@link #join()}, its <i>interrupt status</i>
+ * will be cleared, and an InterruptedException will be thrown. Notice that
+ * this case is only possible if an external thread called interrupt().
+ *
+ * <p>If the thread is blocked in an interruptible I/O operation, in
+ * {@link java.nio.channels.InterruptibleChannel}, the <i>interrupt
+ * status</i> will be set, and ClosedByInterruptException will be thrown.
+ *
+ * <p>If the thread is blocked on a {@link java.nio.channels.Selector}, the
+ * <i>interrupt status</i> will be set, and the selection will return, with
+ * a possible non-zero value, as though by the wakeup() method.
+ *
+ * <p>Otherwise, the interrupt status will be set.
+ *
+ * @throws SecurityException if you cannot modify this Thread
+ */
+ public native void interrupt();
+
+ /**
+ * Determine whether the current Thread has been interrupted, and clear
+ * the <i>interrupted status</i> in the process.
+ *
+ * @return whether the current Thread has been interrupted
+ * @see #isInterrupted()
+ */
+ public static native boolean interrupted();
+
+ /**
+ * Determine whether the given Thread has been interrupted, but leave
+ * the <i>interrupted status</i> alone in the process.
+ *
+ * @return whether the Thread has been interrupted
+ * @see #interrupted()
+ */
+ public native boolean isInterrupted();
+
+ /**
+ * Determine whether this Thread is alive. A thread which is alive has
+ * started and not yet died.
+ *
+ * @return whether this Thread is alive
+ */
+ public native final boolean isAlive();
+
+ /**
+ * Tell whether this is a daemon Thread or not.
+ *
+ * @return whether this is a daemon Thread or not
+ * @see #setDaemon(boolean)
+ */
+ public final boolean isDaemon()
+ {
+ return daemon;
+ }
+
+ /**
+ * Wait forever for the Thread in question to die.
+ *
+ * @throws InterruptedException if the Thread is interrupted; it's
+ * <i>interrupted status</i> will be cleared
+ */
+ public final synchronized void join() throws InterruptedException {
+ // Test interrupted status
+ if (isInterupted0()) {
+ throw new InterruptedExce...
[truncated message content] |