jdk/src/java.base/share/classes/sun/misc/Signal.java
changeset 37010 467b7b9caa2b
parent 37009 476d8d615222
parent 36988 4b12a11168e8
child 37011 c84d0cce090e
equal deleted inserted replaced
37009:476d8d615222 37010:467b7b9caa2b
     1 /*
       
     2  * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.  Oracle designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Oracle in the LICENSE file that accompanied this code.
       
    10  *
       
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    14  * version 2 for more details (a copy is included in the LICENSE file that
       
    15  * accompanied this code).
       
    16  *
       
    17  * You should have received a copy of the GNU General Public License version
       
    18  * 2 along with this work; if not, write to the Free Software Foundation,
       
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    20  *
       
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    22  * or visit www.oracle.com if you need additional information or have any
       
    23  * questions.
       
    24  */
       
    25 
       
    26 package sun.misc;
       
    27 
       
    28 import java.util.Objects;
       
    29 
       
    30 /**
       
    31  * This class provides ANSI/ISO C signal support. A Java program can register
       
    32  * signal handlers for the current process. There are two restrictions:
       
    33  * <ul>
       
    34  * <li>
       
    35  * Java code cannot register a handler for signals that are already used
       
    36  * by the Java VM implementation. The <code>Signal.handle</code>
       
    37  * function raises an <code>IllegalArgumentException</code> if such an attempt
       
    38  * is made.
       
    39  * <li>
       
    40  * When <code>Signal.handle</code> is called, the VM internally registers a
       
    41  * special C signal handler. There is no way to force the Java signal handler
       
    42  * to run synchronously before the C signal handler returns. Instead, when the
       
    43  * VM receives a signal, the special C signal handler creates a new thread
       
    44  * (at priority <code>Thread.MAX_PRIORITY</code>) to
       
    45  * run the registered Java signal handler. The C signal handler immediately
       
    46  * returns. Note that because the Java signal handler runs in a newly created
       
    47  * thread, it may not actually be executed until some time after the C signal
       
    48  * handler returns.
       
    49  * </ul>
       
    50  * <p>
       
    51  * Signal objects are created based on their names. For example:
       
    52  * <blockquote><pre>
       
    53  * new Signal("INT");
       
    54  * </pre></blockquote>
       
    55  * constructs a signal object corresponding to <code>SIGINT</code>, which is
       
    56  * typically produced when the user presses <code>Ctrl-C</code> at the command line.
       
    57  * The <code>Signal</code> constructor throws <code>IllegalArgumentException</code>
       
    58  * when it is passed an unknown signal.
       
    59  * <p>
       
    60  * This is an example of how Java code handles <code>SIGINT</code>:
       
    61  * <blockquote><pre>
       
    62  * SignalHandler handler = new SignalHandler () {
       
    63  *     public void handle(Signal sig) {
       
    64  *       ... // handle SIGINT
       
    65  *     }
       
    66  * };
       
    67  * Signal.handle(new Signal("INT"), handler);
       
    68  * </pre></blockquote>
       
    69  *
       
    70  * @author   Sheng Liang
       
    71  * @author   Bill Shannon
       
    72  * @see     sun.misc.SignalHandler
       
    73  * @since    1.2
       
    74  */
       
    75 public final class Signal {
       
    76 
       
    77     // Delegate to jdk.internal.misc.Signal.
       
    78     private final jdk.internal.misc.Signal iSignal;
       
    79 
       
    80     /* Returns the signal number */
       
    81     public int getNumber() {
       
    82         return iSignal.getNumber();
       
    83     }
       
    84 
       
    85     /**
       
    86      * Returns the signal name.
       
    87      *
       
    88      * @return the name of the signal.
       
    89      * @see sun.misc.Signal#Signal(String name)
       
    90      */
       
    91     public String getName() {
       
    92         return iSignal.getName();
       
    93     }
       
    94 
       
    95     /**
       
    96      * Compares the equality of two <code>Signal</code> objects.
       
    97      *
       
    98      * @param other the object to compare with.
       
    99      * @return whether two <code>Signal</code> objects are equal.
       
   100      */
       
   101     public boolean equals(Object other) {
       
   102         if (this == other) {
       
   103             return true;
       
   104         }
       
   105         if (other == null || !(other instanceof Signal)) {
       
   106             return false;
       
   107         }
       
   108         Signal other1 = (Signal)other;
       
   109         return iSignal.equals(other1.iSignal);
       
   110     }
       
   111 
       
   112     /**
       
   113      * Returns a hashcode for this Signal.
       
   114      *
       
   115      * @return  a hash code value for this object.
       
   116      */
       
   117     public int hashCode() {
       
   118         return getNumber();
       
   119     }
       
   120 
       
   121     /**
       
   122      * Returns a string representation of this signal. For example, "SIGINT"
       
   123      * for an object constructed using <code>new Signal ("INT")</code>.
       
   124      *
       
   125      * @return a string representation of the signal
       
   126      */
       
   127     public String toString() {
       
   128         return iSignal.toString();
       
   129     }
       
   130 
       
   131     /**
       
   132      * Constructs a signal from its name.
       
   133      *
       
   134      * @param name the name of the signal.
       
   135      * @exception IllegalArgumentException unknown signal
       
   136      * @see sun.misc.Signal#getName()
       
   137      */
       
   138     public Signal(String name) {
       
   139         iSignal = new jdk.internal.misc.Signal(name);
       
   140     }
       
   141 
       
   142     /**
       
   143      * Registers a signal handler.
       
   144      *
       
   145      * @param sig a signal
       
   146      * @param handler the handler to be registered with the given signal.
       
   147      * @return the old handler
       
   148      * @exception IllegalArgumentException the signal is in use by the VM
       
   149      * @see sun.misc.Signal#raise(Signal sig)
       
   150      * @see sun.misc.SignalHandler
       
   151      * @see sun.misc.SignalHandler#SIG_DFL
       
   152      * @see sun.misc.SignalHandler#SIG_IGN
       
   153      */
       
   154     public static synchronized SignalHandler handle(Signal sig,
       
   155                                                     SignalHandler handler)
       
   156         throws IllegalArgumentException {
       
   157         jdk.internal.misc.Signal.Handler oldHandler = jdk.internal.misc.Signal.handle(sig.iSignal,
       
   158                 InternalMiscHandler.of(sig, handler));
       
   159         return SunMiscHandler.of(sig.iSignal, oldHandler);
       
   160     }
       
   161 
       
   162     /**
       
   163      * Raises a signal in the current process.
       
   164      *
       
   165      * @param sig a signal
       
   166      * @see sun.misc.Signal#handle(Signal sig, SignalHandler handler)
       
   167      */
       
   168     public static void raise(Signal sig) throws IllegalArgumentException {
       
   169         jdk.internal.misc.Signal.raise(sig.iSignal);
       
   170     }
       
   171 
       
   172     /*
       
   173      * Wrapper class to proxy a SignalHandler to a jdk.internal.misc.Signal.Handler.
       
   174      */
       
   175     static final class InternalMiscHandler implements jdk.internal.misc.Signal.Handler {
       
   176         private final SignalHandler handler;
       
   177         private final Signal signal;
       
   178 
       
   179         static jdk.internal.misc.Signal.Handler of(Signal signal, SignalHandler handler) {
       
   180             if (handler == SignalHandler.SIG_DFL) {
       
   181                 return jdk.internal.misc.Signal.Handler.SIG_DFL;
       
   182             } else if (handler == SignalHandler.SIG_IGN) {
       
   183                 return jdk.internal.misc.Signal.Handler.SIG_IGN;
       
   184             } else if (handler instanceof SunMiscHandler) {
       
   185                 return ((SunMiscHandler)handler).iHandler;
       
   186             } else {
       
   187                 return new InternalMiscHandler(signal, handler);
       
   188             }
       
   189         }
       
   190 
       
   191         private InternalMiscHandler(Signal signal, SignalHandler handler) {
       
   192             this.handler = handler;
       
   193             this.signal = signal;
       
   194         }
       
   195 
       
   196         @Override
       
   197         public void handle(jdk.internal.misc.Signal ignore) {
       
   198             handler.handle(signal);
       
   199         }
       
   200     }
       
   201 
       
   202     /*
       
   203      * Wrapper class to proxy a jdk.internal.misc.Signal.Handler to a SignalHandler.
       
   204      */
       
   205     static final class SunMiscHandler implements SignalHandler {
       
   206         private final jdk.internal.misc.Signal iSignal;
       
   207         private final jdk.internal.misc.Signal.Handler iHandler;
       
   208 
       
   209         static SignalHandler of(jdk.internal.misc.Signal signal, jdk.internal.misc.Signal.Handler handler) {
       
   210             if (handler == jdk.internal.misc.Signal.Handler.SIG_DFL) {
       
   211                 return SignalHandler.SIG_DFL;
       
   212             } else if (handler == jdk.internal.misc.Signal.Handler.SIG_IGN) {
       
   213                 return SignalHandler.SIG_IGN;
       
   214             } else if (handler instanceof InternalMiscHandler) {
       
   215                 return ((InternalMiscHandler) handler).handler;
       
   216             } else {
       
   217                 return new SunMiscHandler(signal, handler);
       
   218             }
       
   219         }
       
   220 
       
   221         SunMiscHandler(jdk.internal.misc.Signal iSignal, jdk.internal.misc.Signal.Handler iHandler) {
       
   222             this.iSignal = iSignal;
       
   223             this.iHandler = iHandler;
       
   224         }
       
   225 
       
   226         @Override
       
   227         public void handle(Signal sig) {
       
   228             iHandler.handle(iSignal);
       
   229         }
       
   230 
       
   231         public String toString() {
       
   232             return iHandler.toString();
       
   233         }
       
   234     }
       
   235 }