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