diff --git a/jdk/make/mapfiles/libjava/mapfile-vers b/jdk/make/mapfiles/libjava/mapfile-vers
index faf1cc130fe..e6e6c6cfee8 100644
--- a/jdk/make/mapfiles/libjava/mapfile-vers
+++ b/jdk/make/mapfiles/libjava/mapfile-vers
@@ -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 @@ SUNWprivate_1.1 {
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;
diff --git a/jdk/make/mapfiles/libjava/reorder-sparc b/jdk/make/mapfiles/libjava/reorder-sparc
index 3994c916c2d..db653652f4f 100644
--- a/jdk/make/mapfiles/libjava/reorder-sparc
+++ b/jdk/make/mapfiles/libjava/reorder-sparc
@@ -35,8 +35,6 @@ text: .text%Java_sun_reflect_NativeConstructorAccessorImpl_newInstance0;
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;
diff --git a/jdk/make/mapfiles/libjava/reorder-sparcv9 b/jdk/make/mapfiles/libjava/reorder-sparcv9
index 63a667f0124..d6e3a326b35 100644
--- a/jdk/make/mapfiles/libjava/reorder-sparcv9
+++ b/jdk/make/mapfiles/libjava/reorder-sparcv9
@@ -39,8 +39,6 @@ text: .text%Java_java_lang_Throwable_fillInStackTrace;
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;
diff --git a/jdk/make/mapfiles/libjava/reorder-x86 b/jdk/make/mapfiles/libjava/reorder-x86
index c6c3fced9f6..0728f662c03 100644
--- a/jdk/make/mapfiles/libjava/reorder-x86
+++ b/jdk/make/mapfiles/libjava/reorder-x86
@@ -81,8 +81,6 @@ text: .text%Java_java_lang_reflect_Array_newArray;
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;
diff --git a/jdk/src/java.base/share/classes/jdk/internal/misc/Signal.java b/jdk/src/java.base/share/classes/jdk/internal/misc/Signal.java
new file mode 100644
index 00000000000..92adbbe295e
--- /dev/null
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/Signal.java
@@ -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:
+ *
+ * -
+ * Java code cannot register a handler for signals that are already used
+ * by the Java VM implementation. The
Signal.handle
+ * function raises an IllegalArgumentException
if such an attempt
+ * is made.
+ * -
+ * When
Signal.handle
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 Thread.MAX_PRIORITY
) 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.
+ *
+ *
+ * Signal objects are created based on their names. For example:
+ *
+ * new Signal("INT");
+ *
+ * constructs a signal object corresponding to SIGINT
, which is
+ * typically produced when the user presses Ctrl-C
at the command line.
+ * The Signal
constructor throws IllegalArgumentException
+ * when it is passed an unknown signal.
+ *
+ * This is an example of how Java code handles SIGINT
:
+ *
+ * Signal.Handler handler = new Signal.Handler () {
+ * public void handle(Signal sig) {
+ * ... // handle SIGINT
+ * }
+ * };
+ * Signal.handle(new Signal("INT"), handler);
+ *
+ *
+ * @since 9
+ */
+public final class Signal {
+ private static Hashtable handlers = new Hashtable<>(4);
+ private static Hashtable 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 Signal
objects.
+ *
+ * @param other the object to compare with.
+ * @return whether two Signal
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 new Signal ("INT")
.
+ *
+ * @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 Signal.handle
.
+ */
+ 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");
+ }
+ }
+
+}
diff --git a/jdk/src/java.base/share/classes/sun/misc/NativeSignalHandler.java b/jdk/src/java.base/share/classes/sun/misc/NativeSignalHandler.java
deleted file mode 100644
index 39c68c29b54..00000000000
--- a/jdk/src/java.base/share/classes/sun/misc/NativeSignalHandler.java
+++ /dev/null
@@ -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);
-}
diff --git a/jdk/src/java.base/share/classes/sun/misc/Signal.java b/jdk/src/java.base/share/classes/sun/misc/Signal.java
index 6094de35509..3e6de4a2736 100644
--- a/jdk/src/java.base/share/classes/sun/misc/Signal.java
+++ b/jdk/src/java.base/share/classes/sun/misc/Signal.java
@@ -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 @@ import java.util.Hashtable;
*
* @author Sheng Liang
* @author Bill Shannon
- * @see sun.misc.SignalHandler
+ * @see sun.misc.SignalHandler
* @since 1.2
*/
public final class Signal {
- private static Hashtable handlers = new Hashtable<>(4);
- private static Hashtable 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 @@ public final class Signal {
* @see sun.misc.Signal#Signal(String name)
*/
public String getName() {
- return name;
+ return iSignal.getName();
}
/**
@@ -107,7 +106,7 @@ public final class Signal {
return false;
}
Signal other1 = (Signal)other;
- return name.equals(other1.name) && (number == other1.number);
+ return iSignal.equals(other1.iSignal);
}
/**
@@ -116,7 +115,7 @@ public final class Signal {
* @return a hash code value for this object.
*/
public int hashCode() {
- return number;
+ return getNumber();
}
/**
@@ -126,7 +125,7 @@ public final class Signal {
* @return a string representation of the signal
*/
public String toString() {
- return "SIG" + name;
+ return iSignal.toString();
}
/**
@@ -137,11 +136,7 @@ public final class Signal {
* @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 final class Signal {
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 @@ public final class Signal {
* @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);
-
- 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 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 SignalHandler to a jdk.internal.misc.Signal.Handler.
*/
- private static native long handle0(int sig, long nativeH);
- /* Raise a given signal number */
- private static native void raise0(int sig);
+ static final class InternalMiscHandler implements jdk.internal.misc.Signal.Handler {
+ private final SignalHandler handler;
+ private final Signal signal;
+
+ 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);
+ }
+ }
+
+ private InternalMiscHandler(Signal signal, SignalHandler handler) {
+ this.handler = handler;
+ this.signal = signal;
+ }
+
+ @Override
+ public void handle(jdk.internal.misc.Signal ignore) {
+ handler.handle(signal);
+ }
+ }
+
+ /*
+ * Wrapper class to proxy a jdk.internal.misc.Signal.Handler to a SignalHandler.
+ */
+ 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();
+ }
+ }
}
diff --git a/jdk/src/java.base/share/classes/sun/misc/SignalHandler.java b/jdk/src/java.base/share/classes/sun/misc/SignalHandler.java
index e6cc96e73c1..1211510112b 100644
--- a/jdk/src/java.base/share/classes/sun/misc/SignalHandler.java
+++ b/jdk/src/java.base/share/classes/sun/misc/SignalHandler.java
@@ -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 @@ public interface SignalHandler {
/**
* 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
diff --git a/jdk/src/java.base/share/native/libjava/NativeSignalHandler.c b/jdk/src/java.base/share/native/libjava/NativeSignalHandler.c
deleted file mode 100644
index 23c75898a39..00000000000
--- a/jdk/src/java.base/share/native/libjava/NativeSignalHandler.c
+++ /dev/null
@@ -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
-#include
-
-#include
-#include
-#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);
-}
diff --git a/jdk/src/java.base/share/native/libjava/Signal.c b/jdk/src/java.base/share/native/libjava/Signal.c
index da1bc1932bc..5163a75bf21 100644
--- a/jdk/src/java.base/share/native/libjava/Signal.c
+++ b/jdk/src/java.base/share/native/libjava/Signal.c
@@ -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
#include
#include
-#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 @@ Java_sun_misc_Signal_findSignal(JNIEnv *env, jclass cls, jstring name)
}
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);
}
diff --git a/jdk/src/java.base/unix/classes/java/lang/Terminator.java b/jdk/src/java.base/unix/classes/java/lang/Terminator.java
index 569773b68da..41a134db89e 100644
--- a/jdk/src/java.base/unix/classes/java/lang/Terminator.java
+++ b/jdk/src/java.base/unix/classes/java/lang/Terminator.java
@@ -25,8 +25,7 @@
package java.lang;
-import sun.misc.Signal;
-import sun.misc.SignalHandler;
+import jdk.internal.misc.Signal;
/**
@@ -39,7 +38,7 @@ import sun.misc.SignalHandler;
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 @@ class Terminator {
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);
}
diff --git a/jdk/src/java.base/windows/classes/java/lang/Terminator.java b/jdk/src/java.base/windows/classes/java/lang/Terminator.java
index 4b2c2847bf6..a4d7c6e590b 100644
--- a/jdk/src/java.base/windows/classes/java/lang/Terminator.java
+++ b/jdk/src/java.base/windows/classes/java/lang/Terminator.java
@@ -25,8 +25,7 @@
package java.lang;
-import sun.misc.Signal;
-import sun.misc.SignalHandler;
+import jdk.internal.misc.Signal;
/**
@@ -39,7 +38,7 @@ import sun.misc.SignalHandler;
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 @@ class Terminator {
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);
}
diff --git a/jdk/test/sun/misc/SunMiscSignalTest.java b/jdk/test/sun/misc/SunMiscSignalTest.java
new file mode 100644
index 00000000000..4179b000b85
--- /dev/null
+++ b/jdk/test/sun/misc/SunMiscSignalTest.java
@@ -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();
+ }
+
+}