diff options
Diffstat (limited to 'libjava/java/lang/Thread.java')
-rw-r--r-- | libjava/java/lang/Thread.java | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/libjava/java/lang/Thread.java b/libjava/java/lang/Thread.java index 7938498..505b99b 100644 --- a/libjava/java/lang/Thread.java +++ b/libjava/java/lang/Thread.java @@ -127,11 +127,17 @@ public class Thread implements Runnable /** The context classloader for this Thread. */ private ClassLoader contextClassLoader; + /** The default exception handler. */ + private static UncaughtExceptionHandler defaultHandler; + /** Thread local storage. Package accessible for use by * InheritableThreadLocal. */ WeakIdentityHashMap locals; + /** The uncaught exception handler. */ + UncaughtExceptionHandler exceptionHandler; + // This describes the top-most interpreter frame for this thread. RawData interp_frame; @@ -935,4 +941,147 @@ public class Thread implements Runnable } return locals; } + + /** + * Assigns the given <code>UncaughtExceptionHandler</code> to this + * thread. This will then be called if the thread terminates due + * to an uncaught exception, pre-empting that of the + * <code>ThreadGroup</code>. + * + * @param h the handler to use for this thread. + * @throws SecurityException if the current thread can't modify this thread. + * @since 1.5 + */ + public void setUncaughtExceptionHandler(UncaughtExceptionHandler h) + { + SecurityManager sm = SecurityManager.current; // Be thread-safe. + if (sm != null) + sm.checkAccess(this); + exceptionHandler = h; + } + + /** + * <p> + * Returns the handler used when this thread terminates due to an + * uncaught exception. The handler used is determined by the following: + * </p> + * <ul> + * <li>If this thread has its own handler, this is returned.</li> + * <li>If not, then the handler of the thread's <code>ThreadGroup</code> + * object is returned.</li> + * <li>If both are unavailable, then <code>null</code> is returned + * (which can only happen when the thread was terminated since + * then it won't have an associated thread group anymore).</li> + * </ul> + * + * @return the appropriate <code>UncaughtExceptionHandler</code> or + * <code>null</code> if one can't be obtained. + * @since 1.5 + */ + public UncaughtExceptionHandler getUncaughtExceptionHandler() + { + return exceptionHandler != null ? exceptionHandler : group; + } + + /** + * <p> + * Sets the default uncaught exception handler used when one isn't + * provided by the thread or its associated <code>ThreadGroup</code>. + * This exception handler is used when the thread itself does not + * have an exception handler, and the thread's <code>ThreadGroup</code> + * does not override this default mechanism with its own. As the group + * calls this handler by default, this exception handler should not defer + * to that of the group, as it may lead to infinite recursion. + * </p> + * <p> + * Uncaught exception handlers are used when a thread terminates due to + * an uncaught exception. Replacing this handler allows default code to + * be put in place for all threads in order to handle this eventuality. + * </p> + * + * @param h the new default uncaught exception handler to use. + * @throws SecurityException if a security manager is present and + * disallows the runtime permission + * "setDefaultUncaughtExceptionHandler". + * @since 1.5 + */ + public static void + setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler h) + { + SecurityManager sm = SecurityManager.current; // Be thread-safe. + if (sm != null) + sm.checkPermission(new RuntimePermission("setDefaultUncaughtExceptionHandler")); + defaultHandler = h; + } + + /** + * Returns the handler used by default when a thread terminates + * unexpectedly due to an exception, or <code>null</code> if one doesn't + * exist. + * + * @return the default uncaught exception handler. + * @since 1.5 + */ + public static UncaughtExceptionHandler getDefaultUncaughtExceptionHandler() + { + return defaultHandler; + } + + /** + * <p> + * This interface is used to handle uncaught exceptions + * which cause a <code>Thread</code> to terminate. When + * a thread, t, is about to terminate due to an uncaught + * exception, the virtual machine looks for a class which + * implements this interface, in order to supply it with + * the dying thread and its uncaught exception. + * </p> + * <p> + * The virtual machine makes two attempts to find an + * appropriate handler for the uncaught exception, in + * the following order: + * </p> + * <ol> + * <li> + * <code>t.getUncaughtExceptionHandler()</code> -- + * the dying thread is queried first for a handler + * specific to that thread. + * </li> + * <li> + * <code>t.getThreadGroup()</code> -- + * the thread group of the dying thread is used to + * handle the exception. If the thread group has + * no special requirements for handling the exception, + * it may simply forward it on to + * <code>Thread.getDefaultUncaughtExceptionHandler()</code>, + * the default handler, which is used as a last resort. + * </li> + * </ol> + * <p> + * The first handler found is the one used to handle + * the uncaught exception. + * </p> + * + * @author Tom Tromey <tromey@redhat.com> + * @author Andrew John Hughes <gnu_andrew@member.fsf.org> + * @since 1.5 + * @see Thread#getUncaughtExceptionHandler() + * @see Thread#setUncaughtExceptionHander(java.lang.Thread.UncaughtExceptionHandler) + * @see Thread#getDefaultUncaughtExceptionHandler() + * @see + * Thread#setDefaultUncaughtExceptionHandler(java.lang.Thread.UncaughtExceptionHandler) + */ + public interface UncaughtExceptionHandler + { + /** + * Invoked by the virtual machine with the dying thread + * and the uncaught exception. Any exceptions thrown + * by this method are simply ignored by the virtual + * machine. + * + * @param thr the dying thread. + * @param exc the uncaught exception. + */ + void uncaughtException(Thread thr, Throwable exc); + } } |