diff --git a/include/tarantool_pthread.h b/include/tarantool_pthread.h index e1f781dd525f458c238ca19054b185ae8c6e47a7..41094a031a8fe493fed88bdab1144d1583e30d95 100644 --- a/include/tarantool_pthread.h +++ b/include/tarantool_pthread.h @@ -149,5 +149,10 @@ tt_pthread_error(e); \ }) +#define tt_pthread_atfork(prepare, parent, child)\ +({ int e = pthread_atfork(prepare, parent, child);\ + tt_pthread_error(e); \ +}) + #endif /* TARANTOOL_PTHREAD_H_INCLUDED */ diff --git a/src/log_io.m b/src/log_io.m index ac1ef27c48a1e2484dcce0a6fe899c2c6005dcae..684842164a11c8345f4cc7643a7aaf62c3a4dbce 100644 --- a/src/log_io.m +++ b/src/log_io.m @@ -1254,7 +1254,7 @@ wal_writer_child() static void wal_writer_init_once() { - pthread_atfork(NULL, NULL, wal_writer_child); + tt_pthread_atfork(NULL, NULL, wal_writer_child); } /** diff --git a/src/tarantool.m b/src/tarantool.m index 8df1136927471dae6fa4d9dcc7a6e78b57600c70..b9a397193ef586790514b3d355bc246a0fab9f0d 100644 --- a/src/tarantool.m +++ b/src/tarantool.m @@ -57,6 +57,7 @@ #include <util.h> #include <third_party/gopt/gopt.h> #include <cfg/warning.h> +#include "tarantool_pthread.h" static pid_t master_pid; @@ -277,7 +278,8 @@ snapshot(void *ev, int events __attribute__((unused))) */ wait_for_child(p); assert(p == fiber->cw.rpid); - return WEXITSTATUS(fiber->cw.rstatus); + return (WIFSIGNALED(fiber->cw.rstatus) ? EINTR : + WEXITSTATUS(fiber->cw.rstatus)); } fiber_set_name(fiber, "dumper"); @@ -312,6 +314,31 @@ signal_free(void) ev_signal_stop(&sigs[i]); } +/** Make sure the child has a default signal disposition. */ +static void +signal_reset() +{ + struct sigaction sa; + + /* Reset all signals to their defaults. */ + memset(&sa, 0, sizeof(sa)); + sigemptyset(&sa.sa_mask); + sa.sa_handler = SIG_DFL; + + if (sigaction(SIGUSR1, &sa, NULL) == -1 || + sigaction(SIGINT, &sa, NULL) == -1 || + sigaction(SIGTERM, &sa, NULL) == -1 || + sigaction(SIGHUP, &sa, NULL) == -1) + say_syserror("sigaction"); + + /* Unblock any signals blocked by libev. */ + sigset_t sigset; + sigfillset(&sigset); + if (sigprocmask(SIG_UNBLOCK, &sigset, NULL) == -1) + say_syserror("sigprocmask"); +} + + /** * Adjust the process signal mask and add handlers for signals. */ @@ -341,6 +368,7 @@ signal_init(void) ev_signal_start(&sigs[3]); atexit(signal_free); + tt_pthread_atfork(NULL, NULL, signal_reset); } static void