< 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 >