Save This Page
Home » openjdk-7 » sun » misc » [javadoc | source]
    1   /*
    2    * Copyright (c) 1998, 2007, 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   import java.util.Hashtable;
   28   
   29   /**
   30    * This class provides ANSI/ISO C signal support. A Java program can register
   31    * signal handlers for the current process. There are two restrictions:
   32    * <ul>
   33    * <li>
   34    * Java code cannot register a handler for signals that are already used
   35    * by the Java VM implementation. The <code>Signal.handle</code>
   36    * function raises an <code>IllegalArgumentException</code> if such an attempt
   37    * is made.
   38    * <li>
   39    * When <code>Signal.handle</code> is called, the VM internally registers a
   40    * special C signal handler. There is no way to force the Java signal handler
   41    * to run synchronously before the C signal handler returns. Instead, when the
   42    * VM receives a signal, the special C signal handler creates a new thread
   43    * (at priority <code>Thread.MAX_PRIORITY</code>) to
   44    * run the registered Java signal handler. The C signal handler immediately
   45    * returns. Note that because the Java signal handler runs in a newly created
   46    * thread, it may not actually be executed until some time after the C signal
   47    * handler returns.
   48    * </ul>
   49    * <p>
   50    * Signal objects are created based on their names. For example:
   51    * <blockquote><pre>
   52    * new Signal("INT");
   53    * </blockquote></pre>
   54    * constructs a signal object corresponding to <code>SIGINT</code>, which is
   55    * typically produced when the user presses <code>Ctrl-C</code> at the command line.
   56    * The <code>Signal</code> constructor throws <code>IllegalArgumentException</code>
   57    * when it is passed an unknown signal.
   58    * <p>
   59    * This is an example of how Java code handles <code>SIGINT</code>:
   60    * <blockquote><pre>
   61    * SignalHandler handler = new SignalHandler () {
   62    *     public void handle(Signal sig) {
   63    *       ... // handle SIGINT
   64    *     }
   65    * };
   66    * Signal.handle(new Signal("INT"), handler);
   67    * </blockquote></pre>
   68    *
   69    * @author   Sheng Liang
   70    * @author   Bill Shannon
   71    * @see      sun.misc.SignalHandler
   72    * @since    1.2
   73    */
   74   public final class Signal {
   75       private static Hashtable handlers = new Hashtable(4);
   76       private static Hashtable signals = new Hashtable(4);
   77   
   78       private int number;
   79       private String name;
   80   
   81       /* Returns the signal number */
   82       public int getNumber() {
   83           return number;
   84       }
   85   
   86       /**
   87        * Returns the signal name.
   88        *
   89        * @return the name of the signal.
   90        * @see sun.misc.Signal#Signal(String name)
   91        */
   92       public String getName() {
   93           return name;
   94       }
   95   
   96       /**
   97        * Compares the equality of two <code>Signal</code> objects.
   98        *
   99        * @param other the object to compare with.
  100        * @return whether two <code>Signal</code> objects are equal.
  101        */
  102       public boolean equals(Object other) {
  103           if (this == other) {
  104               return true;
  105           }
  106           if (other == null || !(other instanceof Signal)) {
  107               return false;
  108           }
  109           Signal other1 = (Signal)other;
  110           return name.equals(other1.name) && (number == other1.number);
  111       }
  112   
  113       /**
  114        * Returns a hashcode for this Signal.
  115        *
  116        * @return  a hash code value for this object.
  117        */
  118       public int hashCode() {
  119           return number;
  120       }
  121   
  122       /**
  123        * Returns a string representation of this signal. For example, "SIGINT"
  124        * for an object constructed using <code>new Signal ("INT")</code>.
  125        *
  126        * @return a string representation of the signal
  127        */
  128       public String toString() {
  129           return "SIG" + name;
  130       }
  131   
  132       /**
  133        * Constructs a signal from its name.
  134        *
  135        * @param name the name of the signal.
  136        * @exception IllegalArgumentException unknown signal
  137        * @see sun.misc.Signal#getName()
  138        */
  139       public Signal(String name) {
  140           number = findSignal(name);
  141           this.name = name;
  142           if (number < 0) {
  143               throw new IllegalArgumentException("Unknown signal: " + name);
  144           }
  145       }
  146   
  147       /**
  148        * Registers a signal handler.
  149        *
  150        * @param sig a signal
  151        * @param handler the handler to be registered with the given signal.
  152        * @result the old handler
  153        * @exception IllegalArgumentException the signal is in use by the VM
  154        * @see sun.misc.Signal#raise(Signal sig)
  155        * @see sun.misc.SignalHandler
  156        * @see sun.misc.SignalHandler#SIG_DFL
  157        * @see sun.misc.SignalHandler#SIG_IGN
  158        */
  159       public static synchronized SignalHandler handle(Signal sig,
  160                                                       SignalHandler handler)
  161           throws IllegalArgumentException {
  162           long newH = (handler instanceof NativeSignalHandler) ?
  163                         ((NativeSignalHandler)handler).getHandler() : 2;
  164           long oldH = handle0(sig.number, newH);
  165           if (oldH == -1) {
  166               throw new IllegalArgumentException
  167                   ("Signal already used by VM or OS: " + sig);
  168           }
  169           signals.put(new Integer(sig.number), sig);
  170           synchronized (handlers) {
  171               SignalHandler oldHandler = (SignalHandler)handlers.get(sig);
  172               handlers.remove(sig);
  173               if (newH == 2) {
  174                   handlers.put(sig, handler);
  175               }
  176               if (oldH == 0) {
  177                   return SignalHandler.SIG_DFL;
  178               } else if (oldH == 1) {
  179                   return SignalHandler.SIG_IGN;
  180               } else if (oldH == 2) {
  181                   return oldHandler;
  182               } else {
  183                   return new NativeSignalHandler(oldH);
  184               }
  185           }
  186       }
  187   
  188       /**
  189        * Raises a signal in the current process.
  190        *
  191        * @param sig a signal
  192        * @see sun.misc.Signal#handle(Signal sig, SignalHandler handler)
  193        */
  194       public static void raise(Signal sig) throws IllegalArgumentException {
  195           if (handlers.get(sig) == null) {
  196               throw new IllegalArgumentException("Unhandled signal: " + sig);
  197           }
  198           raise0(sig.number);
  199       }
  200   
  201       /* Called by the VM to execute Java signal handlers. */
  202       private static void dispatch(final int number) {
  203           final Signal sig = (Signal)signals.get(new Integer(number));
  204           final SignalHandler handler = (SignalHandler)handlers.get(sig);
  205   
  206           Runnable runnable = new Runnable () {
  207               public void run() {
  208                 // Don't bother to reset the priority. Signal handler will
  209                 // run at maximum priority inherited from the VM signal
  210                 // dispatch thread.
  211                 // Thread.currentThread().setPriority(Thread.NORM_PRIORITY);
  212                   handler.handle(sig);
  213               }
  214           };
  215           if (handler != null) {
  216               new Thread(runnable, sig + " handler").start();
  217           }
  218       }
  219   
  220       /* Find the signal number, given a name. Returns -1 for unknown signals. */
  221       private static native int findSignal(String sigName);
  222       /* Registers a native signal handler, and returns the old handler.
  223        * Handler values:
  224        *   0     default handler
  225        *   1     ignore the signal
  226        *   2     call back to Signal.dispatch
  227        *   other arbitrary native signal handlers
  228        */
  229       private static native long handle0(int sig, long nativeH);
  230       /* Raise a given signal number */
  231       private static native void raise0(int sig);
  232   }

Save This Page
Home » openjdk-7 » sun » misc » [javadoc | source]