author | rriggs |
Thu, 18 Feb 2016 14:44:50 -0500 | |
changeset 36009 | 2dbdf909ac81 |
parent 36008 | 3113bdef9cb1 |
child 36010 | 8fe81891e76c |
--- a/jdk/make/mapfiles/libjava/mapfile-vers Thu Feb 18 02:49:44 2016 +0000 +++ b/jdk/make/mapfiles/libjava/mapfile-vers Thu Feb 18 14:44:50 2016 -0500 @@ -1,5 +1,5 @@ # -# Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -244,10 +244,9 @@ Java_java_util_TimeZone_getSystemTimeZoneID; Java_java_util_TimeZone_getSystemGMTOffsetID; Java_java_util_concurrent_atomic_AtomicLong_VMSupportsCS8; - Java_sun_misc_NativeSignalHandler_handle0; - Java_sun_misc_Signal_findSignal; - Java_sun_misc_Signal_handle0; - Java_sun_misc_Signal_raise0; + Java_jdk_internal_misc_Signal_findSignal0; + Java_jdk_internal_misc_Signal_handle0; + Java_jdk_internal_misc_Signal_raise0; Java_sun_reflect_ConstantPool_getClassAt0; Java_sun_reflect_ConstantPool_getClassAtIfLoaded0; Java_sun_reflect_ConstantPool_getClassRefIndexAt0;
--- a/jdk/make/mapfiles/libjava/reorder-sparc Thu Feb 18 02:49:44 2016 +0000 +++ b/jdk/make/mapfiles/libjava/reorder-sparc Thu Feb 18 14:44:50 2016 -0500 @@ -35,8 +35,6 @@ text: .text%Java_java_lang_System_setOut0; text: .text%Java_java_lang_System_setErr0; text: .text%Java_java_lang_System_identityHashCode; -text: .text%Java_sun_misc_Signal_findSignal; -text: .text%Java_sun_misc_Signal_handle0; text: .text%JNU_NewObjectByName; text: .text%Java_java_io_UnixFileSystem_initIDs; text: .text%Java_java_io_UnixFileSystem_canonicalize0;
--- a/jdk/make/mapfiles/libjava/reorder-sparcv9 Thu Feb 18 02:49:44 2016 +0000 +++ b/jdk/make/mapfiles/libjava/reorder-sparcv9 Thu Feb 18 14:44:50 2016 -0500 @@ -39,8 +39,6 @@ text: .text%Java_java_lang_System_setOut0; text: .text%Java_java_lang_System_setErr0; text: .text%Java_java_lang_System_identityHashCode; -text: .text%Java_sun_misc_Signal_findSignal; -text: .text%Java_sun_misc_Signal_handle0; text: .text%JNU_NewObjectByName; text: .text%Java_java_io_UnixFileSystem_initIDs; text: .text%Java_java_io_UnixFileSystem_canonicalize0;
--- a/jdk/make/mapfiles/libjava/reorder-x86 Thu Feb 18 02:49:44 2016 +0000 +++ b/jdk/make/mapfiles/libjava/reorder-x86 Thu Feb 18 14:44:50 2016 -0500 @@ -81,8 +81,6 @@ text: .text%Java_java_lang_Throwable_getStackTraceDepth; text: .text%Java_java_lang_Throwable_getStackTraceElement; text: .text%Java_java_lang_System_identityHashCode; -text: .text%Java_sun_misc_Signal_findSignal; -text: .text%Java_sun_misc_Signal_handle0; text: .text%JNU_NotifyAll; # Test LoadFrame text: .text%JNU_CallMethodByName;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/java.base/share/classes/jdk/internal/misc/Signal.java Thu Feb 18 14:44:50 2016 -0500 @@ -0,0 +1,284 @@ +/* + * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.internal.misc; + +import java.util.Hashtable; +import java.util.Objects; + +/** + * This class provides ANSI/ISO C signal support. A Java program can register + * signal handlers for the current process. There are two restrictions: + * <ul> + * <li> + * Java code cannot register a handler for signals that are already used + * by the Java VM implementation. The <code>Signal.handle</code> + * function raises an <code>IllegalArgumentException</code> if such an attempt + * is made. + * <li> + * When <code>Signal.handle</code> is called, the VM internally registers a + * special C signal handler. There is no way to force the Java signal handler + * to run synchronously before the C signal handler returns. Instead, when the + * VM receives a signal, the special C signal handler creates a new thread + * (at priority <code>Thread.MAX_PRIORITY</code>) to + * run the registered Java signal handler. The C signal handler immediately + * returns. Note that because the Java signal handler runs in a newly created + * thread, it may not actually be executed until some time after the C signal + * handler returns. + * </ul> + * <p> + * Signal objects are created based on their names. For example: + * <blockquote><pre> + * new Signal("INT"); + * </pre></blockquote> + * constructs a signal object corresponding to <code>SIGINT</code>, which is + * typically produced when the user presses <code>Ctrl-C</code> at the command line. + * The <code>Signal</code> constructor throws <code>IllegalArgumentException</code> + * when it is passed an unknown signal. + * <p> + * This is an example of how Java code handles <code>SIGINT</code>: + * <blockquote><pre> + * Signal.Handler handler = new Signal.Handler () { + * public void handle(Signal sig) { + * ... // handle SIGINT + * } + * }; + * Signal.handle(new Signal("INT"), handler); + * </pre></blockquote> + * + * @since 9 + */ +public final class Signal { + private static Hashtable<Signal, Signal.Handler> handlers = new Hashtable<>(4); + private static Hashtable<Integer, Signal> signals = new Hashtable<>(4); + + private int number; + private String name; + + /* Returns the signal number */ + public int getNumber() { + return number; + } + + /** + * Returns the signal name. + * + * @return the name of the signal. + * @see jdk.internal.misc.Signal#Signal(String name) + */ + public String getName() { + return name; + } + + /** + * Compares the equality of two <code>Signal</code> objects. + * + * @param other the object to compare with. + * @return whether two <code>Signal</code> objects are equal. + */ + public boolean equals(Object other) { + if (this == other) { + return true; + } + if (other == null || !(other instanceof Signal)) { + return false; + } + Signal other1 = (Signal)other; + return name.equals(other1.name) && (number == other1.number); + } + + /** + * Returns a hashcode for this Signal. + * + * @return a hash code value for this object. + */ + public int hashCode() { + return number; + } + + /** + * Returns a string representation of this signal. For example, "SIGINT" + * for an object constructed using <code>new Signal ("INT")</code>. + * + * @return a string representation of the signal + */ + public String toString() { + return "SIG" + name; + } + + /** + * Constructs a signal from its name. + * + * @param name the name of the signal. + * @exception IllegalArgumentException unknown signal + * @see jdk.internal.misc.Signal#getName() + */ + public Signal(String name) { + Objects.requireNonNull(name, "name"); + // Signal names are the short names; + // the "SIG" prefix is not used for compatibility with previous JDKs + if (name.startsWith("SIG")) { + throw new IllegalArgumentException("Unknown signal: " + name); + } + this.name = name; + number = findSignal0(name); + if (number < 0) { + throw new IllegalArgumentException("Unknown signal: " + name); + } + } + + /** + * Registers a signal handler. + * + * @param sig a signal + * @param handler the handler to be registered with the given signal. + * @return the old handler + * @exception IllegalArgumentException the signal is in use by the VM + * @see jdk.internal.misc.Signal#raise(Signal sig) + * @see jdk.internal.misc.Signal.Handler + * @see jdk.internal.misc.Signal.Handler#SIG_DFL + * @see jdk.internal.misc.Signal.Handler#SIG_IGN + */ + public static synchronized Signal.Handler handle(Signal sig, + Signal.Handler handler) + throws IllegalArgumentException { + Objects.requireNonNull(sig, "sig"); + Objects.requireNonNull(handler, "handler"); + long newH = (handler instanceof NativeHandler) ? + ((NativeHandler)handler).getHandler() : 2; + long oldH = handle0(sig.number, newH); + if (oldH == -1) { + throw new IllegalArgumentException + ("Signal already used by VM or OS: " + sig); + } + signals.put(sig.number, sig); + synchronized (handlers) { + Signal.Handler oldHandler = handlers.get(sig); + handlers.remove(sig); + if (newH == 2) { + handlers.put(sig, handler); + } + if (oldH == 0) { + return Signal.Handler.SIG_DFL; + } else if (oldH == 1) { + return Signal.Handler.SIG_IGN; + } else if (oldH == 2) { + return oldHandler; + } else { + return new NativeHandler(oldH); + } + } + } + + /** + * Raises a signal in the current process. + * + * @param sig a signal + * @see jdk.internal.misc.Signal#handle(Signal sig, Signal.Handler handler) + */ + public static void raise(Signal sig) throws IllegalArgumentException { + Objects.requireNonNull(sig, "sig"); + if (handlers.get(sig) == null) { + throw new IllegalArgumentException("Unhandled signal: " + sig); + } + raise0(sig.number); + } + + /* Called by the VM to execute Java signal handlers. */ + private static void dispatch(final int number) { + final Signal sig = signals.get(number); + final Signal.Handler handler = handlers.get(sig); + + Runnable runnable = new Runnable () { + public void run() { + // Don't bother to reset the priority. Signal handler will + // run at maximum priority inherited from the VM signal + // dispatch thread. + // Thread.currentThread().setPriority(Thread.NORM_PRIORITY); + handler.handle(sig); + } + }; + if (handler != null) { + new Thread(null, runnable, sig + " handler", 0, false).start(); + } + } + + /* Find the signal number, given a name. Returns -1 for unknown signals. */ + private static native int findSignal0(String sigName); + /* Registers a native signal handler, and returns the old handler. + * Handler values: + * 0 default handler + * 1 ignore the signal + * 2 call back to Signal.dispatch + * other arbitrary native signal handlers + */ + private static native long handle0(int sig, long nativeH); + /* Raise a given signal number */ + private static native void raise0(int sig); + + /** + * This is the signal handler interface expected in <code>Signal.handle</code>. + */ + public interface Handler { + + /** + * The default signal handler + */ + public static final Signal.Handler SIG_DFL = new NativeHandler(0); + /** + * Ignore the signal + */ + public static final Signal.Handler SIG_IGN = new NativeHandler(1); + + /** + * Handle the given signal + * + * @param sig a signal object + */ + public void handle(Signal sig); + } + + + /* + * A package-private class implementing a signal handler in native code. + */ + static final class NativeHandler implements Signal.Handler { + + private final long handler; + + long getHandler() { + return handler; + } + + NativeHandler(long handler) { + this.handler = handler; + } + + public void handle(Signal sig) { + throw new UnsupportedOperationException("invoking native signal handle not supported"); + } + } + +}
--- a/jdk/src/java.base/share/classes/sun/misc/NativeSignalHandler.java Thu Feb 18 02:49:44 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,47 +0,0 @@ -/* - * Copyright (c) 1998, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code 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 - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package sun.misc; - -/* A package-private class implementing a signal handler in native code. */ - -final class NativeSignalHandler implements SignalHandler { - - private final long handler; - - long getHandler() { - return handler; - } - - NativeSignalHandler(long handler) { - this.handler = handler; - } - - public void handle(Signal sig) { - handle0(sig.getNumber(), handler); - } - - private static native void handle0(int number, long handler); -}
--- a/jdk/src/java.base/share/classes/sun/misc/Signal.java Thu Feb 18 02:49:44 2016 +0000 +++ b/jdk/src/java.base/share/classes/sun/misc/Signal.java Thu Feb 18 14:44:50 2016 -0500 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,8 @@ */ package sun.misc; -import java.util.Hashtable; + +import java.util.Objects; /** * This class provides ANSI/ISO C signal support. A Java program can register @@ -68,19 +69,17 @@ * * @author Sheng Liang * @author Bill Shannon - * @see sun.misc.SignalHandler + * @see sun.misc.SignalHandler * @since 1.2 */ public final class Signal { - private static Hashtable<Signal,SignalHandler> handlers = new Hashtable<>(4); - private static Hashtable<Integer,Signal> signals = new Hashtable<>(4); - private int number; - private String name; + // Delegate to jdk.internal.misc.Signal. + private final jdk.internal.misc.Signal iSignal; /* Returns the signal number */ public int getNumber() { - return number; + return iSignal.getNumber(); } /** @@ -90,7 +89,7 @@ * @see sun.misc.Signal#Signal(String name) */ public String getName() { - return name; + return iSignal.getName(); } /** @@ -107,7 +106,7 @@ return false; } Signal other1 = (Signal)other; - return name.equals(other1.name) && (number == other1.number); + return iSignal.equals(other1.iSignal); } /** @@ -116,7 +115,7 @@ * @return a hash code value for this object. */ public int hashCode() { - return number; + return getNumber(); } /** @@ -126,7 +125,7 @@ * @return a string representation of the signal */ public String toString() { - return "SIG" + name; + return iSignal.toString(); } /** @@ -137,11 +136,7 @@ * @see sun.misc.Signal#getName() */ public Signal(String name) { - number = findSignal(name); - this.name = name; - if (number < 0) { - throw new IllegalArgumentException("Unknown signal: " + name); - } + iSignal = new jdk.internal.misc.Signal(name); } /** @@ -159,30 +154,9 @@ public static synchronized SignalHandler handle(Signal sig, SignalHandler handler) throws IllegalArgumentException { - long newH = (handler instanceof NativeSignalHandler) ? - ((NativeSignalHandler)handler).getHandler() : 2; - long oldH = handle0(sig.number, newH); - if (oldH == -1) { - throw new IllegalArgumentException - ("Signal already used by VM or OS: " + sig); - } - signals.put(sig.number, sig); - synchronized (handlers) { - SignalHandler oldHandler = handlers.get(sig); - handlers.remove(sig); - if (newH == 2) { - handlers.put(sig, handler); - } - if (oldH == 0) { - return SignalHandler.SIG_DFL; - } else if (oldH == 1) { - return SignalHandler.SIG_IGN; - } else if (oldH == 2) { - return oldHandler; - } else { - return new NativeSignalHandler(oldH); - } - } + jdk.internal.misc.Signal.Handler oldHandler = jdk.internal.misc.Signal.handle(sig.iSignal, + InternalMiscHandler.of(sig, handler)); + return SunMiscHandler.of(sig.iSignal, oldHandler); } /** @@ -192,41 +166,70 @@ * @see sun.misc.Signal#handle(Signal sig, SignalHandler handler) */ public static void raise(Signal sig) throws IllegalArgumentException { - if (handlers.get(sig) == null) { - throw new IllegalArgumentException("Unhandled signal: " + sig); - } - raise0(sig.number); + jdk.internal.misc.Signal.raise(sig.iSignal); } - /* Called by the VM to execute Java signal handlers. */ - private static void dispatch(final int number) { - final Signal sig = signals.get(number); - final SignalHandler handler = handlers.get(sig); + /* + * Wrapper class to proxy a SignalHandler to a jdk.internal.misc.Signal.Handler. + */ + static final class InternalMiscHandler implements jdk.internal.misc.Signal.Handler { + private final SignalHandler handler; + private final Signal signal; - Runnable runnable = new Runnable () { - public void run() { - // Don't bother to reset the priority. Signal handler will - // run at maximum priority inherited from the VM signal - // dispatch thread. - // Thread.currentThread().setPriority(Thread.NORM_PRIORITY); - handler.handle(sig); + static jdk.internal.misc.Signal.Handler of(Signal signal, SignalHandler handler) { + if (handler == SignalHandler.SIG_DFL) { + return jdk.internal.misc.Signal.Handler.SIG_DFL; + } else if (handler == SignalHandler.SIG_IGN) { + return jdk.internal.misc.Signal.Handler.SIG_IGN; + } else if (handler instanceof SunMiscHandler) { + return ((SunMiscHandler)handler).iHandler; + } else { + return new InternalMiscHandler(signal, handler); } - }; - if (handler != null) { - new Thread(null, runnable, sig + " handler", 0, false).start(); + } + + private InternalMiscHandler(Signal signal, SignalHandler handler) { + this.handler = handler; + this.signal = signal; + } + + @Override + public void handle(jdk.internal.misc.Signal ignore) { + handler.handle(signal); } } - /* Find the signal number, given a name. Returns -1 for unknown signals. */ - private static native int findSignal(String sigName); - /* Registers a native signal handler, and returns the old handler. - * Handler values: - * 0 default handler - * 1 ignore the signal - * 2 call back to Signal.dispatch - * other arbitrary native signal handlers + /* + * Wrapper class to proxy a jdk.internal.misc.Signal.Handler to a SignalHandler. */ - private static native long handle0(int sig, long nativeH); - /* Raise a given signal number */ - private static native void raise0(int sig); + static final class SunMiscHandler implements SignalHandler { + private final jdk.internal.misc.Signal iSignal; + private final jdk.internal.misc.Signal.Handler iHandler; + + static SignalHandler of(jdk.internal.misc.Signal signal, jdk.internal.misc.Signal.Handler handler) { + if (handler == jdk.internal.misc.Signal.Handler.SIG_DFL) { + return SignalHandler.SIG_DFL; + } else if (handler == jdk.internal.misc.Signal.Handler.SIG_IGN) { + return SignalHandler.SIG_IGN; + } else if (handler instanceof InternalMiscHandler) { + return ((InternalMiscHandler) handler).handler; + } else { + return new SunMiscHandler(signal, handler); + } + } + + SunMiscHandler(jdk.internal.misc.Signal iSignal, jdk.internal.misc.Signal.Handler iHandler) { + this.iSignal = iSignal; + this.iHandler = iHandler; + } + + @Override + public void handle(Signal sig) { + iHandler.handle(iSignal); + } + + public String toString() { + return iHandler.toString(); + } + } }
--- a/jdk/src/java.base/share/classes/sun/misc/SignalHandler.java Thu Feb 18 02:49:44 2016 +0000 +++ b/jdk/src/java.base/share/classes/sun/misc/SignalHandler.java Thu Feb 18 14:44:50 2016 -0500 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,11 +39,13 @@ /** * The default signal handler */ - public static final SignalHandler SIG_DFL = new NativeSignalHandler(0); + public static final SignalHandler SIG_DFL = + new Signal.SunMiscHandler(null, jdk.internal.misc.Signal.Handler.SIG_DFL); /** * Ignore the signal */ - public static final SignalHandler SIG_IGN = new NativeSignalHandler(1); + public static final SignalHandler SIG_IGN = + new Signal.SunMiscHandler(null, jdk.internal.misc.Signal.Handler.SIG_IGN); /** * Handle the given signal
--- a/jdk/src/java.base/share/native/libjava/NativeSignalHandler.c Thu Feb 18 02:49:44 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ -/* - * Copyright (c) 1998, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code 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 - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -#include <signal.h> -#include <stdlib.h> - -#include <jni.h> -#include <jlong.h> -#include "sun_misc_NativeSignalHandler.h" - -typedef void (*sig_handler_t)(jint, void *, void *); - -JNIEXPORT void JNICALL -Java_sun_misc_NativeSignalHandler_handle0(JNIEnv *env, jclass cls, jint sig, jlong f) -{ - /* We've lost the siginfo and context */ - (*(sig_handler_t)jlong_to_ptr(f))(sig, NULL, NULL); -}
--- a/jdk/src/java.base/share/native/libjava/Signal.c Thu Feb 18 02:49:44 2016 +0000 +++ b/jdk/src/java.base/share/native/libjava/Signal.c Thu Feb 18 14:44:50 2016 -0500 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,13 +30,18 @@ #include <jvm.h> #include <jni_util.h> #include <jlong.h> -#include "sun_misc_Signal.h" +#include "jdk_internal_misc_Signal.h" JNIEXPORT jint JNICALL -Java_sun_misc_Signal_findSignal(JNIEnv *env, jclass cls, jstring name) +Java_jdk_internal_misc_Signal_findSignal0(JNIEnv *env, jclass cls, jstring name) { jint res; - const char *cname = (*env)->GetStringUTFChars(env, name, 0); + const char *cname; + if (name == NULL) { + JNU_ThrowNullPointerException(env, "name"); + return 0; + } + cname = (*env)->GetStringUTFChars(env, name, 0); if (cname == NULL) { /* out of memory thrown */ return 0; @@ -47,13 +52,13 @@ } JNIEXPORT jlong JNICALL -Java_sun_misc_Signal_handle0(JNIEnv *env, jclass cls, jint sig, jlong handler) +Java_jdk_internal_misc_Signal_handle0(JNIEnv *env, jclass cls, jint sig, jlong handler) { return ptr_to_jlong(JVM_RegisterSignal(sig, jlong_to_ptr(handler))); } JNIEXPORT void JNICALL -Java_sun_misc_Signal_raise0(JNIEnv *env, jclass cls, jint sig) +Java_jdk_internal_misc_Signal_raise0(JNIEnv *env, jclass cls, jint sig) { JVM_RaiseSignal(sig); }
--- a/jdk/src/java.base/unix/classes/java/lang/Terminator.java Thu Feb 18 02:49:44 2016 +0000 +++ b/jdk/src/java.base/unix/classes/java/lang/Terminator.java Thu Feb 18 14:44:50 2016 -0500 @@ -25,8 +25,7 @@ package java.lang; -import sun.misc.Signal; -import sun.misc.SignalHandler; +import jdk.internal.misc.Signal; /** @@ -39,7 +38,7 @@ class Terminator { - private static SignalHandler handler = null; + private static Signal.Handler handler = null; /* Invocations of setup and teardown are already synchronized * on the shutdown lock, so no further synchronization is needed here @@ -47,7 +46,7 @@ static void setup() { if (handler != null) return; - SignalHandler sh = new SignalHandler() { + Signal.Handler sh = new Signal.Handler() { public void handle(Signal sig) { Shutdown.exit(sig.getNumber() + 0200); }
--- a/jdk/src/java.base/windows/classes/java/lang/Terminator.java Thu Feb 18 02:49:44 2016 +0000 +++ b/jdk/src/java.base/windows/classes/java/lang/Terminator.java Thu Feb 18 14:44:50 2016 -0500 @@ -25,8 +25,7 @@ package java.lang; -import sun.misc.Signal; -import sun.misc.SignalHandler; +import jdk.internal.misc.Signal; /** @@ -39,7 +38,7 @@ class Terminator { - private static SignalHandler handler = null; + private static Signal.Handler handler = null; /* Invocations of setup and teardown are already synchronized * on the shutdown lock, so no further synchronization is needed here @@ -47,7 +46,7 @@ static void setup() { if (handler != null) return; - SignalHandler sh = new SignalHandler() { + Signal.Handler sh = new Signal.Handler() { public void handle(Signal sig) { Shutdown.exit(sig.getNumber() + 0200); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/sun/misc/SunMiscSignalTest.java Thu Feb 18 14:44:50 2016 -0500 @@ -0,0 +1,398 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.Semaphore; +import java.util.concurrent.TimeUnit; + +import org.testng.Assert; +import org.testng.TestNG; +import org.testng.annotations.Test; +import org.testng.annotations.BeforeSuite; +import org.testng.annotations.DataProvider; + +import jdk.test.lib.Platform; +import jdk.test.lib.Utils; + +import sun.misc.Signal; +import sun.misc.SignalHandler; + +/* + * @test + * @library /test/lib/share/classes + * @build jdk.test.lib.Platform jdk.test.lib.Utils + * @run testng/othervm -Xrs -DXrs=true SunMiscSignalTest + * @run testng/othervm SunMiscSignalTest + * @summary sun.misc.Signal test + */ + +@Test +public class SunMiscSignalTest { + + // Set to true to enable additional debug output + static boolean debug = true; + + // True to test while running with -Xrs + static boolean RUNNING_WITH_Xrs = Boolean.getBoolean("Xrs"); + + /** + * Print a debug message if enabled. + * + * @param format the format + * @param args the arguments + */ + static void printf(String format, Object... args) { + if (debug) { + System.out.printf(" " + format, args); + } + } + + enum IsSupported {NO, YES} + + enum CanRegister {NO, YES} + + enum CanRaise {NO, YES} + + enum Invoked {NO, YES} + + enum RestrictedSignals {NORMAL, XRS} + + @BeforeSuite + static void setup() { + System.out.printf("-Xrs: %s%n", RUNNING_WITH_Xrs); + } + + // Provider of signals to be tested with variations for -Xrs and + // platform dependencies + // -Xrs restricted signals signals the VM will not handle SIGINT, SIGTERM, SIGHUP and others + @DataProvider(name = "supportedSignals") + static Object[][] supportedSignals() { + RestrictedSignals rs = RUNNING_WITH_Xrs ? RestrictedSignals.XRS : RestrictedSignals.NORMAL; + CanRegister registerXrs = RUNNING_WITH_Xrs ? CanRegister.NO : CanRegister.YES; + CanRaise raiseXrs = RUNNING_WITH_Xrs ? CanRaise.NO : CanRaise.YES; + Invoked invokedXrs = RUNNING_WITH_Xrs ? Invoked.NO : Invoked.YES; + + Object[][] commonSignals = new Object[][]{ + {"INT", IsSupported.YES, registerXrs, raiseXrs, invokedXrs}, + {"TERM", IsSupported.YES, registerXrs, raiseXrs, invokedXrs}, + {"ABRT", IsSupported.YES, CanRegister.YES, CanRaise.YES, invokedXrs}, + }; + + Object[][] posixSignals = { + {"HUP", IsSupported.YES, registerXrs, raiseXrs, invokedXrs}, + {"QUIT", IsSupported.YES, CanRegister.NO, CanRaise.NO, Invoked.NO}, + {"BUS", IsSupported.YES, CanRegister.YES, CanRaise.YES, invokedXrs}, + {"USR1", IsSupported.YES, CanRegister.YES, CanRaise.YES, invokedXrs}, + {"USR2", IsSupported.YES, CanRegister.YES, CanRaise.YES, invokedXrs}, + {"PIPE", IsSupported.YES, CanRegister.YES, CanRaise.YES, invokedXrs}, + {"ALRM", IsSupported.YES, CanRegister.YES, CanRaise.YES, invokedXrs}, + {"CHLD", IsSupported.YES, CanRegister.YES, CanRaise.YES, invokedXrs}, + {"CONT", IsSupported.YES, CanRegister.YES, CanRaise.YES, invokedXrs}, + {"TSTP", IsSupported.YES, CanRegister.YES, CanRaise.YES, invokedXrs}, + {"TTIN", IsSupported.YES, CanRegister.YES, CanRaise.YES, invokedXrs}, + {"TTOU", IsSupported.YES, CanRegister.YES, CanRaise.YES, invokedXrs}, + {"URG", IsSupported.YES, CanRegister.YES, CanRaise.YES, invokedXrs}, + {"XCPU", IsSupported.YES, CanRegister.YES, CanRaise.YES, invokedXrs}, + {"XFSZ", IsSupported.YES, CanRegister.YES, CanRaise.YES, invokedXrs}, + {"VTALRM", IsSupported.YES, CanRegister.YES, CanRaise.YES, invokedXrs}, + {"PROF", IsSupported.YES, CanRegister.YES, CanRaise.YES, invokedXrs}, + {"WINCH", IsSupported.YES, CanRegister.YES, CanRaise.YES, invokedXrs}, + {"IO", IsSupported.YES, CanRegister.YES, CanRaise.YES, invokedXrs}, + {"SYS", IsSupported.YES, CanRegister.YES, CanRaise.YES, invokedXrs}, + }; + + Object[][] windowsSignals = { + {"HUP", IsSupported.NO, CanRegister.NO, CanRaise.NO, Invoked.NO}, + {"QUIT", IsSupported.NO, CanRegister.NO, CanRaise.NO, Invoked.NO}, + {"BUS", IsSupported.NO, CanRegister.NO, CanRaise.NO, Invoked.NO}, + {"USR1", IsSupported.NO, CanRegister.NO, CanRaise.NO, Invoked.NO}, + {"USR2", IsSupported.NO, CanRegister.NO, CanRaise.NO, Invoked.NO}, + {"PIPE", IsSupported.NO, CanRegister.NO, CanRaise.NO, Invoked.NO}, + {"ALRM", IsSupported.NO, CanRegister.NO, CanRaise.NO, Invoked.NO}, + {"CHLD", IsSupported.NO, CanRegister.NO, CanRaise.NO, Invoked.NO}, + {"CONT", IsSupported.NO, CanRegister.NO, CanRaise.NO, Invoked.NO}, + {"TSTP", IsSupported.NO, CanRegister.NO, CanRaise.NO, Invoked.NO}, + {"TTIN", IsSupported.NO, CanRegister.NO, CanRaise.NO, Invoked.NO}, + {"TTOU", IsSupported.NO, CanRegister.NO, CanRaise.NO, Invoked.NO}, + {"URG", IsSupported.NO, CanRegister.NO, CanRaise.NO, Invoked.NO}, + {"XCPU", IsSupported.NO, CanRegister.NO, CanRaise.NO, Invoked.NO}, + {"XFSZ", IsSupported.NO, CanRegister.NO, CanRaise.NO, Invoked.NO}, + {"VTALRM", IsSupported.NO, CanRegister.NO, CanRaise.NO, Invoked.NO}, + {"PROF", IsSupported.NO, CanRegister.NO, CanRaise.NO, Invoked.NO}, + {"WINCH", IsSupported.NO, CanRegister.NO, CanRaise.NO, Invoked.NO}, + {"IO", IsSupported.NO, CanRegister.NO, CanRaise.NO, Invoked.NO}, + {"SYS", IsSupported.NO, CanRegister.NO, CanRaise.NO, Invoked.NO}, + }; + + return concatArrays(commonSignals, (Platform.isWindows() ? windowsSignals : posixSignals)); + } + + // Provider of invalid signal names + @DataProvider(name = "invalidSunMiscSignalNames") + Object[][] invalidSunMiscSignalNames() { + return new Object[][]{ + {""}, + {"I"}, + {"SIG"}, + {"SIGabc"}, + {"SIGINT"}, // prefix not allowed + {"abc"}, + }; + } + + static Object[][] concatArrays(Object[][]... arrays) { + int l = 0; + for (Object[][] a : arrays) { + l += a.length; + } + + Object[][] newArray = new Object[l][]; + l = 0; + for (int i = 0; i < arrays.length; i++) { + System.arraycopy(arrays[i], 0, newArray, l, arrays[i].length); + l += arrays[i].length; + } + + return newArray; + } + + /** + * Quick verification of supported signals using sun.misc.Signal. + * + * @param name the signal name + * @throws InterruptedException would be an error if thrown + */ + @Test(dataProvider = "supportedSignals") + static void testSunMisc(String name, IsSupported supported, CanRegister register, + CanRaise raise, Invoked invoked) throws InterruptedException { + Handler h = new Handler(); + SignalHandler orig = null; + Signal signal = null; + try { + signal = new Signal(name); + Assert.assertEquals(supported, IsSupported.YES, "Unexpected support for " + name); + + Assert.assertEquals(signal.getName(), name, "getName() mismatch, "); + + Assert.assertEquals(signal.toString(), "SIG" + name, "toString() mismatch, "); + + try { + SignalHandler old = Signal.handle(signal, h); + Assert.assertEquals(CanRegister.YES, register, "Unexpected handle succeeded " + name); + try { + Signal.raise(signal); + Assert.assertEquals(CanRaise.YES, raise, "Unexpected raise success for " + name); + Invoked inv = h.semaphore().tryAcquire(Utils.adjustTimeout(100L), + TimeUnit.MILLISECONDS) ? Invoked.YES : Invoked.NO; + Assert.assertEquals(inv, invoked, "handler not invoked;"); + } catch (IllegalArgumentException uoe3) { + Assert.assertNotEquals(CanRaise.YES, raise, "raise failed for " + name + + ": " + uoe3.getMessage()); + } + } catch (IllegalArgumentException uoe2) { + Assert.assertNotEquals(CanRegister.YES, register, "handle failed for: " + name + + ": " + uoe2.getMessage()); + } + } catch (IllegalArgumentException uoe) { + Assert.assertNotEquals(IsSupported.YES, supported, "Support missing for " + name + + ": " + uoe.getMessage()); + return; + } finally { + // Restore original signal handler + if (orig != null && signal != null) { + Signal.handle(signal, orig); + } + } + } + + // Test Signal is equal to itself and not equals to others + @Test(dataProvider = "supportedSignals") + static void testEquals(String name, IsSupported supported, CanRegister register, + CanRaise raise, Invoked invoked) { + Object[][] data = supportedSignals(); + for (int i = 0; i < data.length; i++) { + IsSupported otherSupported = (IsSupported) data[i][1]; + if (supported == IsSupported.NO || otherSupported == IsSupported.NO) { + continue; + } + String otherName = (String) data[i][0]; + + Signal sig1 = new Signal(name); + Signal sig2 = new Signal(otherName); + if (name.equals(otherName)) { + Assert.assertEquals(sig1, sig2, "Equals failed; "); + Assert.assertEquals(sig1.hashCode(), sig2.hashCode(), "HashCode wrong; "); + } else { + Assert.assertNotEquals(sig1, sig2, "NotEquals failed; "); + Assert.assertNotEquals(sig1.hashCode(), sig2.hashCode(), "HashCode wrong; "); + } + } + } + + @Test(dataProvider = "invalidSunMiscSignalNames") + static void testSunMiscIAE(String name) { + try { + new Signal(name); + Assert.fail("Should have thrown IAE for signal: " + name); + } catch (IllegalArgumentException iae) { + Assert.assertEquals(iae.getMessage(), "Unknown signal: " + name, "getMessage() incorrect; "); + } + } + + // Note: JDK 8 did not check/throw NPE, passing null resulted in a segv + @Test(expectedExceptions = NullPointerException.class) + static void nullSignal() { + new Signal(null); + } + + // Test expected exception when raising a signal when no handler defined + @Test(expectedExceptions = IllegalArgumentException.class) + static void testRaiseNoConsumer() { + Signal signal = new Signal("INT"); + SignalHandler orig = null; + try { + Signal.handle(signal, SignalHandler.SIG_DFL); + Signal.raise(signal); + } finally { + // Restore original signal handler + if (orig != null && signal != null) { + Signal.handle(signal, orig); + } + } + } + + /** + * The thread that runs the handler for sun.misc.Signal should be a + * Daemon thread. + */ + @Test + static void isDaemonThread() throws InterruptedException { + if (RUNNING_WITH_Xrs) { + return; + } + Handler handler = new Handler(); + Signal signal = new Signal("INT"); + Signal.handle(signal, handler); + Signal.raise(signal); + boolean handled = handler.semaphore() + .tryAcquire(Utils.adjustTimeout(100L), TimeUnit.MILLISECONDS); + Assert.assertEquals(handled, !RUNNING_WITH_Xrs, + "raising s.m.Signal did not get a callback;"); + + Assert.assertTrue(handler.wasDaemon(), "Thread.isDaemon running the handler; "); + } + + // Check that trying to invoke SIG_DFL.handle throws UnsupportedOperationException. + @Test(expectedExceptions = UnsupportedOperationException.class) + static void cannotHandleSIGDFL() { + Signal signal = new Signal("INT"); + Assert.assertNotNull(SignalHandler.SIG_DFL, "SIG_DFL null; "); + SignalHandler.SIG_DFL.handle(signal); + } + + // Check that trying to invoke SIG_IGN.handle throws UnsupportedOperationException. + @Test(expectedExceptions = UnsupportedOperationException.class) + static void cannotHandleSIGIGN() { + Signal signal = new Signal("INT"); + Assert.assertNotNull(SignalHandler.SIG_IGN, "SIG_IGN null; "); + SignalHandler.SIG_IGN.handle(signal); + } + + // Check that setting a Signal handler returns the previous handler. + @Test() + static void checkLastHandler() { + if (RUNNING_WITH_Xrs) { + return; + } + Signal signal = new Signal("TERM"); + Handler h1 = new Handler(); + Handler h2 = new Handler(); + SignalHandler orig = Signal.handle(signal, h1); + + try { + SignalHandler prev = Signal.handle(signal, h2); + Assert.assertSame(prev, h1, "prev handler mismatch"); + + prev = Signal.handle(signal, h1); + Assert.assertSame(prev, h2, "prev handler mismatch"); + } finally { + if (orig != null && signal != null) { + Signal.handle(signal, orig); + } + } + } + + /** + * Test Handler, a SignalHandler for Signal notifications. + * Signals a semaphore when invoked and records whether + * the thread calling the Handler was a daemon. + */ + static class Handler implements SignalHandler { + // A semaphore to check for accept being called + Semaphore sema = new Semaphore(0); + + Boolean wasDaemon = null; + + Semaphore semaphore() { + return sema; + } + + synchronized Boolean wasDaemon() { + return wasDaemon; + } + + /** + * Releases the semaphore when called as SignalHandler.handle. + * + * @param signal the Signal that occurred + */ + @Override + public void handle(Signal signal) { + synchronized (this) { + wasDaemon = Thread.currentThread().isDaemon(); + } + sema.release(); + printf("sun.misc.handle sig: %s, num: %d%n", signal.getName(), signal.getNumber()); + } + + public String toString() { + return "Handler: sem: " + sema.getQueueLength() + + ", wasDaemon: " + Objects.toString(wasDaemon()); + } + } + + // Main can be used to run the tests from the command line with only testng.jar. + @SuppressWarnings("raw_types") + @Test(enabled = false) + public static void main(String[] args) { + Class<?>[] testclass = {SunMiscSignalTest.class}; + TestNG testng = new TestNG(); + testng.setTestClasses(testclass); + testng.run(); + } + +}