summaryrefslogtreecommitdiffstats
path: root/src/daemon/signals.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/daemon/signals.c')
-rw-r--r--src/daemon/signals.c49
1 files changed, 20 insertions, 29 deletions
diff --git a/src/daemon/signals.c b/src/daemon/signals.c
index 4e4d7c4d4..163f92ad8 100644
--- a/src/daemon/signals.c
+++ b/src/daemon/signals.c
@@ -2,12 +2,6 @@
#include "common.h"
-/*
- * IMPORTANT: Libuv uv_spawn() uses SIGCHLD internally:
- * https://github.com/libuv/libuv/blob/cc51217a317e96510fbb284721d5e6bc2af31e33/src/unix/process.c#L485
- * Extreme care is needed when mixing and matching POSIX and libuv.
- */
-
typedef enum signal_action {
NETDATA_SIGNAL_END_OF_LIST,
NETDATA_SIGNAL_IGNORE,
@@ -56,24 +50,33 @@ static void signal_handler(int signo) {
}
}
-void signals_block(void) {
+// Mask all signals, to ensure they will only be unmasked at the threads that can handle them.
+// This means that all third party libraries (including libuv) cannot use signals anymore.
+// The signals they are interested must be unblocked at their corresponding event loops.
+static void posix_mask_all_signals(void) {
sigset_t sigset;
sigfillset(&sigset);
- if(pthread_sigmask(SIG_BLOCK, &sigset, NULL) == -1)
- netdata_log_error("SIGNAL: Could not block signals for threads");
+ if(pthread_sigmask(SIG_BLOCK, &sigset, NULL) != 0)
+ netdata_log_error("SIGNAL: cannot mask all signals");
}
-void signals_unblock(void) {
+// Unmask all signals the netdata main signal handler uses.
+// All other signals remain masked.
+static void posix_unmask_my_signals(void) {
sigset_t sigset;
- sigfillset(&sigset);
+ sigemptyset(&sigset);
- if(pthread_sigmask(SIG_UNBLOCK, &sigset, NULL) == -1) {
- netdata_log_error("SIGNAL: Could not unblock signals for threads");
- }
+ for (int i = 0; signals_waiting[i].action != NETDATA_SIGNAL_END_OF_LIST; i++)
+ sigaddset(&sigset, signals_waiting[i].signo);
+
+ if (pthread_sigmask(SIG_UNBLOCK, &sigset, NULL) != 0)
+ netdata_log_error("SIGNAL: cannot unmask netdata signals");
}
-void signals_init(void) {
+void nd_initialize_signals(void) {
+ posix_mask_all_signals(); // block all signals for all threads
+
// Catch signals which we want to use
struct sigaction sa;
sa.sa_flags = 0;
@@ -97,22 +100,10 @@ void signals_init(void) {
}
}
-void signals_reset(void) {
- struct sigaction sa;
- sigemptyset(&sa.sa_mask);
- sa.sa_handler = SIG_DFL;
- sa.sa_flags = 0;
-
- int i;
- for (i = 0; signals_waiting[i].action != NETDATA_SIGNAL_END_OF_LIST; i++) {
- if(sigaction(signals_waiting[i].signo, &sa, NULL) == -1)
- netdata_log_error("SIGNAL: Failed to reset signal handler for: %s", signals_waiting[i].name);
- }
-}
+void nd_process_signals(void) {
+ posix_unmask_my_signals();
-void signals_handle(void) {
while(1) {
-
// pause() causes the calling process (or thread) to sleep until a signal
// is delivered that either terminates the process or causes the invocation
// of a signal-catching function.