001    package javax.realtime;
002    
003    import java.util.HashMap;
004    
005    /** Use instances of <code>AsyncEvent</code> to handle POSIX signals. Usage:
006     *  <p>
007     *  <code>
008     *      POSIXSignalHandler.addHandler(SIGINT, intHandler);
009     *  </code>
010     *  <p>
011     *  This class is required to be implemented only if the underlying
012     *  system supports POSIX signals.
013     */
014    public final class POSIXSignalHandler {
015    
016        // Spec says all these fields should be final, but I don't see how
017        // to make them final and to guarantee the "platform independence".
018        // So I just "un-final-ed" them, and I'll set them at the runtime,
019        // using JNI.
020    
021        /** Used by abort, replace <code>SIBIOT</code> in the future. */
022        public static /*final*/ int SIGABRT;
023        /** Alarm clock. */
024        public static /*final*/ int SIGALRM;
025        /** Bus error. */
026        public static /*final*/ int SIGBUS;
027        /** Thread cancellation signal used by <code>libthread</code>. */
028        public static /*final*/ int SIGCANCEL;
029        /** Child status change alis (POSIX). */
030        public static /*final*/ int SIGCHLD;
031        /** Child status change. */
032        public static /*final*/ int SIGCLD;
033        /** Stopped process has been continued. */
034        public static /*final*/ int SIGCONT;
035        /** EMT instructions. */
036        public static /*final*/ int SIGEMT;
037        /**  Floaating point exception. */
038        public static /*final*/ int SIGFPE;
039        /** Special signal used by CPR. */
040        public static /*final*/ int SIGFREEZE;
041        /** Hangup. */
042        public static /*final*/ int SIGHUP;
043        /** Illegal instruction (not reset when caught). */
044        public static /*final*/ int SIGILL;
045        /** Interrupt (rubout). */
046        public static /*final*/ int SIGINT;
047        /** Socked I/O possible (<code>SIGPOLL alias). */
048        public static /*final*/ int SIGIO;
049        /** IOT instruction. */
050        public static /*final*/ int SIGIOT;
051        /** Kill (cannot be caught or ignored). */
052        public static /*final*/ int SIGKILL;
053        /** Resource lost (e.g., record-lock lost). */
054        public static /*final*/ int SIGLOST;
055        /** Special signal used by thread library. */
056        public static /*final*/ int SIGLWP;
057        /** Write on a pipe with no one to read it. */
058        public static /*final*/ int SIGPIPE;
059        /** Pollable event occured. */
060        public static /*final*/ int SIGPOLL;
061        /** Profiling timer expired. */
062        public static /*final*/ int SIGPROF;
063        /** Power-fail restart. */
064        public static /*final*/ int SIGPWR;
065        /** Quit (ASCII FS). */
066        public static /*final*/ int SIGQUIT;
067        /** Segmentation violation. */
068        public static /*final*/ int SIGSEGV;
069        /** Stop (cannot be caught or ignored). */
070        public static /*final*/ int SIGSTOP;
071        /** Bad argument to system call. */
072        public static /*final*/ int SIGSYS;
073        /** Software termination signal from kill. */
074        public static /*final*/ int SIGTERM;
075        /** Special signal used by CPR. */
076        public static /*final*/ int SIGTHAW;
077        /** Trace trap (not reset when caught). */
078        public static /*final*/ int SIGTRAP;
079        /** User stop requested from tty. */
080        public static /*final*/ int SIGTSTP;
081        /** Background tty read attempted. */
082        public static /*final*/ int SIGTTIN;
083        /** Background tty write attempted. */
084        public static /*final*/ int SIGTTOU;
085        /** Urgent socket condition. */
086        public static /*final*/ int SIGURG;
087        /** User defined signal = 1. */
088        public static /*final*/ int SIGUSR1;
089        /** User defined signal = 2. */
090        public static /*final*/ int SIGUSR2;
091        /** Virtual timer expired. */
092        public static /*final*/ int SIGVTALRM;
093        /** Process's lwps are blocked. */
094        public static /*final*/ int SIGWAITING;
095        /** Window size change. */
096        public static /*final*/ int SIGWINCH;
097        /** Exceeded cpu limit. */
098        public static /*final*/ int SIGXCPU;
099        /** Exceeded file size limit. */
100        public static /*final*/ int SIGXFSZ;
101    
102        // I don't know what are the codes of all these signals, but I guess they are all <50.
103        // If you know that any of these signals has a code >50, just change MAX_SIG.
104        private static final int MAX_SIG = 50;
105        private static AsyncEvent[] signalsHandlersList = new AsyncEvent[MAX_SIG];
106        
107        public POSIXSignalHandler() {
108            setSignals();
109            for (int i = 0; i < MAX_SIG; i++) signalsHandlersList[i] = new AsyncEvent();
110        }
111    
112        /** Add the given <code>AsyncEventHandler</code> to the list of
113         *  handlers of the <code>AsyncEvent</code> of the given signal.
114         *
115         *  @param signal One of the POSIX signals from <code>this</code> (e.g.,
116         *                <code>this.SIGLOST</code>). If the value given to
117         *                <code>signal</code> is not one of the POSIX signals
118         *                then a <code>java.lang.IllegalArgumentException</code>
119         *                will be thrown.
120         *  @param handler An <code>AsyncEventHandler</code> which will be
121         *                 scheduled when the given signal occurs.
122         */
123        public static void addHandler(int signal, AsyncEventHandler handler) {
124            signalsHandlersList[signal].addHandler(handler);
125        }
126    
127        /** Remove the given <code>AsyncEventHandler</code> to the list
128         *  of handlers of the <code>AsyncEvent</code> of the given signal.
129         *
130         *  @param signal One of the POSIX signals from <code>this</code> (e.g.,
131         *                <code>this.SIGLOST</code>). If the value given to
132         *                <code>signal</code> is not one of the POSIX signals
133         *                then a <code>java.lang.IllegalArgumentException</code>
134         *                will be thrown.
135         *  @param handler An <code>AsyncEventHandler</code> which will be
136         *                 scheduled when the given signal occurs.
137         */
138        public static void removeHandler(int signal, AsyncEventHandler handler) {
139            signalsHandlersList[signal].removeHandler(handler);
140        }
141    
142        /** Set the given <code>AsyncEventHandler</code> as the handler
143         *  of the <code>AsyncEvent</code> of the given signal.
144         *  @param signal One of the POSIX signals from <code>this</code> (e.g.,
145         *                <code>this.SIGLOST</code>). If the value given to
146         *                <code>signal</code> is not one of the POSIX signals
147         *                then a <code>java.lang.IllegalArgumentException</code>
148         *                will be thrown.
149         *  @param handler An <code>AsyncEventHandler</code> which will be
150         *                 scheduled when the given signal occurs. If
151         *                 <code>handler</code> is null then no handler will be
152         *                 associated with <code>this</code> (i.e., remove all handlers).
153         */
154        public static void setHandler(int signal, AsyncEventHandler handler) {
155            signalsHandlersList[signal].setHandler(handler);
156        }
157    
158        /** Assigns machine-dependent values to all <code>SIGxxxx</code> constants. */
159        private native void setSignals();
160    }