#include "RtsUtils.h"
#include "RtsFlags.h"
#include "Prelude.h"
+#include "ThrIOManager.h"
#ifdef alpha_HOST_ARCH
# if defined(linux_HOST_OS)
* to POSIX.1 to control whether or not to include SA_NOCLDSTOP when
* installing a SIGCHLD handler.
*/
-StgInt nocldstop = 0;
+HsInt nocldstop = 0;
/* -----------------------------------------------------------------------------
* The table of signal handlers
Capability *cap;
if (io_manager_pipe < 0) {
cap = rts_lock();
- rts_evalIO(cap,&base_GHCziConc_ensureIOManagerIsRunning_closure,NULL);
+ cap = rts_evalIO(cap,&base_GHCziConc_ensureIOManagerIsRunning_closure,NULL);
rts_unlock(cap);
}
}
#endif /* THREADED_RTS */
/* -----------------------------------------------------------------------------
- * SIGCONT handler
- *
- * It seems that shells tend to put stdin back into blocking mode
- * following a suspend/resume of the process. Here we arrange to put
- * it back into non-blocking mode. We don't do anything to
- * stdout/stderr because these handles don't get put into non-blocking
- * mode at all - see the comments on stdout/stderr in PrelHandle.hsc.
- * -------------------------------------------------------------------------- */
-
-static void
-cont_handler(int sig STG_UNUSED)
-{
- setNonBlockingFd(0);
-}
-
-/* -----------------------------------------------------------------------------
* Low-level signal handler
*
* Places the requested handler on a stack of pending handlers to be
stg_exit(EXIT_FAILURE);
}
+ MainCapability.context_switch = 1;
+
#endif /* THREADED_RTS */
// re-establish the signal handler, and carry on
sigemptyset(&signals);
sigaddset(&signals, sig);
sigprocmask(SIG_UNBLOCK, &signals, NULL);
-
- // *always* do the SIGCONT handler, even if the user overrides it.
- if (sig == SIGCONT) {
- cont_handler(sig);
- }
-
- context_switch = 1;
}
/* -----------------------------------------------------------------------------
#if !defined(THREADED_RTS)
void
-markSignalHandlers (evac_fn evac)
+markSignalHandlers (evac_fn evac, void *user)
{
StgPtr *p;
p = next_pending_handler;
while (p != pending_handler_buf) {
p--;
- evac((StgClosure **)p);
+ evac(user, (StgClosure **)p);
}
}
#else
void
-markSignalHandlers (evac_fn evac STG_UNUSED)
+markSignalHandlers (evac_fn evac STG_UNUSED, void *user STG_UNUSED)
{
}
#endif
* We like to shutdown nicely after receiving a SIGINT, write out the
* stats, write profiling info, close open files and flush buffers etc.
* -------------------------------------------------------------------------- */
-#ifdef SMP
-pthread_t startup_guy;
-#endif
-
static void
shutdown_handler(int sig STG_UNUSED)
{
-#ifdef SMP
- // if I'm a worker thread, send this signal to the guy who
- // originally called startupHaskell(). Since we're handling
- // the signal, it won't be a "send to all threads" type of signal
- // (according to the POSIX threads spec).
- if (pthread_self() != startup_guy) {
- pthread_kill(startup_guy, sig);
- return;
- }
-#endif
-
// If we're already trying to interrupt the RTS, terminate with
// extreme prejudice. So the first ^C tries to exit the program
// cleanly, and the second one just kills it.
* doesn't seem to do so.
* -------------------------------------------------------------------------- */
void
-initDefaultHandlers()
+initDefaultHandlers(void)
{
struct sigaction action,oact;
-#ifdef SMP
- startup_guy = pthread_self();
-#endif
-
// install the SIGINT handler
action.sa_handler = shutdown_handler;
sigemptyset(&action.sa_mask);
action.sa_flags = 0;
if (sigaction(SIGINT, &action, &oact) != 0) {
- errorBelch("warning: failed to install SIGINT handler");
+ sysErrorBelch("warning: failed to install SIGINT handler");
}
#if defined(HAVE_SIGINTERRUPT)
siginterrupt(SIGINT, 1); // isn't this the default? --SDM
#endif
- // install the SIGCONT handler
- action.sa_handler = cont_handler;
- sigemptyset(&action.sa_mask);
- action.sa_flags = 0;
- if (sigaction(SIGCONT, &action, &oact) != 0) {
- errorBelch("warning: failed to install SIGCONT handler");
- }
-
// install the SIGFPE handler
// In addition to handling SIGINT, also handle SIGFPE by ignoring it.
sigemptyset(&action.sa_mask);
action.sa_flags = 0;
if (sigaction(SIGFPE, &action, &oact) != 0) {
- errorBelch("warning: failed to install SIGFPE handler");
+ sysErrorBelch("warning: failed to install SIGFPE handler");
}
#endif
#ifdef alpha_HOST_ARCH
ieee_set_fp_control(0);
#endif
+
+ // ignore SIGPIPE; see #1619
+ action.sa_handler = SIG_IGN;
+ sigemptyset(&action.sa_mask);
+ action.sa_flags = 0;
+ if (sigaction(SIGPIPE, &action, &oact) != 0) {
+ sysErrorBelch("warning: failed to install SIGPIPE handler");
+ }
+}
+
+void
+resetDefaultHandlers(void)
+{
+ struct sigaction action;
+
+ action.sa_handler = SIG_DFL;
+ sigemptyset(&action.sa_mask);
+ action.sa_flags = 0;
+
+ // restore SIGINT
+ if (sigaction(SIGINT, &action, NULL) != 0) {
+ sysErrorBelch("warning: failed to uninstall SIGINT handler");
+ }
+ // restore SIGPIPE
+ if (sigaction(SIGPIPE, &action, NULL) != 0) {
+ sysErrorBelch("warning: failed to uninstall SIGPIPE handler");
+ }
+}
+
+void
+freeSignalHandlers(void) {
+ if (signal_handlers != NULL) {
+ stgFree(signal_handlers);
+ }
}
#endif /* RTS_USER_SIGNALS */