Add psignal module for centralized signal handling (#368)
* Add psignal module for centralized signal handling - Added pclsync/psignal.h with psignal_register() and psignal_check_pending() API - Added pclsync/psignal.c with async-signal-safe handlers for SIGINT, SIGTERM, SIGHUP - Implements flag-based deferred signal handling pattern * Integrate psignal into main loop and remove conflicting handlers - Added extern "C" linkage to psignal.h for C++ compatibility - Integrated psignal_check_pending() into pclsync_lib.cpp main loop - Integrated psignal_check_pending() into ptimer.c timer loop - Removed conflicting signal handlers from pfs.c * Migrate psync_set_signal to psignal module - Added psignal_set_custom_handler() to psignal.h and psignal.c - Replaced psync_set_signal() calls in pfs.c with psignal_set_custom_handler() - Centralizes all signal handling in psignal module --------- Co-authored-by: Levi Neely <lkn@darkstar.example.net>
This commit is contained in:
parent
9d4143f1f0
commit
89ef8663b0
|
|
@ -3601,28 +3601,7 @@ static void psync_usr2_handler(int sig) {
|
|||
pdbg_reopen_log();
|
||||
}
|
||||
|
||||
static void psync_set_signal(int sig, void (*handler)(int)) {
|
||||
struct sigaction sa;
|
||||
|
||||
if (pdbg_unlikely(sigaction(sig, NULL, &sa)))
|
||||
return;
|
||||
|
||||
if (sa.sa_handler == SIG_DFL) {
|
||||
memset(&sa, 0, sizeof(struct sigaction));
|
||||
sigemptyset(&(sa.sa_mask));
|
||||
sa.sa_handler = handler;
|
||||
sa.sa_flags = 0;
|
||||
sigaction(sig, &sa, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void psync_setup_signals() {
|
||||
psync_set_signal(SIGTERM, psync_signal_handler);
|
||||
psync_set_signal(SIGINT, psync_signal_handler);
|
||||
psync_set_signal(SIGHUP, psync_signal_handler);
|
||||
pfs_debug_register_signal_handlers();
|
||||
psync_set_signal(SIGUSR2, psync_usr2_handler);
|
||||
}
|
||||
#include "psignal.h"
|
||||
|
||||
static void pfs_init_once() {
|
||||
#if pfs_need_per_folder_refresh_const()
|
||||
|
|
@ -3637,7 +3616,8 @@ static void pfs_init_once() {
|
|||
pfs_task_init();
|
||||
ppagecache_init();
|
||||
atexit(pfs_do_stop);
|
||||
psync_setup_signals();
|
||||
pfs_debug_register_signal_handlers();
|
||||
psignal_set_custom_handler(SIGUSR2, psync_usr2_handler);
|
||||
pfs_stat_add_files();
|
||||
pfs_task_add_banned_folders();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,71 @@
|
|||
#include "psignal.h"
|
||||
#include <signal.h>
|
||||
#include <stddef.h>
|
||||
|
||||
static volatile sig_atomic_t sigint_flag = 0;
|
||||
static volatile sig_atomic_t sigterm_flag = 0;
|
||||
static volatile sig_atomic_t sighup_flag = 0;
|
||||
|
||||
static void sigint_handler(int sig) {
|
||||
sigint_flag = 1;
|
||||
}
|
||||
|
||||
static void sigterm_handler(int sig) {
|
||||
sigterm_flag = 1;
|
||||
}
|
||||
|
||||
static void sighup_handler(int sig) {
|
||||
sighup_flag = 1;
|
||||
}
|
||||
|
||||
void psignal_set_custom_handler(int sig, void (*handler)(int)) {
|
||||
struct sigaction sa;
|
||||
|
||||
if (sigaction(sig, NULL, &sa) != 0)
|
||||
return;
|
||||
|
||||
if (sa.sa_handler == SIG_DFL) {
|
||||
sa.sa_handler = handler;
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sa.sa_flags = 0;
|
||||
if (sigaction(sig, &sa, NULL) != 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void psignal_register(int signum) {
|
||||
void (*handler)(int) = NULL;
|
||||
|
||||
if (signum == SIGINT) {
|
||||
handler = sigint_handler;
|
||||
} else if (signum == SIGTERM) {
|
||||
handler = sigterm_handler;
|
||||
} else if (signum == SIGHUP) {
|
||||
handler = sighup_handler;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
psignal_set_custom_handler(signum, handler);
|
||||
}
|
||||
|
||||
int psignal_check_pending(void) {
|
||||
sig_atomic_t int_flag = sigint_flag;
|
||||
sig_atomic_t term_flag = sigterm_flag;
|
||||
sig_atomic_t hup_flag = sighup_flag;
|
||||
|
||||
if (int_flag) {
|
||||
sigint_flag = 0;
|
||||
return SIGINT;
|
||||
}
|
||||
if (term_flag) {
|
||||
sigterm_flag = 0;
|
||||
return SIGTERM;
|
||||
}
|
||||
if (hup_flag) {
|
||||
sighup_flag = 0;
|
||||
return SIGHUP;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
#ifndef PSIGNAL_H
|
||||
#define PSIGNAL_H
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void psignal_register(int signum);
|
||||
int psignal_check_pending(void);
|
||||
void psignal_set_custom_handler(int sig, void (*handler)(int));
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -35,6 +35,7 @@
|
|||
#include "prun.h"
|
||||
#include "psys.h"
|
||||
#include "ptimer.h"
|
||||
#include "psignal.h"
|
||||
|
||||
/* Maximum timeout possible is TIMER_ARRAY_SIZE^TIMER_LEVELS seconds, in the
|
||||
* worst case TIMER_LEVELS operations will be preformed for each timer to
|
||||
|
|
@ -145,8 +146,15 @@ PSYNC_NOINLINE static void timer_process_timers(psync_list *timers) {
|
|||
static void timer_thread() {
|
||||
psync_list timers;
|
||||
time_t lt;
|
||||
int sig;
|
||||
lt = __atomic_load_n(&psync_current_time, __ATOMIC_RELAXED);
|
||||
while (psync_do_run) {
|
||||
sig = psignal_check_pending();
|
||||
if (sig) {
|
||||
pdbg_logf(D_NOTICE, "received signal %d, shutting down", sig);
|
||||
psync_do_run = 0;
|
||||
break;
|
||||
}
|
||||
psync_list_init(&timers);
|
||||
psys_sleep_milliseconds(1000);
|
||||
__atomic_store_n(&psync_current_time, psys_time_seconds(), __ATOMIC_RELAXED);
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@
|
|||
#include "pclsync/pdbg.h"
|
||||
#include "pclsync/psock.h"
|
||||
#include "pclsync/plibs.h"
|
||||
#include "pclsync/psignal.h"
|
||||
|
||||
#include "pclsync_lib.h"
|
||||
|
||||
|
|
@ -668,6 +669,10 @@ int clib::pclsync_lib::init() {
|
|||
|
||||
was_init_ = true;
|
||||
|
||||
psignal_register(SIGINT);
|
||||
psignal_register(SIGTERM);
|
||||
psignal_register(SIGHUP);
|
||||
|
||||
if (!get_mount().empty()) {
|
||||
psync_set_string_setting("fsroot", get_mount().c_str());
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue