From 72b48c4440c3bbb7344b15c13c7ddb56019b0af5 Mon Sep 17 00:00:00 2001 From: Viktor Dukhovni Date: Tue, 20 Apr 2021 13:56:01 -0400 Subject: Block signals in the ticker thread This avoids surprises in the non-threaded runtime with blocked signals killing the process because they're only blocked in the main thread and not in the ticker thread. --- rts/posix/itimer/Pthread.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/rts/posix/itimer/Pthread.c b/rts/posix/itimer/Pthread.c index 438bc2f69c..7b968f28f0 100644 --- a/rts/posix/itimer/Pthread.c +++ b/rts/posix/itimer/Pthread.c @@ -171,6 +171,11 @@ initTicker (Time interval, TickProc handle_tick) itimer_interval = interval; stopped = false; exited = false; +#if defined(HAVE_SIGNAL_H) + sigset_t mask, omask; + int sigret; +#endif + int ret; initCondition(&start_cond); initMutex(&mutex); @@ -184,8 +189,23 @@ initTicker (Time interval, TickProc handle_tick) * when _POSIX_SOURCE is not defined, but we're including * , so must use pthread_set_name_np() instead. See similar * code in "rts/posix/OSThreads.c". + * + * Create the thread with all blockable signals blocked, leaving signal + * handling to the main and/or other threads. This is especially useful in + * the non-threaded runtime, where applications might expect sigprocmask(2) + * to effectively block signals. */ - if (! pthread_create(&thread, NULL, itimer_thread_func, (void*)handle_tick)) { +#if defined(HAVE_SIGNAL_H) + sigfillset(&mask); + sigret = pthread_sigmask(SIG_SETMASK, &mask, &omask); +#endif + ret = pthread_create(&thread, NULL, itimer_thread_func, (void*)handle_tick); +#if defined(HAVE_SIGNAL_H) + if (sigret == 0) + pthread_sigmask(SIG_SETMASK, &omask, NULL); +#endif + + if (ret == 0) { #if defined(HAVE_PTHREAD_SET_NAME_NP) pthread_set_name_np(thread, "ghc_ticker"); #elif defined(HAVE_PTHREAD_SETNAME_NP) -- cgit v1.2.1