--- /dev/null 2018-11-02 08:21:52.000000000 -0700 +++ new/src/java.base/share/classes/jdk/internal/unsupported/SignalDelegate.java 2018-11-02 08:21:52.000000000 -0700 @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2018, 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.unsupported; + +public final class SignalDelegate { + // Delegate to jdk.internal.misc.Signal. + private final jdk.internal.misc.Signal iSignal; + + /** + * Constructs a signal from its name. + * + * @param name the name of the signal. + * @exception IllegalArgumentException unknown signal + */ + public SignalDelegate(String name) { + iSignal = new jdk.internal.misc.Signal(name); + } + + /* Returns the signal number */ + public int getNumber() { + return iSignal.getNumber(); + } + + /** + * Returns the signal name. + * + * @return the name of the signal. + */ + public String getName() { + return iSignal.getName(); + } + + /** + * 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 SignalDelegate)) { + return false; + } + SignalDelegate other1 = (SignalDelegate)other; + return iSignal.equals(other1.iSignal); + } + + /** + * 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 new Signal ("INT"). + * + * @return a string representation of the signal + */ + public String toString() { + return iSignal.toString(); + } + + + /** + * 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 + */ + public static synchronized Handler handle(SignalDelegate sig, Handler handler) { + jdk.internal.misc.Signal.Handler oldHandler = jdk.internal.misc.Signal.handle(sig.iSignal, + InternalMiscHandler.of(sig, handler)); + return new HandlerProxy(sig.iSignal, oldHandler); + } + + /** + * Raises a signal in the current process. + * + * @param sig a signal + */ + public static void raise(SignalDelegate sig) throws IllegalArgumentException { + jdk.internal.misc.Signal.raise(sig.iSignal); + } + + public interface Handler { + /** + * The default signal handler + */ + public static final Handler SIG_DFL = + new HandlerProxy(null, jdk.internal.misc.Signal.Handler.SIG_DFL); + + /** + * Ignore the signal + */ + public static final Handler SIG_IGN = + new HandlerProxy(null, jdk.internal.misc.Signal.Handler.SIG_IGN); + + + public void handle(SignalDelegate ignore); + } + + static class HandlerProxy implements Handler { + private final jdk.internal.misc.Signal iSignal; + private final jdk.internal.misc.Signal.Handler iHandler; + + static Handler of(jdk.internal.misc.Signal signal, jdk.internal.misc.Signal.Handler handler) { + if (handler == SignalDelegate.Handler.SIG_DFL) { + return Handler.SIG_DFL; + } else if (handler == SignalDelegate.Handler.SIG_IGN) { + return Handler.SIG_IGN; + } else if (handler instanceof InternalMiscHandler) { + return ((InternalMiscHandler) handler).handler; + } else { + return new HandlerProxy(signal, handler); + } + } + + HandlerProxy(jdk.internal.misc.Signal iSignal, jdk.internal.misc.Signal.Handler iHandler) { + this.iSignal = iSignal; + this.iHandler = iHandler; + } + + @Override + public void handle(SignalDelegate ignore) { + iHandler.handle(iSignal); + } + } + + static final class InternalMiscHandler implements jdk.internal.misc.Signal.Handler { + private final Handler handler; + private final SignalDelegate signal; + + static jdk.internal.misc.Signal.Handler of(SignalDelegate signal, Handler handler) { + if (handler == Handler.SIG_DFL) { + return jdk.internal.misc.Signal.Handler.SIG_DFL; + } else if (handler == Handler.SIG_IGN) { + return jdk.internal.misc.Signal.Handler.SIG_IGN; + } else if (handler instanceof HandlerProxy) { + return ((HandlerProxy)handler).iHandler; + } else { + return new InternalMiscHandler(signal, handler); + } + } + + private InternalMiscHandler(SignalDelegate signal, Handler handler) { + this.handler = handler; + this.signal = signal; + } + + @Override + public void handle(jdk.internal.misc.Signal ignore) { + handler.handle(signal); + } + } +}