diff --git a/kitty/child-monitor.c b/kitty/child-monitor.c index 918897825..c538cb961 100644 --- a/kitty/child-monitor.c +++ b/kitty/child-monitor.c @@ -137,8 +137,7 @@ new(PyTypeObject *type, PyObject *args, PyObject UNUSED *kwds) { return NULL; } self = (ChildMonitor *)type->tp_alloc(type, 0); - if (!init_loop_data(&self->io_loop_data)) return PyErr_SetFromErrno(PyExc_OSError); - if (!install_signal_handlers(&self->io_loop_data)) return PyErr_SetFromErrno(PyExc_OSError); + if (!init_loop_data(&self->io_loop_data, 5, SIGINT, SIGTERM, SIGCHLD, SIGUSR1, SIGUSR2)) return PyErr_SetFromErrno(PyExc_OSError); self->talk_fd = talk_fd; self->listen_fd = listen_fd; if (self == NULL) return PyErr_NoMemory(); @@ -1605,7 +1604,7 @@ talk_loop(void *data) { // The talk thread loop ChildMonitor *self = (ChildMonitor*)data; set_thread_name("KittyPeerMon"); - if (!init_loop_data(&talk_data.loop_data)) { log_error("Failed to create wakeup fd for talk thread with error: %s", strerror(errno)); } + if (!init_loop_data(&talk_data.loop_data, 0)) { log_error("Failed to create wakeup fd for talk thread with error: %s", strerror(errno)); } PollFD fds[PEER_LIMIT + 8] = {{0}}; size_t num_listen_fds = 0, num_peer_fds = 0; #define add_listener(which) \ diff --git a/kitty/disk-cache.c b/kitty/disk-cache.c index d1bdc56cf..cdb00955d 100644 --- a/kitty/disk-cache.c +++ b/kitty/disk-cache.c @@ -329,7 +329,7 @@ ensure_state(DiskCache *self) { int ret; if (self->fully_initialized) return true; if (!self->loop_data_inited) { - if (!init_loop_data(&self->loop_data)) { PyErr_SetFromErrno(PyExc_OSError); return false; } + if (!init_loop_data(&self->loop_data, 0)) { PyErr_SetFromErrno(PyExc_OSError); return false; } self->loop_data_inited = true; } if (!self->currently_writing.hash_key) { diff --git a/kitty/loop-utils.c b/kitty/loop-utils.c index 7d6ae2bd5..85e8ea2c3 100644 --- a/kitty/loop-utils.c +++ b/kitty/loop-utils.c @@ -8,22 +8,6 @@ #include "loop-utils.h" #include "safe-wrappers.h" -bool -init_loop_data(LoopData *ld) { -#ifdef HAS_EVENT_FD - ld->wakeup_read_fd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK); - if (ld->wakeup_read_fd < 0) return false; -#else - if (!self_pipe(ld->wakeup_fds, true)) return false; - ld->wakeup_read_fd = ld->wakeup_fds[0]; -#endif - ld->signal_read_fd = -1; -#ifndef HAS_SIGNAL_FD - ld->signal_fds[0] = -1; ld->signal_fds[1] = -1; -#endif - return true; -} - #ifndef HAS_SIGNAL_FD static int signal_write_fd = -1; @@ -48,10 +32,44 @@ handle_signal(int sig_num UNUSED, siginfo_t *si, void *ucontext UNUSED) { #endif -#define SIGNAL_SET \ - sigset_t signals = {0}; \ - sigemptyset(&signals); \ - sigaddset(&signals, SIGINT); sigaddset(&signals, SIGTERM); sigaddset(&signals, SIGCHLD); sigaddset(&signals, SIGUSR1); sigaddset(&signals, SIGUSR2); \ +bool +init_loop_data(LoopData *ld, size_t num_signals, ...) { + ld->num_handled_signals = num_signals; + va_list valist; + va_start(valist, num_signals); + for (size_t i = 0; i < ld->num_handled_signals; i++) { + ld->handled_signals[i] = va_arg(valist, int); + } + va_end(valist); +#ifdef HAS_EVENT_FD + ld->wakeup_read_fd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK); + if (ld->wakeup_read_fd < 0) return false; +#else + if (!self_pipe(ld->wakeup_fds, true)) return false; + ld->wakeup_read_fd = ld->wakeup_fds[0]; +#endif + ld->signal_read_fd = -1; +#ifdef HAS_SIGNAL_FD + sigemptyset(&ld->signals); + if (ld->num_handled_signals) { + for (size_t i = 0; i < ld->num_handled_signals; i++) sigaddset(&ld->signals, ld->handled_signals[i]); + if (sigprocmask(SIG_BLOCK, &ld->signals, NULL) == -1) return false; + ld->signal_read_fd = signalfd(-1, &ld->signals, SFD_NONBLOCK | SFD_CLOEXEC); + if (ld->signal_read_fd == -1) return false; + } +#else + ld->signal_fds[0] = -1; ld->signal_fds[1] = -1; + if (ld->num_handled_signals) { + if (!self_pipe(ld->signal_fds, true)) return false; + signal_write_fd = ld->signal_fds[1]; + ld->signal_read_fd = ld->signal_fds[0]; + struct sigaction act = {.sa_sigaction=handle_signal, .sa_flags=SA_SIGINFO | SA_RESTART}; + for (size_t i = 0; i < ld->num_handled_signals; i++) { if (sigaction(ld->handled_signals[i], &act, NULL) != 0) return false; } + } +#endif + return true; +} + void free_loop_data(LoopData *ld) { @@ -60,22 +78,16 @@ free_loop_data(LoopData *ld) { CLOSE(wakeup_fds, 0); CLOSE(wakeup_fds, 1); #endif #ifndef HAS_SIGNAL_FD + signal_write_fd = -1; CLOSE(signal_fds, 0); CLOSE(signal_fds, 1); #endif #undef CLOSE if (ld->signal_read_fd > -1) { #ifdef HAS_SIGNAL_FD safe_close(ld->signal_read_fd, __FILE__, __LINE__); - SIGNAL_SET - sigprocmask(SIG_UNBLOCK, &signals, NULL); -#else - signal_write_fd = -1; + sigprocmask(SIG_UNBLOCK, &ld->signals, NULL); #endif - signal(SIGINT, SIG_DFL); - signal(SIGTERM, SIG_DFL); - signal(SIGCHLD, SIG_DFL); - signal(SIGUSR1, SIG_DFL); - signal(SIGUSR2, SIG_DFL); + for (size_t i = 0; i < ld->num_handled_signals; i++) signal(ld->num_handled_signals, SIG_DFL); } #ifdef HAS_EVENT_FD safe_close(ld->wakeup_read_fd, __FILE__, __LINE__); @@ -102,26 +114,6 @@ wakeup_loop(LoopData *ld, bool in_signal_handler, const char *loop_name) { } -bool -install_signal_handlers(LoopData *ld) { -#ifdef HAS_SIGNAL_FD - SIGNAL_SET - if (sigprocmask(SIG_BLOCK, &signals, NULL) == -1) return false; - ld->signal_read_fd = signalfd(-1, &signals, SFD_NONBLOCK | SFD_CLOEXEC); - if (ld->signal_read_fd == -1) return false; -#else - if (!self_pipe(ld->signal_fds, true)) return false; - signal_write_fd = ld->signal_fds[1]; - struct sigaction act = {.sa_sigaction=handle_signal, .sa_flags=SA_SIGINFO | SA_RESTART}; -#define SA(which) { if (sigaction(which, &act, NULL) != 0) return false; } - SA(SIGINT); SA(SIGTERM); SA(SIGCHLD); SA(SIGUSR1); SA(SIGUSR2); -#undef SA - ld->signal_read_fd = ld->signal_fds[0]; -#endif - return true; -} - - void read_signals(int fd, handle_signal_func callback, void *data) { #ifdef HAS_SIGNAL_FD diff --git a/kitty/loop-utils.h b/kitty/loop-utils.h index 9139e1862..df89fb211 100644 --- a/kitty/loop-utils.h +++ b/kitty/loop-utils.h @@ -34,16 +34,19 @@ typedef struct { #endif #ifndef HAS_SIGNAL_FD int signal_fds[2]; +#else + sigset_t signals; #endif int wakeup_read_fd; int signal_read_fd; + int handled_signals[16]; + size_t num_handled_signals; } LoopData; typedef void(*handle_signal_func)(const siginfo_t* siginfo, void *data); -bool init_loop_data(LoopData *ld); +bool init_loop_data(LoopData *ld, size_t num_handled_signals, ...); void free_loop_data(LoopData *ld); void wakeup_loop(LoopData *ld, bool in_signal_handler, const char*); -bool install_signal_handlers(LoopData *ld); void read_signals(int fd, handle_signal_func callback, void *data); static inline bool