From 881ec3e2718d63c5d847fc9fac6cee2b56eb4b77 Mon Sep 17 00:00:00 2001 From: Tatsuo Ishii Date: Sat, 19 Mar 2022 18:25:15 +0900 Subject: [PATCH] Allow shutdown interrupt while processing SIGCHILD in pgpool main. Currently most signals are blocked in pgpool main loop. In some situations the SIGCHLD handler (reaper()) takes long time or blocked in wait system call. I suspect that this could cause occasional timeout in some regression tests. So allow interrupts while executing reaper(). Also re-implement CHECK_REQUEST macro as a function. There's no point to implement CHECK_REQUEST using macro. --- src/main/pgpool_main.c | 89 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 85 insertions(+), 4 deletions(-) diff --git a/src/main/pgpool_main.c b/src/main/pgpool_main.c index 2f3f4b065..ef68ddc01 100644 --- a/src/main/pgpool_main.c +++ b/src/main/pgpool_main.c @@ -85,6 +85,7 @@ typedef struct User1SignalSlot sig_atomic_t signalFlags[MAX_INTERRUPTS]; } User1SignalSlot; +#ifdef NOT_USED /* * Process pending signal actions. */ @@ -112,6 +113,7 @@ typedef struct User1SignalSlot reload_config_request = 0; \ } \ } while (0) +#endif #define PGPOOLMAXLITSENQUEUELENGTH 10000 @@ -190,6 +192,11 @@ static void save_node_info(FAILOVER_CONTEXT *failover_context, int new_primary_n static void exec_child_restart(FAILOVER_CONTEXT *failover_context, int node_id); static void exec_notice_pcp_child(FAILOVER_CONTEXT *failover_context); +static void check_requests(void); +#ifdef DEBUG +static void print_signal_member(sigset_t *sig); +#endif + static struct sockaddr_un un_addr; /* unix domain socket path */ static struct sockaddr_un pcp_un_addr; /* unix domain socket path for PCP */ ProcessInfo *process_info = NULL; /* Per child info table on shmem */ @@ -512,8 +519,11 @@ PgpoolMain(bool discard_status, bool clear_memcache_oidmaps) /* This is the main loop */ for (;;) { + /* Check pending requests */ + check_requests(); +#ifdef NOT_USED CHECK_REQUEST; - +#endif /* * check for child signals to ensure child startup before reporting * successful start. @@ -1636,7 +1646,7 @@ reaper(void) int status; int i; - ereport(DEBUG1, + ereport(LOG, (errmsg("reaper handler"))); if (exiting) @@ -1852,7 +1862,7 @@ reaper(void) } } - ereport(DEBUG1, + ereport(LOG, (errmsg("reaper handler: exiting normally"))); } @@ -2060,7 +2070,7 @@ pool_sleep(unsigned int second) r = pool_pause(&timeout); POOL_SETMASK(&BlockSig); if (r > 0) - CHECK_REQUEST; + check_requests(); POOL_SETMASK(&UnBlockSig); gettimeofday(¤t_time, NULL); } @@ -4621,3 +4631,74 @@ create_inet_domain_sockets_by_list(char **listen_addresses, int n_listen_address return sockets; } + +/* + * Check and execute pending requests set by signal interrupts. + */ +static +void check_requests(void) +{ + /* + * Waking child request? + */ + if (wakeup_request) + { + wakeup_children(); + wakeup_request = 0; + } + + /* + * Failover or failback request? + */ + if (sigusr1_request) + { + do { + sigusr1_request = 0; + sigusr1_interrupt_processor(); + } while (sigusr1_request == 1); + } + + /* + * Unblock signals so that SIGQUIT/SIGTERRM/SIGINT can be accepted. + * They are all shutdown requests. + */ + POOL_SETMASK(&UnBlockSig); + + /* + * Reap child request? + */ + if (sigchld_request) + { + reaper(); + } + + /* + * Configuration file reloading request? + */ + if (reload_config_request) + { + reload_config(); + reload_config_request = 0; + } + + /* + * Block signals again + */ + POOL_SETMASK(&BlockSig); +} + +#ifdef DEBUG +static +void print_signal_member(sigset_t *sig) +{ + if (sigismember(sig, SIGQUIT)) + ereport(LOG, + (errmsg("SIGQUIT is member"))); + if (sigismember(sig, SIGINT)) + ereport(LOG, + (errmsg("SIGINT is member"))); + if (sigismember(sig, SIGTERM)) + ereport(LOG, + (errmsg("SIGTERM is member"))); +} +#endif -- 2.39.5