8149750: Decouple sun.misc.Signal from the base module
authorrriggs
Thu, 18 Feb 2016 14:44:50 -0500
changeset 36009 2dbdf909ac81
parent 36008 3113bdef9cb1
child 36010 8fe81891e76c
8149750: Decouple sun.misc.Signal from the base module Reviewed-by: chegar, dholmes
jdk/make/mapfiles/libjava/mapfile-vers
jdk/make/mapfiles/libjava/reorder-sparc
jdk/make/mapfiles/libjava/reorder-sparcv9
jdk/make/mapfiles/libjava/reorder-x86
jdk/src/java.base/share/classes/jdk/internal/misc/Signal.java
jdk/src/java.base/share/classes/sun/misc/NativeSignalHandler.java
jdk/src/java.base/share/classes/sun/misc/Signal.java
jdk/src/java.base/share/classes/sun/misc/SignalHandler.java
jdk/src/java.base/share/native/libjava/NativeSignalHandler.c
jdk/src/java.base/share/native/libjava/Signal.c
jdk/src/java.base/unix/classes/java/lang/Terminator.java
jdk/src/java.base/windows/classes/java/lang/Terminator.java
jdk/test/sun/misc/SunMiscSignalTest.java
--- 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();
+    }
+
+}