1 /* -----------------------------------------------------------------------------
2 * $Id: Signals.c,v 1.37 2003/04/01 15:05:22 sof Exp $
4 * (c) The GHC Team, 1998-1999
6 * Signal processing / handling.
8 * ---------------------------------------------------------------------------*/
10 /* This is non-Posix-compliant.
11 #include "PosixSource.h"
19 #include "StablePriv.h"
21 #ifdef alpha_TARGET_ARCH
22 # include <machine/fpu.h>
35 /* This curious flag is provided for the benefit of the Haskell binding
36 * to POSIX.1 to control whether or not to include SA_NOCLDSTOP when
37 * installing a SIGCHLD handler.
42 #if defined(RTS_USER_SIGNALS)
44 /* SUP: The type of handlers is a little bit, well, doubtful... */
45 static StgInt *handlers = NULL; /* Dynamically grown array of signal handlers */
46 static StgInt nHandlers = 0; /* Size of handlers array */
48 static nat n_haskell_handlers = 0;
50 #define N_PENDING_HANDLERS 16
52 StgPtr pending_handler_buf[N_PENDING_HANDLERS];
53 StgPtr *next_pending_handler = pending_handler_buf;
55 #ifdef RTS_SUPPORTS_THREADS
56 pthread_t signalHandlingThread;
59 // Handle all signals in the current thread.
60 // Called from Capability.c whenever the main capability is granted to a thread
61 // and in installDefaultHandlers
63 handleSignalsInThisThread()
65 #ifdef RTS_SUPPORTS_THREADS
66 signalHandlingThread = pthread_self();
71 /* -----------------------------------------------------------------------------
72 * Allocate/resize the table of signal handlers.
73 * -------------------------------------------------------------------------- */
84 handlers = (StgInt *)stgMallocBytes((sig + 1) * sizeof(StgInt), "more_handlers");
86 handlers = (StgInt *)stgReallocBytes(handlers, (sig + 1) * sizeof(StgInt), "more_handlers");
88 for(i = nHandlers; i <= sig; i++)
89 // Fill in the new slots with default actions
90 handlers[i] = STG_SIG_DFL;
95 /* -----------------------------------------------------------------------------
98 * It seems that shells tend to put stdin back into blocking mode
99 * following a suspend/resume of the process. Here we arrange to put
100 * it back into non-blocking mode. We don't do anything to
101 * stdout/stderr because these handles don't get put into non-blocking
102 * mode at all - see the comments on stdout/stderr in PrelHandle.hsc.
103 * -------------------------------------------------------------------------- */
106 cont_handler(int sig STG_UNUSED)
111 /* -----------------------------------------------------------------------------
112 * Low-level signal handler
114 * Places the requested handler on a stack of pending handlers to be
115 * started up at the next context switch.
116 * -------------------------------------------------------------------------- */
119 generic_handler(int sig)
123 #if defined(THREADED_RTS)
124 // Make the thread that currently holds the main capability
125 // handle the signal.
126 // This makes sure that awaitEvent() is interrupted
127 // and it (hopefully) prevents race conditions
128 // (signal handlers are not atomic with respect to other threads)
130 if(pthread_self() != signalHandlingThread) {
131 pthread_kill(signalHandlingThread, sig);
136 /* Can't call allocate from here. Probably can't call malloc
137 either. However, we have to schedule a new thread somehow.
139 It's probably ok to request a context switch and allow the
140 scheduler to start the handler thread, but how do we
141 communicate this to the scheduler?
143 We need some kind of locking, but with low overhead (i.e. no
144 blocking signals every time around the scheduler).
146 Signal Handlers are atomic (i.e. they can't be interrupted), and
147 we can make use of this. We just need to make sure the
148 critical section of the scheduler can't be interrupted - the
149 only way to do this is to block signals. However, we can lower
150 the overhead by only blocking signals when there are any
151 handlers to run, i.e. the set of pending handlers is
155 /* We use a stack to store the pending signals. We can't
156 dynamically grow this since we can't allocate any memory from
157 within a signal handler.
159 Hence unfortunately we have to bomb out if the buffer
160 overflows. It might be acceptable to carry on in certain
161 circumstances, depending on the signal.
164 *next_pending_handler++ = deRefStablePtr((StgStablePtr)handlers[sig]);
167 if (next_pending_handler == &pending_handler_buf[N_PENDING_HANDLERS]) {
168 prog_belch("too many pending signals");
169 stg_exit(EXIT_FAILURE);
172 // re-establish the signal handler, and carry on
173 sigemptyset(&signals);
174 sigaddset(&signals, sig);
175 sigprocmask(SIG_UNBLOCK, &signals, NULL);
177 // *always* do the SIGCONT handler, even if the user overrides it.
178 if (sig == SIGCONT) {
185 /* -----------------------------------------------------------------------------
186 * Blocking/Unblocking of the user signals
187 * -------------------------------------------------------------------------- */
189 static sigset_t userSignals;
190 static sigset_t savedSignals;
193 initUserSignals(void)
195 sigemptyset(&userSignals);
199 blockUserSignals(void)
201 sigprocmask(SIG_BLOCK, &userSignals, &savedSignals);
205 unblockUserSignals(void)
207 sigprocmask(SIG_SETMASK, &savedSignals, NULL);
211 anyUserHandlers(void)
213 return n_haskell_handlers != 0;
217 awaitUserSignals(void)
219 while (!signals_pending() && !interrupted) {
224 /* -----------------------------------------------------------------------------
225 * Install a Haskell signal handler.
226 * -------------------------------------------------------------------------- */
229 stg_sig_install(int sig, int spi, StgStablePtr *handler, void *mask)
231 sigset_t signals, osignals;
232 struct sigaction action;
235 // Block the signal until we figure out what to do
236 // Count on this to fail if the signal number is invalid
237 if (sig < 0 || sigemptyset(&signals) ||
238 sigaddset(&signals, sig) || sigprocmask(SIG_BLOCK, &signals, &osignals)) {
244 previous_spi = handlers[sig];
250 handlers[sig] = STG_SIG_IGN;
251 sigdelset(&userSignals, sig);
252 action.sa_handler = SIG_IGN;
256 handlers[sig] = STG_SIG_DFL;
257 sigdelset(&userSignals, sig);
258 action.sa_handler = SIG_DFL;
263 handlers[sig] = (StgInt)*handler;
264 sigaddset(&userSignals, sig);
265 action.sa_handler = generic_handler;
266 if (spi == STG_SIG_RST) {
267 action.sa_flags = SA_RESETHAND;
269 n_haskell_handlers++;
273 barf("stg_sig_install: bad spi");
277 action.sa_mask = *(sigset_t *)mask;
279 sigemptyset(&action.sa_mask);
281 action.sa_flags |= sig == SIGCHLD && nocldstop ? SA_NOCLDSTOP : 0;
283 if (sigaction(sig, &action, NULL) ||
284 sigprocmask(SIG_SETMASK, &osignals, NULL))
286 // need to return an error code, so avoid a stable pointer leak
287 // by freeing the previous handler if there was one.
288 if (previous_spi >= 0) {
289 freeStablePtr(stgCast(StgStablePtr,handlers[sig]));
290 n_haskell_handlers--;
295 if (previous_spi == STG_SIG_DFL || previous_spi == STG_SIG_IGN
296 || previous_spi == STG_SIG_ERR) {
299 *handler = (StgStablePtr)previous_spi;
304 /* -----------------------------------------------------------------------------
305 * Creating new threads for the pending signal handlers.
306 * -------------------------------------------------------------------------- */
308 startSignalHandlers(void)
312 while (next_pending_handler != pending_handler_buf) {
314 next_pending_handler--;
317 createIOThread(RtsFlags.GcFlags.initialStkSize,
318 (StgClosure *) *next_pending_handler));
321 unblockUserSignals();
324 /* ----------------------------------------------------------------------------
325 * Mark signal handlers during GC.
327 * We do this rather than trying to start all the signal handlers
328 * prior to GC, because that requires extra heap for the new threads.
329 * Signals must be blocked (see blockUserSignals() above) during GC to
330 * avoid race conditions.
331 * -------------------------------------------------------------------------- */
334 markSignalHandlers (evac_fn evac)
338 p = next_pending_handler;
339 while (p != pending_handler_buf) {
341 evac((StgClosure **)p);
345 #else /* !RTS_USER_SIGNALS */
347 stg_sig_install(StgInt sig STG_UNUSED,
348 StgInt spi STG_UNUSED,
349 StgStablePtr* handler STG_UNUSED,
350 void* mask STG_UNUSED)
352 //barf("User signals not supported");
358 #if defined(RTS_USER_SIGNALS)
359 /* -----------------------------------------------------------------------------
362 * We like to shutdown nicely after receiving a SIGINT, write out the
363 * stats, write profiling info, close open files and flush buffers etc.
364 * -------------------------------------------------------------------------- */
366 pthread_t startup_guy;
370 shutdown_handler(int sig STG_UNUSED)
373 // if I'm a worker thread, send this signal to the guy who
374 // originally called startupHaskell(). Since we're handling
375 // the signal, it won't be a "send to all threads" type of signal
376 // (according to the POSIX threads spec).
377 if (pthread_self() != startup_guy) {
378 pthread_kill(startup_guy, sig);
381 // ToDo: The code for the threaded RTS below does something very
382 // similar. Maybe the SMP special case is not needed
383 // -- Wolfgang Thaller
384 #elif defined(THREADED_RTS)
385 // Make the thread that currently holds the main capability
386 // handle the signal.
387 // This makes sure that awaitEvent() is interrupted
388 if(pthread_self() != signalHandlingThread) {
389 pthread_kill(signalHandlingThread, sig);
394 // If we're already trying to interrupt the RTS, terminate with
395 // extreme prejudice. So the first ^C tries to exit the program
396 // cleanly, and the second one just kills it.
398 stg_exit(EXIT_INTERRUPTED);
404 /* -----------------------------------------------------------------------------
405 * Install default signal handlers.
407 * The RTS installs a default signal handler for catching
408 * SIGINT, so that we can perform an orderly shutdown.
410 * Haskell code may install their own SIGINT handler, which is
411 * fine, provided they're so kind as to put back the old one
412 * when they de-install.
414 * In addition to handling SIGINT, the RTS also handles SIGFPE
415 * by ignoring it. Apparently IEEE requires floating-point
416 * exceptions to be ignored by default, but alpha-dec-osf3
417 * doesn't seem to do so.
418 * -------------------------------------------------------------------------- */
420 initDefaultHandlers()
422 struct sigaction action,oact;
425 startup_guy = pthread_self();
427 #ifdef RTS_SUPPORTS_THREADS
428 handleSignalsInThisThread();
431 // install the SIGINT handler
432 action.sa_handler = shutdown_handler;
433 sigemptyset(&action.sa_mask);
435 if (sigaction(SIGINT, &action, &oact) != 0) {
436 prog_belch("warning: failed to install SIGINT handler");
439 #ifndef cygwin32_TARGET_OS
440 siginterrupt(SIGINT, 1); // isn't this the default? --SDM
443 // install the SIGCONT handler
444 action.sa_handler = cont_handler;
445 sigemptyset(&action.sa_mask);
447 if (sigaction(SIGCONT, &action, &oact) != 0) {
448 prog_belch("warning: failed to install SIGCONT handler");
451 // install the SIGFPE handler
453 // In addition to handling SIGINT, also handle SIGFPE by ignoring it.
454 // Apparently IEEE requires floating-point exceptions to be ignored by
455 // default, but alpha-dec-osf3 doesn't seem to do so.
457 // Commented out by SDM 2/7/2002: this causes an infinite loop on
458 // some architectures when an integer division by zero occurs: we
459 // don't recover from the floating point exception, and the
460 // program just generates another one immediately.
462 action.sa_handler = SIG_IGN;
463 sigemptyset(&action.sa_mask);
465 if (sigaction(SIGFPE, &action, &oact) != 0) {
466 prog_belch("warning: failed to install SIGFPE handler");
470 #ifdef alpha_TARGET_ARCH
471 ieee_set_fp_control(0);
475 #endif /* RTS_USER_SIGNALS */