fix haddock submodule pointer
[ghc-hetmet.git] / rts / posix / Signals.c
1 /* -----------------------------------------------------------------------------
2  *
3  * (c) The GHC Team, 1998-2005
4  *
5  * Signal processing / handling.
6  *
7  * ---------------------------------------------------------------------------*/
8
9 #include "PosixSource.h" 
10 #include "Rts.h"
11
12 #include "Schedule.h"
13 #include "RtsSignals.h"
14 #include "Signals.h"
15 #include "RtsUtils.h"
16 #include "Prelude.h"
17 #include "Stable.h"
18
19 #ifdef alpha_HOST_ARCH
20 # if defined(linux_HOST_OS)
21 #  include <asm/fpu.h>
22 # else
23 #  include <machine/fpu.h>
24 # endif
25 #endif
26
27 #ifdef HAVE_UNISTD_H
28 # include <unistd.h>
29 #endif
30
31 #ifdef HAVE_SIGNAL_H
32 # include <signal.h>
33 #endif
34
35 #ifdef HAVE_ERRNO_H
36 # include <errno.h>
37 #endif
38
39 #ifdef HAVE_EVENTFD_H
40 # include <sys/eventfd.h>
41 #endif
42
43 #ifdef HAVE_TERMIOS_H
44 #include <termios.h>
45 #endif
46
47 #include <stdlib.h>
48 #include <string.h>
49
50 /* This curious flag is provided for the benefit of the Haskell binding
51  * to POSIX.1 to control whether or not to include SA_NOCLDSTOP when
52  * installing a SIGCHLD handler. 
53  */
54 HsInt nocldstop = 0;
55
56 /* -----------------------------------------------------------------------------
57  * The table of signal handlers
58  * -------------------------------------------------------------------------- */
59
60 #if defined(RTS_USER_SIGNALS)
61
62 /* SUP: The type of handlers is a little bit, well, doubtful... */
63 StgInt *signal_handlers = NULL; /* Dynamically grown array of signal handlers */
64 static StgInt nHandlers = 0;    /* Size of handlers array */
65
66 static nat n_haskell_handlers = 0;
67
68 /* -----------------------------------------------------------------------------
69  * Allocate/resize the table of signal handlers.
70  * -------------------------------------------------------------------------- */
71
72 static void
73 more_handlers(int sig)
74 {
75     StgInt i;
76
77     if (sig < nHandlers)
78         return;
79
80     if (signal_handlers == NULL)
81         signal_handlers = (StgInt *)stgMallocBytes((sig + 1) * sizeof(StgInt), "more_handlers");
82     else
83         signal_handlers = (StgInt *)stgReallocBytes(signal_handlers, (sig + 1) * sizeof(StgInt), "more_handlers");
84
85     for(i = nHandlers; i <= sig; i++)
86         // Fill in the new slots with default actions
87         signal_handlers[i] = STG_SIG_DFL;
88
89     nHandlers = sig + 1;
90 }
91
92 // Here's the pipe into which we will send our signals
93 static int io_manager_wakeup_fd = -1;
94 static int io_manager_control_fd = -1;
95
96 #define IO_MANAGER_WAKEUP 0xff
97 #define IO_MANAGER_DIE    0xfe
98 #define IO_MANAGER_SYNC   0xfd
99
100 void
101 setIOManagerWakeupFd (int fd)
102 {
103     // only called when THREADED_RTS, but unconditionally
104     // compiled here because GHC.Event.Control depends on it.
105     io_manager_wakeup_fd = fd;
106 }
107
108 void
109 setIOManagerControlFd (int fd)
110 {
111     // only called when THREADED_RTS, but unconditionally
112     // compiled here because GHC.Event.Control depends on it.
113     io_manager_control_fd = fd;
114 }
115
116 void
117 ioManagerWakeup (void)
118 {
119     int r;
120     // Wake up the IO Manager thread by sending a byte down its pipe
121     if (io_manager_wakeup_fd >= 0) {
122 #if defined(HAVE_EVENTFD)
123         StgWord64 n = (StgWord64)IO_MANAGER_WAKEUP;
124         r = write(io_manager_wakeup_fd, (char *) &n, 8);
125 #else
126         StgWord8 byte = (StgWord8)IO_MANAGER_WAKEUP;
127         r = write(io_manager_wakeup_fd, &byte, 1);
128 #endif
129         if (r == -1) { sysErrorBelch("ioManagerWakeup: write"); }
130     }
131 }
132
133 #if defined(THREADED_RTS)
134 void
135 ioManagerDie (void)
136 {
137     int r;
138     // Ask the IO Manager thread to exit
139     if (io_manager_control_fd >= 0) {
140         StgWord8 byte = (StgWord8)IO_MANAGER_DIE;
141         r = write(io_manager_control_fd, &byte, 1);
142         if (r == -1) { sysErrorBelch("ioManagerDie: write"); }
143         io_manager_control_fd = -1;
144         io_manager_wakeup_fd = -1;
145     }
146 }
147
148 Capability *
149 ioManagerStartCap (Capability *cap)
150 {
151     return rts_evalIO(
152         cap,&base_GHCziConcziIO_ensureIOManagerIsRunning_closure,NULL);
153 }
154
155 void
156 ioManagerStart (void)
157 {
158     // Make sure the IO manager thread is running
159     Capability *cap;
160     if (io_manager_control_fd < 0 || io_manager_wakeup_fd < 0) {
161         cap = rts_lock();
162         cap = ioManagerStartCap(cap);
163         rts_unlock(cap);
164     }
165 }
166 #endif
167
168 #if !defined(THREADED_RTS)
169
170 #define N_PENDING_HANDLERS 16
171
172 siginfo_t pending_handler_buf[N_PENDING_HANDLERS];
173 siginfo_t *next_pending_handler = pending_handler_buf;
174
175 #endif /* THREADED_RTS */
176
177 /* -----------------------------------------------------------------------------
178  * Low-level signal handler
179  *
180  * Places the requested handler on a stack of pending handlers to be
181  * started up at the next context switch.
182  * -------------------------------------------------------------------------- */
183
184 static void
185 generic_handler(int sig USED_IF_THREADS,
186                 siginfo_t *info,
187                 void *p STG_UNUSED)
188 {
189 #if defined(THREADED_RTS)
190
191     if (io_manager_control_fd != -1)
192     {
193         StgWord8 buf[sizeof(siginfo_t) + 1];
194         int r;
195
196         buf[0] = sig;
197
198         if (info == NULL) {
199             // info may be NULL on Solaris (see #3790)
200             memset(buf+1, 0, sizeof(siginfo_t));
201         } else {
202             memcpy(buf+1, info, sizeof(siginfo_t));
203         }
204
205         r = write(io_manager_control_fd, buf, sizeof(siginfo_t)+1);
206         if (r == -1 && errno == EAGAIN)
207         {
208             errorBelch("lost signal due to full pipe: %d\n", sig);
209         }
210     }
211     // If the IO manager hasn't told us what the FD of the write end
212     // of its pipe is, there's not much we can do here, so just ignore
213     // the signal..
214
215 #else /* not THREADED_RTS */
216
217     /* Can't call allocate from here.  Probably can't call malloc
218        either.  However, we have to schedule a new thread somehow.
219
220        It's probably ok to request a context switch and allow the
221        scheduler to  start the handler thread, but how do we
222        communicate this to the scheduler?
223
224        We need some kind of locking, but with low overhead (i.e. no
225        blocking signals every time around the scheduler).
226        
227        Signal Handlers are atomic (i.e. they can't be interrupted), and
228        we can make use of this.  We just need to make sure the
229        critical section of the scheduler can't be interrupted - the
230        only way to do this is to block signals.  However, we can lower
231        the overhead by only blocking signals when there are any
232        handlers to run, i.e. the set of pending handlers is
233        non-empty.
234     */
235        
236     /* We use a stack to store the pending signals.  We can't
237        dynamically grow this since we can't allocate any memory from
238        within a signal handler.
239
240        Hence unfortunately we have to bomb out if the buffer
241        overflows.  It might be acceptable to carry on in certain
242        circumstances, depending on the signal.  
243     */
244
245     memcpy(next_pending_handler, info, sizeof(siginfo_t));
246
247     next_pending_handler++;
248
249     // stack full?
250     if (next_pending_handler == &pending_handler_buf[N_PENDING_HANDLERS]) {
251         errorBelch("too many pending signals");
252         stg_exit(EXIT_FAILURE);
253     }
254     
255     contextSwitchCapability(&MainCapability);
256
257 #endif /* THREADED_RTS */
258 }
259
260 /* -----------------------------------------------------------------------------
261  * Blocking/Unblocking of the user signals
262  * -------------------------------------------------------------------------- */
263
264 static sigset_t userSignals;
265 static sigset_t savedSignals;
266
267 void
268 initUserSignals(void)
269 {
270     sigemptyset(&userSignals);
271 #ifndef THREADED_RTS
272     getStablePtr((StgPtr)&base_GHCziConcziSignal_runHandlers_closure);
273     // needed to keep runHandler alive
274 #endif
275 }
276
277 void
278 blockUserSignals(void)
279 {
280     sigprocmask(SIG_BLOCK, &userSignals, &savedSignals);
281 }
282
283 void
284 unblockUserSignals(void)
285 {
286     sigprocmask(SIG_SETMASK, &savedSignals, NULL);
287 }
288
289 rtsBool
290 anyUserHandlers(void)
291 {
292     return n_haskell_handlers != 0;
293 }
294
295 #if !defined(THREADED_RTS)
296 void
297 awaitUserSignals(void)
298 {
299     while (!signals_pending() && sched_state == SCHED_RUNNING) {
300         pause();
301     }
302 }
303 #endif
304
305 /* -----------------------------------------------------------------------------
306  * Install a Haskell signal handler.
307  *
308  * We should really do this in Haskell in GHC.Conc, and share the
309  * signal_handlers array with the one there.
310  *
311  * -------------------------------------------------------------------------- */
312
313 int
314 stg_sig_install(int sig, int spi, void *mask)
315 {
316     sigset_t signals, osignals;
317     struct sigaction action;
318     StgInt previous_spi;
319
320     // Block the signal until we figure out what to do
321     // Count on this to fail if the signal number is invalid
322     if (sig < 0 || sigemptyset(&signals) ||
323         sigaddset(&signals, sig) || sigprocmask(SIG_BLOCK, &signals, &osignals)) {
324         return STG_SIG_ERR;
325     }
326     
327     more_handlers(sig);
328
329     previous_spi = signal_handlers[sig];
330
331     action.sa_flags = 0;
332     
333     switch(spi) {
334     case STG_SIG_IGN:
335         action.sa_handler = SIG_IGN;
336         break;
337
338     case STG_SIG_DFL:
339         action.sa_handler = SIG_DFL;
340         break;
341
342     case STG_SIG_RST:
343         action.sa_flags |= SA_RESETHAND;
344         /* fall through */
345     case STG_SIG_HAN:
346         action.sa_sigaction = generic_handler;
347         action.sa_flags |= SA_SIGINFO;
348         break;
349
350     default:
351         barf("stg_sig_install: bad spi");
352     }
353
354     if (mask != NULL)
355         action.sa_mask = *(sigset_t *)mask;
356     else
357         sigemptyset(&action.sa_mask);
358
359     action.sa_flags |= sig == SIGCHLD && nocldstop ? SA_NOCLDSTOP : 0;
360
361     if (sigaction(sig, &action, NULL))
362     {
363         errorBelch("sigaction");
364         return STG_SIG_ERR;
365     }
366
367     signal_handlers[sig] = spi;
368
369     switch(spi) {
370     case STG_SIG_RST:
371     case STG_SIG_HAN:
372         sigaddset(&userSignals, sig);
373         if (previous_spi != STG_SIG_HAN && previous_spi != STG_SIG_RST) {
374             n_haskell_handlers++;
375         }
376         break;
377
378     default:
379         sigdelset(&userSignals, sig);
380         if (previous_spi == STG_SIG_HAN || previous_spi == STG_SIG_RST) {
381             n_haskell_handlers--;
382         }
383         break;
384     }
385
386     if (sigprocmask(SIG_SETMASK, &osignals, NULL))
387     {
388         errorBelch("sigprocmask");
389         return STG_SIG_ERR;
390     }
391
392     return previous_spi;
393 }
394
395 /* -----------------------------------------------------------------------------
396  * Creating new threads for signal handlers.
397  * -------------------------------------------------------------------------- */
398
399 #if !defined(THREADED_RTS)
400 void
401 startSignalHandlers(Capability *cap)
402 {
403   siginfo_t *info;
404   int sig;
405
406   blockUserSignals();
407   
408   while (next_pending_handler != pending_handler_buf) {
409
410     next_pending_handler--;
411
412     sig = next_pending_handler->si_signo;
413     if (signal_handlers[sig] == STG_SIG_DFL) {
414         continue; // handler has been changed.
415     }
416
417     info = stgMallocBytes(sizeof(siginfo_t), "startSignalHandlers"); 
418            // freed by runHandler
419     memcpy(info, next_pending_handler, sizeof(siginfo_t));
420
421     scheduleThread (cap,
422         createIOThread(cap,
423                        RtsFlags.GcFlags.initialStkSize, 
424                        rts_apply(cap,
425                                  rts_apply(cap,
426                                            &base_GHCziConcziSignal_runHandlers_closure,
427                                            rts_mkPtr(cap, info)),
428                                  rts_mkInt(cap, info->si_signo))));
429   }
430
431   unblockUserSignals();
432 }
433 #endif
434
435 /* ----------------------------------------------------------------------------
436  * Mark signal handlers during GC.
437  * -------------------------------------------------------------------------- */
438
439 void
440 markSignalHandlers (evac_fn evac STG_UNUSED, void *user STG_UNUSED)
441 {
442     // nothing to do
443 }
444
445 #else /* !RTS_USER_SIGNALS */
446 StgInt 
447 stg_sig_install(StgInt sig STG_UNUSED,
448                 StgInt spi STG_UNUSED,
449                 void* mask STG_UNUSED)
450 {
451   //barf("User signals not supported");
452   return STG_SIG_DFL;
453 }
454
455 #endif
456
457 #if defined(RTS_USER_SIGNALS)
458 /* -----------------------------------------------------------------------------
459  * SIGINT handler.
460  *
461  * We like to shutdown nicely after receiving a SIGINT, write out the
462  * stats, write profiling info, close open files and flush buffers etc.
463  * -------------------------------------------------------------------------- */
464 static void
465 shutdown_handler(int sig STG_UNUSED)
466 {
467     // If we're already trying to interrupt the RTS, terminate with
468     // extreme prejudice.  So the first ^C tries to exit the program
469     // cleanly, and the second one just kills it.
470     if (sched_state >= SCHED_INTERRUPTING) {
471         stg_exit(EXIT_INTERRUPTED);
472     } else {
473         interruptStgRts();
474     }
475 }
476
477 /* -----------------------------------------------------------------------------
478  * An empty signal handler, currently used for SIGPIPE
479  * -------------------------------------------------------------------------- */
480 static void
481 empty_handler (int sig STG_UNUSED)
482 {
483     // nothing
484 }
485
486 /* -----------------------------------------------------------------------------
487    SIGTSTP handling
488
489    When a process is suspeended with ^Z and resumed again, the shell
490    makes no attempt to save and restore the terminal settings.  So on
491    resume, any terminal setting modificaions we made (e.g. turning off
492    ICANON due to hSetBuffering NoBuffering) may well be lost.  Hence,
493    we arrange to save and restore the terminal settings ourselves.
494
495    The trick we use is:
496      - catch SIGTSTP
497      - in the handler,  kill(getpid(),SIGTSTP)
498      - when this returns, restore the TTY settings
499    This means we don't have to catch SIGCONT too.
500
501    -------------------------------------------------------------------------- */
502
503 static void sigtstp_handler(int sig);
504 static void set_sigtstp_action (rtsBool handle);
505
506 static void
507 sigtstp_handler (int sig)
508 {
509     int fd;
510     struct termios ts[3];
511
512     // save the current TTY state for TTYs we modified
513     for (fd = 0; fd <= 2; fd++) {
514         if (__hscore_get_saved_termios(fd) != NULL) {
515             tcgetattr(fd,&ts[fd]);
516         }
517     }
518
519     // de-install the SIGTSTP handler
520     set_sigtstp_action(rtsFalse);
521
522     // really stop the process now
523     {
524         sigset_t mask;
525         sigemptyset(&mask);
526         sigaddset(&mask, sig);
527         sigprocmask(SIG_UNBLOCK, &mask, NULL);
528         kill(getpid(), sig);
529     }
530
531     // on return, restore the TTY state
532     for (fd = 0; fd <= 2; fd++) {
533         if (__hscore_get_saved_termios(fd) != NULL) {
534             tcsetattr(0,TCSANOW,&ts[fd]);
535         }
536     }
537
538     set_sigtstp_action(rtsTrue);
539 }
540
541 static void
542 set_sigtstp_action (rtsBool handle)
543 {
544     struct sigaction sa;
545     if (handle) {
546         sa.sa_handler = sigtstp_handler;
547     } else {
548         sa.sa_handler = SIG_DFL;
549     }
550     sa.sa_flags = 0;
551     sigemptyset(&sa.sa_mask);
552     sigaction(SIGTSTP, &sa, NULL);
553 }
554
555 /* -----------------------------------------------------------------------------
556  * Install default signal handlers.
557  *
558  * The RTS installs a default signal handler for catching
559  * SIGINT, so that we can perform an orderly shutdown.
560  *
561  * Haskell code may install their own SIGINT handler, which is
562  * fine, provided they're so kind as to put back the old one
563  * when they de-install.
564  *
565  * In addition to handling SIGINT, the RTS also handles SIGFPE
566  * by ignoring it.  Apparently IEEE requires floating-point
567  * exceptions to be ignored by default, but alpha-dec-osf3
568  * doesn't seem to do so.
569  * -------------------------------------------------------------------------- */
570 void
571 initDefaultHandlers(void)
572 {
573     struct sigaction action,oact;
574
575     // install the SIGINT handler
576     action.sa_handler = shutdown_handler;
577     sigemptyset(&action.sa_mask);
578     action.sa_flags = 0;
579     if (sigaction(SIGINT, &action, &oact) != 0) {
580         sysErrorBelch("warning: failed to install SIGINT handler");
581     }
582
583 #if defined(HAVE_SIGINTERRUPT)
584     siginterrupt(SIGINT, 1);    // isn't this the default? --SDM
585 #endif
586
587     // install the SIGFPE handler
588
589     // In addition to handling SIGINT, also handle SIGFPE by ignoring it.
590     // Apparently IEEE requires floating-point exceptions to be ignored by
591     // default, but alpha-dec-osf3 doesn't seem to do so.
592
593     // Commented out by SDM 2/7/2002: this causes an infinite loop on
594     // some architectures when an integer division by zero occurs: we
595     // don't recover from the floating point exception, and the
596     // program just generates another one immediately.
597 #if 0
598     action.sa_handler = SIG_IGN;
599     sigemptyset(&action.sa_mask);
600     action.sa_flags = 0;
601     if (sigaction(SIGFPE, &action, &oact) != 0) {
602         sysErrorBelch("warning: failed to install SIGFPE handler");
603     }
604 #endif
605
606 #ifdef alpha_HOST_ARCH
607     ieee_set_fp_control(0);
608 #endif
609
610     // ignore SIGPIPE; see #1619
611     // actually, we use an empty signal handler rather than SIG_IGN,
612     // so that SIGPIPE gets reset to its default behaviour on exec.
613     action.sa_handler = empty_handler;
614     sigemptyset(&action.sa_mask);
615     action.sa_flags = 0;
616     if (sigaction(SIGPIPE, &action, &oact) != 0) {
617         sysErrorBelch("warning: failed to install SIGPIPE handler");
618     }
619
620     set_sigtstp_action(rtsTrue);
621 }
622
623 void
624 resetDefaultHandlers(void)
625 {
626     struct sigaction action;
627
628     action.sa_handler = SIG_DFL;
629     sigemptyset(&action.sa_mask);
630     action.sa_flags = 0;
631
632     // restore SIGINT
633     if (sigaction(SIGINT, &action, NULL) != 0) {
634         sysErrorBelch("warning: failed to uninstall SIGINT handler");
635     }
636     // restore SIGPIPE
637     if (sigaction(SIGPIPE, &action, NULL) != 0) {
638         sysErrorBelch("warning: failed to uninstall SIGPIPE handler");
639     }
640
641     set_sigtstp_action(rtsFalse);
642 }
643
644 void
645 freeSignalHandlers(void) {
646     if (signal_handlers != NULL) {
647         stgFree(signal_handlers);
648     }
649 }
650
651 #endif /* RTS_USER_SIGNALS */