< prev index next >

src/java.base/share/classes/sun/misc/Signal.java

Print this page

        

*** 22,32 **** * or visit www.oracle.com if you need additional information or have any * questions. */ package sun.misc; ! import java.util.Hashtable; /** * This class provides ANSI/ISO C signal support. A Java program can register * signal handlers for the current process. There are two restrictions: * <ul> --- 22,36 ---- * or visit www.oracle.com if you need additional information or have any * questions. */ package sun.misc; ! import jdk.internal.misc.NativeSignal; ! ! import java.util.Map; ! import java.util.concurrent.ConcurrentHashMap; ! import java.util.function.Consumer; /** * This class provides ANSI/ISO C signal support. A Java program can register * signal handlers for the current process. There are two restrictions: * <ul>
*** 70,98 **** * @author Bill Shannon * @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; /* Returns the signal number */ public int getNumber() { ! return number; } /** * Returns the signal name. * * @return the name of the signal. * @see sun.misc.Signal#Signal(String name) */ public String getName() { ! return name; } /** * Compares the equality of two <code>Signal</code> objects. * --- 74,101 ---- * @author Bill Shannon * @see sun.misc.SignalHandler * @since 1.2 */ public final class Signal { ! private static final Map<Integer, UtHandler> handlers = new ConcurrentHashMap<>(4); ! ! private final java.util.Signal utSignal; /* Returns the signal number */ public int getNumber() { ! return utSignal.number(); } /** * Returns the signal name. * * @return the name of the signal. * @see sun.misc.Signal#Signal(String name) */ public String getName() { ! return utSignal.name(); } /** * Compares the equality of two <code>Signal</code> objects. *
*** 104,149 **** 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 sun.misc.Signal#getName() */ public Signal(String name) { ! number = findSignal(name); ! this.name = name; ! if (number < 0) { ! throw new IllegalArgumentException("Unknown signal: " + name); } } /** * Registers a signal handler. * --- 107,151 ---- return true; } if (other == null || !(other instanceof Signal)) { return false; } ! return utSignal == ((Signal) other).utSignal; } /** * Returns a hashcode for this Signal. * * @return a hash code value for this object. */ public int hashCode() { ! return getNumber(); } /** * 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 getName(); } /** * Constructs a signal from its name. * * @param name the name of the signal. * @exception IllegalArgumentException unknown signal * @see sun.misc.Signal#getName() */ public Signal(String name) { ! this(java.util.Signal.of("SIG" + name)); } + + private Signal(java.util.Signal utSignal) { + this.utSignal = utSignal; } /** * Registers a signal handler. *
*** 157,232 **** * @see sun.misc.SignalHandler#SIG_IGN */ 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); } } } /** * Raises a signal in the current process. * * @param sig a 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); } ! /* 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 ! */ ! private static native long handle0(int sig, long nativeH); ! /* Raise a given signal number */ ! private static native void raise0(int sig); } --- 159,259 ---- * @see sun.misc.SignalHandler#SIG_IGN */ public static synchronized SignalHandler handle(Signal sig, SignalHandler handler) throws IllegalArgumentException { ! ! UtHandler newUtHandler = handler == null ? null : UtHandler.create(handler); ! UtHandler oldUtHandler = newUtHandler == null ! ? handlers.remove(sig.getNumber()) ! : handlers.put(sig.getNumber(), newUtHandler); ! ! if (oldUtHandler != null) { ! if (!oldUtHandler.unregisterFrom(sig.utSignal)) { ! throw new IllegalStateException( ! "Can't unregister old sun.misc.SignalHandler as some new " + ! "handler has been registered with java.util.Signal API."); ! } } + + if (newUtHandler != null) { + newUtHandler.registerTo(sig.utSignal); } + + return oldUtHandler == null ? null : oldUtHandler.signalHandler; } /** * Raises a signal in the current process. * * @param sig a signal * @see sun.misc.Signal#handle(Signal sig, SignalHandler handler) */ public static void raise(Signal sig) throws IllegalArgumentException { ! if (handlers.get(sig.getNumber()) == null) { throw new IllegalArgumentException("Unhandled signal: " + sig); } ! sig.utSignal.raise(); ! } ! ! // abstraction of Java and Native handlers for java.util.Signal API ! // with delegation to sun.misc.[SignalHandler|NativeSignalHandler] ! private static abstract class UtHandler { ! final SignalHandler signalHandler; ! ! static UtHandler create(SignalHandler signalHandler) { ! return (signalHandler instanceof NativeSignalHandler) ! ? new UtHandler.Native((NativeSignalHandler) signalHandler) ! : new UtHandler.Java(signalHandler); ! } ! ! UtHandler(SignalHandler signalHandler) { ! this.signalHandler = signalHandler; ! } ! ! abstract void registerTo(java.util.Signal utSignal); ! ! abstract boolean unregisterFrom(java.util.Signal utSignal); ! ! private static class Java extends UtHandler ! implements Consumer<java.util.Signal> { ! Java(SignalHandler signalHandler) { ! super(signalHandler); ! } ! ! @Override ! public void accept(java.util.Signal uSignal) { ! signalHandler.handle(new Signal(uSignal)); ! } ! ! @Override ! void registerTo(java.util.Signal utSignal) { ! utSignal.register(this); } ! @Override ! boolean unregisterFrom(java.util.Signal utSignal) { ! return utSignal.unregister(this); } } ! private static class Native extends UtHandler { ! Native(NativeSignalHandler signalHandler) { ! super(signalHandler); ! } ! ! @Override ! void registerTo(java.util.Signal utSignal) { ! ((NativeSignal) utSignal).register( ! ((NativeSignalHandler) signalHandler).getHandler() ! ); ! } ! ! @Override ! boolean unregisterFrom(java.util.Signal utSignal) { ! return ((NativeSignal) utSignal).unregister( ! ((NativeSignalHandler) signalHandler).getHandler() ! ); ! } ! } ! } }
< prev index next >