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