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