pgpool2.git / summary / log / commit / refs

commit    790b231318eab36f30f00608f3f2bf4dafe80890
Author:   Yoshiyuki Asaba <y-asaba at pgfoundry.org>
Date:     Thu Jul 05 09:12:37 2007 +0000

    Improve signal handling.
    
    We fixed signal handling at revision 1.6. That fix was to set a flag
    in signal handler, then pgpool checked flags in safe points. However
    It has a race condition in the following case.
    
      CHECK_REQUEST;   <-- check flags
      <signal handler> <-- set flags
      pause();         <-- wait for signals
    
    So, we modified to deliver signals in safe places which are in pause()
    and sleep().


main.c | 76 ++++++++++++++---------------------------------------------------- 1 file changed, 16 insertions(+), 60 deletions(-) diff --git a/main.c b/main.c index 3204c9b9e..2977ae1ad 100644 --- a/main.c +++ b/main.c @@ -47,25 +47,6 @@ #include "version.h" -#define CHECK_REQUEST \ - do { \ - if (wakeup_request) \ - { \ - wakeup_children(); \ - wakeup_request = 0; \ - } \ - if (failover_request) \ - { \ - failover(); \ - failover_request = 0; \ - } \ - if (sigchld_request) \ - { \ - reaper(); \ - } \ - } while (0) - - #define PGPOOLMAXLITSENQUEUELENGTH 10000 static void daemonize(void); static int read_pid_file(void); @@ -75,9 +56,6 @@ static pid_t fork_a_child(int unix_fd, int inet_fd, int id); static int create_unix_domain_socket(struct sockaddr_un un_addr_tmp); static int create_inet_domain_socket(const char *hostname, const int port); static void myexit(int code); -static void failover(void); -static void reaper(void); -static void wakeup_children(void); static RETSIGTYPE exit_handler(int sig); static RETSIGTYPE reap_handler(int sig); @@ -122,9 +100,6 @@ static int health_check_timer_expired; /* non 0 if health check timer expired * POOL_REQUEST_INFO *Req_info; /* request info area in shared memory */ volatile int *InRecovery; /* non 0 if recovery is started */ -static volatile sig_atomic_t failover_request = 0; -static volatile sig_atomic_t sigchld_request = 0; -static volatile sig_atomic_t wakeup_request = 0; int my_proc_id; @@ -403,8 +378,6 @@ int main(int argc, char **argv) */ for (;;) { - CHECK_REQUEST; - /* do we need health checking for PostgreSQL? */ if (pool_config->health_check_period > 0) { @@ -452,7 +425,7 @@ int main(int argc, char **argv) pool_log("set %d th backend down status", sts); Req_info->kind = NODE_DOWN_REQUEST; Req_info->node_id = sts; - failover(); + failover_handler(0); /* need to distribute this info to children */ } else @@ -466,7 +439,7 @@ int main(int argc, char **argv) pool_log("set %d th backend down status", sts); Req_info->kind = NODE_DOWN_REQUEST; Req_info->node_id = sts; - failover(); + failover_handler(0); retrycnt = 0; } else @@ -476,8 +449,9 @@ int main(int argc, char **argv) pool_debug("retry sleep time: %d seconds", sleep_time); while (sleep_time > 0) { + POOL_SETMASK(&UnBlockSig); sleep_time = sleep(sleep_time); - CHECK_REQUEST; + POOL_SETMASK(&BlockSig); } continue; } @@ -500,8 +474,9 @@ int main(int argc, char **argv) pool_debug("retry sleep time: %d seconds", sleep_time); while (sleep_time > 0) { + POOL_SETMASK(&UnBlockSig); sleep_time = sleep(sleep_time); - CHECK_REQUEST; + POOL_SETMASK(&BlockSig); } continue; } @@ -517,13 +492,16 @@ int main(int argc, char **argv) sleep_time = pool_config->health_check_period; while (sleep_time > 0) { + POOL_SETMASK(&UnBlockSig); sleep_time = sleep(sleep_time); - CHECK_REQUEST; + POOL_SETMASK(&BlockSig); } } else { + POOL_SETMASK(&UnBlockSig); pause(); + POOL_SETMASK(&BlockSig); } } @@ -975,22 +953,10 @@ static RETSIGTYPE exit_handler(int sig) /* * handle SIGUSR1 - * - */ -static RETSIGTYPE failover_handler(int sig) -{ - POOL_SETMASK(&BlockSig); - failover_request = 1; - POOL_SETMASK(&UnBlockSig); -} - -/* * backend connection error, failover/failback request, if possible - * */ -static void failover(void) +static RETSIGTYPE failover_handler(int sig) { - int node_id; int i; @@ -1343,16 +1309,9 @@ system_db_health_check(void) /* * handle SIGCHLD - */ -static RETSIGTYPE reap_handler(int sig) -{ - sigchld_request = 1; -} - -/* * Attach zombie processes and restart child processes. */ -static void reaper(void) +static RETSIGTYPE reap_handler(int sig) { pid_t pid; int status; @@ -1361,7 +1320,6 @@ static void reaper(void) POOL_SETMASK(&BlockSig); pool_debug("reap_handler called"); - sigchld_request = 0; if (exiting) { @@ -1487,10 +1445,12 @@ pool_get_system_db_info(void) * handle SIGUSR2 * Wakeup all process */ -static void wakeup_children(void) +static RETSIGTYPE wakeup_handler(int sig) { int i; + POOL_SETMASK(&BlockSig); + /* kill all children */ for (i = 0; i < pool_config->num_init_children; i++) { @@ -1500,10 +1460,6 @@ static void wakeup_children(void) kill(pid, SIGUSR2); } } -} - -static RETSIGTYPE wakeup_handler(int sig) -{ - wakeup_request = 1; + POOL_SETMASK(&UnBlockSig); } [parent: 85185478feaa]