1 /* -----------------------------------------------------------------------------
3 * (c) The GHC Team, 1998-2005
5 * Signal processing / handling.
7 * ---------------------------------------------------------------------------*/
9 /* This is non-Posix-compliant.
10 #include "PosixSource.h"
16 #include "RtsSignals.h"
17 #include "posix/Signals.h"
23 #ifdef alpha_HOST_ARCH
24 # if defined(linux_HOST_OS)
27 # include <machine/fpu.h>
41 /* This curious flag is provided for the benefit of the Haskell binding
42 * to POSIX.1 to control whether or not to include SA_NOCLDSTOP when
43 * installing a SIGCHLD handler.
47 /* -----------------------------------------------------------------------------
48 * The table of signal handlers
49 * -------------------------------------------------------------------------- */
51 #if defined(RTS_USER_SIGNALS)
53 /* SUP: The type of handlers is a little bit, well, doubtful... */
54 StgInt *signal_handlers = NULL; /* Dynamically grown array of signal handlers */
55 static StgInt nHandlers = 0; /* Size of handlers array */
57 static nat n_haskell_handlers = 0;
59 /* -----------------------------------------------------------------------------
60 * Allocate/resize the table of signal handlers.
61 * -------------------------------------------------------------------------- */
71 if (signal_handlers == NULL)
72 signal_handlers = (StgInt *)stgMallocBytes((sig + 1) * sizeof(StgInt), "more_handlers");
74 signal_handlers = (StgInt *)stgReallocBytes(signal_handlers, (sig + 1) * sizeof(StgInt), "more_handlers");
76 for(i = nHandlers; i <= sig; i++)
77 // Fill in the new slots with default actions
78 signal_handlers[i] = STG_SIG_DFL;
83 /* -----------------------------------------------------------------------------
86 * The mechanism for starting handlers differs between the threaded
87 * (THREADED_RTS) and non-threaded versions of the RTS.
89 * When the RTS is single-threaded, we just write the pending signal
90 * handlers into a buffer, and start a thread for each one in the
93 * When THREADED_RTS, the problem is that signals might be
94 * delivered to multiple threads, so we would need to synchronise
95 * access to pending_handler_buf somehow. Using thread
96 * synchronisation from a signal handler isn't possible in general
97 * (some OSs support it, eg. MacOS X, but not all). So instead:
99 * - the signal handler writes the signal number into the pipe
100 * managed by the IO manager thread (see GHC.Conc).
101 * - the IO manager picks up the signal number and calls
102 * startSignalHandler() to start the thread.
104 * This also has the nice property that we don't need to arrange to
105 * wake up a worker task to start the signal handler: the IO manager
106 * wakes up when we write into the pipe.
108 * -------------------------------------------------------------------------- */
110 // Here's the pipe into which we will send our signals
111 static int io_manager_pipe = -1;
113 #define IO_MANAGER_WAKEUP 0xff
114 #define IO_MANAGER_DIE 0xfe
117 setIOManagerPipe (int fd)
119 // only called when THREADED_RTS, but unconditionally
120 // compiled here because GHC.Conc depends on it.
121 io_manager_pipe = fd;
124 #if defined(THREADED_RTS)
126 ioManagerWakeup (void)
128 // Wake up the IO Manager thread by sending a byte down its pipe
129 if (io_manager_pipe >= 0) {
130 StgWord8 byte = (StgWord8)IO_MANAGER_WAKEUP;
131 write(io_manager_pipe, &byte, 1);
138 // Ask the IO Manager thread to exit
139 if (io_manager_pipe >= 0) {
140 StgWord8 byte = (StgWord8)IO_MANAGER_DIE;
141 write(io_manager_pipe, &byte, 1);
146 ioManagerStart (void)
148 // Make sure the IO manager thread is running
150 if (io_manager_pipe < 0) {
152 rts_evalIO(cap,&base_GHCziConc_ensureIOManagerIsRunning_closure,NULL);
158 #if !defined(THREADED_RTS)
160 #define N_PENDING_HANDLERS 16
162 StgPtr pending_handler_buf[N_PENDING_HANDLERS];
163 StgPtr *next_pending_handler = pending_handler_buf;
165 #endif /* THREADED_RTS */
167 /* -----------------------------------------------------------------------------
170 * It seems that shells tend to put stdin back into blocking mode
171 * following a suspend/resume of the process. Here we arrange to put
172 * it back into non-blocking mode. We don't do anything to
173 * stdout/stderr because these handles don't get put into non-blocking
174 * mode at all - see the comments on stdout/stderr in PrelHandle.hsc.
175 * -------------------------------------------------------------------------- */
178 cont_handler(int sig STG_UNUSED)
183 /* -----------------------------------------------------------------------------
184 * Low-level signal handler
186 * Places the requested handler on a stack of pending handlers to be
187 * started up at the next context switch.
188 * -------------------------------------------------------------------------- */
191 generic_handler(int sig)
195 #if defined(THREADED_RTS)
197 if (io_manager_pipe != -1)
199 // Write the signal number into the pipe as a single byte. We
200 // hope that signals fit into a byte...
201 StgWord8 csig = (StgWord8)sig;
202 write(io_manager_pipe, &csig, 1);
204 // If the IO manager hasn't told us what the FD of the write end
205 // of its pipe is, there's not much we can do here, so just ignore
208 #else /* not THREADED_RTS */
210 /* Can't call allocate from here. Probably can't call malloc
211 either. However, we have to schedule a new thread somehow.
213 It's probably ok to request a context switch and allow the
214 scheduler to start the handler thread, but how do we
215 communicate this to the scheduler?
217 We need some kind of locking, but with low overhead (i.e. no
218 blocking signals every time around the scheduler).
220 Signal Handlers are atomic (i.e. they can't be interrupted), and
221 we can make use of this. We just need to make sure the
222 critical section of the scheduler can't be interrupted - the
223 only way to do this is to block signals. However, we can lower
224 the overhead by only blocking signals when there are any
225 handlers to run, i.e. the set of pending handlers is
229 /* We use a stack to store the pending signals. We can't
230 dynamically grow this since we can't allocate any memory from
231 within a signal handler.
233 Hence unfortunately we have to bomb out if the buffer
234 overflows. It might be acceptable to carry on in certain
235 circumstances, depending on the signal.
238 *next_pending_handler++ = deRefStablePtr((StgStablePtr)signal_handlers[sig]);
241 if (next_pending_handler == &pending_handler_buf[N_PENDING_HANDLERS]) {
242 errorBelch("too many pending signals");
243 stg_exit(EXIT_FAILURE);
246 #endif /* THREADED_RTS */
248 // re-establish the signal handler, and carry on
249 sigemptyset(&signals);
250 sigaddset(&signals, sig);
251 sigprocmask(SIG_UNBLOCK, &signals, NULL);
253 // *always* do the SIGCONT handler, even if the user overrides it.
254 if (sig == SIGCONT) {
261 /* -----------------------------------------------------------------------------
262 * Blocking/Unblocking of the user signals
263 * -------------------------------------------------------------------------- */
265 static sigset_t userSignals;
266 static sigset_t savedSignals;
269 initUserSignals(void)
271 sigemptyset(&userSignals);
275 blockUserSignals(void)
277 sigprocmask(SIG_BLOCK, &userSignals, &savedSignals);
281 unblockUserSignals(void)
283 sigprocmask(SIG_SETMASK, &savedSignals, NULL);
287 anyUserHandlers(void)
289 return n_haskell_handlers != 0;
292 #if !defined(THREADED_RTS)
294 awaitUserSignals(void)
296 while (!signals_pending() && sched_state == SCHED_RUNNING) {
302 /* -----------------------------------------------------------------------------
303 * Install a Haskell signal handler.
304 * -------------------------------------------------------------------------- */
307 stg_sig_install(int sig, int spi, StgStablePtr *handler, void *mask)
309 sigset_t signals, osignals;
310 struct sigaction action;
313 // Block the signal until we figure out what to do
314 // Count on this to fail if the signal number is invalid
315 if (sig < 0 || sigemptyset(&signals) ||
316 sigaddset(&signals, sig) || sigprocmask(SIG_BLOCK, &signals, &osignals)) {
322 previous_spi = signal_handlers[sig];
328 signal_handlers[sig] = STG_SIG_IGN;
329 sigdelset(&userSignals, sig);
330 action.sa_handler = SIG_IGN;
334 signal_handlers[sig] = STG_SIG_DFL;
335 sigdelset(&userSignals, sig);
336 action.sa_handler = SIG_DFL;
341 signal_handlers[sig] = (StgInt)*handler;
342 sigaddset(&userSignals, sig);
343 action.sa_handler = generic_handler;
344 if (spi == STG_SIG_RST) {
345 action.sa_flags = SA_RESETHAND;
347 n_haskell_handlers++;
351 barf("stg_sig_install: bad spi");
355 action.sa_mask = *(sigset_t *)mask;
357 sigemptyset(&action.sa_mask);
359 action.sa_flags |= sig == SIGCHLD && nocldstop ? SA_NOCLDSTOP : 0;
361 if (sigaction(sig, &action, NULL) ||
362 sigprocmask(SIG_SETMASK, &osignals, NULL))
364 // need to return an error code, so avoid a stable pointer leak
365 // by freeing the previous handler if there was one.
366 if (previous_spi >= 0) {
367 freeStablePtr(stgCast(StgStablePtr,signal_handlers[sig]));
368 n_haskell_handlers--;
373 if (previous_spi == STG_SIG_DFL || previous_spi == STG_SIG_IGN
374 || previous_spi == STG_SIG_ERR) {
377 *handler = (StgStablePtr)previous_spi;
382 /* -----------------------------------------------------------------------------
383 * Creating new threads for signal handlers.
384 * -------------------------------------------------------------------------- */
386 #if !defined(THREADED_RTS)
388 startSignalHandlers(Capability *cap)
392 while (next_pending_handler != pending_handler_buf) {
394 next_pending_handler--;
398 RtsFlags.GcFlags.initialStkSize,
399 (StgClosure *) *next_pending_handler));
402 unblockUserSignals();
406 /* ----------------------------------------------------------------------------
407 * Mark signal handlers during GC.
409 * We do this rather than trying to start all the signal handlers
410 * prior to GC, because that requires extra heap for the new threads.
411 * Signals must be blocked (see blockUserSignals() above) during GC to
412 * avoid race conditions.
413 * -------------------------------------------------------------------------- */
415 #if !defined(THREADED_RTS)
417 markSignalHandlers (evac_fn evac)
421 p = next_pending_handler;
422 while (p != pending_handler_buf) {
424 evac((StgClosure **)p);
429 markSignalHandlers (evac_fn evac STG_UNUSED)
434 #else /* !RTS_USER_SIGNALS */
436 stg_sig_install(StgInt sig STG_UNUSED,
437 StgInt spi STG_UNUSED,
438 StgStablePtr* handler STG_UNUSED,
439 void* mask STG_UNUSED)
441 //barf("User signals not supported");
447 #if defined(RTS_USER_SIGNALS)
448 /* -----------------------------------------------------------------------------
451 * We like to shutdown nicely after receiving a SIGINT, write out the
452 * stats, write profiling info, close open files and flush buffers etc.
453 * -------------------------------------------------------------------------- */
455 pthread_t startup_guy;
459 shutdown_handler(int sig STG_UNUSED)
462 // if I'm a worker thread, send this signal to the guy who
463 // originally called startupHaskell(). Since we're handling
464 // the signal, it won't be a "send to all threads" type of signal
465 // (according to the POSIX threads spec).
466 if (pthread_self() != startup_guy) {
467 pthread_kill(startup_guy, sig);
472 // If we're already trying to interrupt the RTS, terminate with
473 // extreme prejudice. So the first ^C tries to exit the program
474 // cleanly, and the second one just kills it.
475 if (sched_state >= SCHED_INTERRUPTING) {
476 stg_exit(EXIT_INTERRUPTED);
482 /* -----------------------------------------------------------------------------
483 * Install default signal handlers.
485 * The RTS installs a default signal handler for catching
486 * SIGINT, so that we can perform an orderly shutdown.
488 * Haskell code may install their own SIGINT handler, which is
489 * fine, provided they're so kind as to put back the old one
490 * when they de-install.
492 * In addition to handling SIGINT, the RTS also handles SIGFPE
493 * by ignoring it. Apparently IEEE requires floating-point
494 * exceptions to be ignored by default, but alpha-dec-osf3
495 * doesn't seem to do so.
496 * -------------------------------------------------------------------------- */
498 initDefaultHandlers()
500 struct sigaction action,oact;
503 startup_guy = pthread_self();
506 // install the SIGINT handler
507 action.sa_handler = shutdown_handler;
508 sigemptyset(&action.sa_mask);
510 if (sigaction(SIGINT, &action, &oact) != 0) {
511 sysErrorBelch("warning: failed to install SIGINT handler");
514 #if defined(HAVE_SIGINTERRUPT)
515 siginterrupt(SIGINT, 1); // isn't this the default? --SDM
518 // install the SIGCONT handler
519 action.sa_handler = cont_handler;
520 sigemptyset(&action.sa_mask);
522 if (sigaction(SIGCONT, &action, &oact) != 0) {
523 sysErrorBelch("warning: failed to install SIGCONT handler");
526 // install the SIGFPE handler
528 // In addition to handling SIGINT, also handle SIGFPE by ignoring it.
529 // Apparently IEEE requires floating-point exceptions to be ignored by
530 // default, but alpha-dec-osf3 doesn't seem to do so.
532 // Commented out by SDM 2/7/2002: this causes an infinite loop on
533 // some architectures when an integer division by zero occurs: we
534 // don't recover from the floating point exception, and the
535 // program just generates another one immediately.
537 action.sa_handler = SIG_IGN;
538 sigemptyset(&action.sa_mask);
540 if (sigaction(SIGFPE, &action, &oact) != 0) {
541 sysErrorBelch("warning: failed to install SIGFPE handler");
545 #ifdef alpha_HOST_ARCH
546 ieee_set_fp_control(0);
550 #endif /* RTS_USER_SIGNALS */