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]