pgpool2.git / summary / log / commit / refs
commit b52b82c1cc7731d7e1c73ea89ea3baf4b9e1ce1d
Author: Tatsuo Ishii <ishii@sraoss.co.jp>
Date: Fri May 21 12:11:27 2021 +0000
Fix watchdog communication race condition.
Watchdog sends information from the watchdog process to the Pgpool-II
main process using SIGUSR1. To pass detailed messages it uses shared
memory area. First it sets a message to the shared memory area then
sends SIGUSR1 to the main process. The main process received the
signal and the signal handler sets a global variable so that
sigusr1_interrupt_processor() processes it. However it is possible
that while sigusr1_interrupt_processor() is running new signal
arrives. In this case the new signal is caught but the global variable
is set to 0 after sigusr1_interrupt_processor() returns. This means
that the new message is not processed until new signal arrives, which
could cause significant delay before the message was processed.
To fix the problem, sigusr1_interrupt_processor() is repeatedly called
until there's no pending message.
Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2021-May/003901.html
src/main/pgpool_main.c | 19 +++++++++++++------
1 file changed, 13 insertions(+), 6 deletions(-)
diff --git a/src/main/pgpool_main.c b/src/main/pgpool_main.c
index 79f83f26d..35c6bc0d2 100644
--- a/src/main/pgpool_main.c
+++ b/src/main/pgpool_main.c
@@ -97,8 +97,10 @@ typedef struct User1SignalSlot
} \
if (sigusr1_request) \
{ \
- sigusr1_interrupt_processor(); \
- sigusr1_request = 0; \
+ do {\
+ sigusr1_request = 0; \
+ sigusr1_interrupt_processor(); \
+ } while (sigusr1_request == 1); \
} \
if (sigchld_request) \
{ \
@@ -350,8 +352,10 @@ PgpoolMain(bool discard_status, bool clear_memcache_oidmaps)
if (sigusr1_request)
{
- sigusr1_interrupt_processor();
- sigusr1_request = 0;
+ do {
+ sigusr1_request = 0;
+ sigusr1_interrupt_processor();
+ } while (sigusr1_request == 1);
}
}
@@ -600,6 +604,9 @@ register_inform_quarantine_nodes_req(void)
static void
signal_user1_to_parent_with_reason(User1SignalReason reason)
{
+ ereport(LOG,
+ (errmsg("signal_user1_to_parent_with_reason(%d)", reason)));
+
user1SignalSlot->signalFlags[reason] = true;
pool_signal_parent(SIGUSR1);
}
@@ -1222,7 +1229,7 @@ static RETSIGTYPE sigusr1_handler(int sig)
static void
sigusr1_interrupt_processor(void)
{
- ereport(DEBUG1,
+ ereport(LOG,
(errmsg("Pgpool-II parent process received SIGUSR1")));
if (user1SignalSlot->signalFlags[SIG_WATCHDOG_QUORUM_CHANGED])
@@ -1266,7 +1273,7 @@ sigusr1_interrupt_processor(void)
if (user1SignalSlot->signalFlags[SIG_WATCHDOG_STATE_CHANGED])
{
- ereport(DEBUG1,
+ ereport(LOG,
(errmsg("Pgpool-II parent process received watchdog state change signal from watchdog")));
user1SignalSlot->signalFlags[SIG_WATCHDOG_STATE_CHANGED] = false;
[parent: 352fe91e1bdc]