daemon: further tweaks to keepalive handling
authorAdam Dickmeiss <adam@indexdata.dk>
Thu, 3 May 2012 14:38:24 +0000 (16:38 +0200)
committerAdam Dickmeiss <adam@indexdata.dk>
Thu, 3 May 2012 14:38:24 +0000 (16:38 +0200)
SIGTERM: we wait until child terminates. This ensures that stop
script can safely assume that when moniotor process is gone, the
listening socket is closed.
SIGHUP: we send a signal to child process. Wait 2 seconds and stop
without waiting for child to terminate. Indeed it may still be running
serving remaining request. We have no way to know if the child has
really closed the listening socket within the two seconds we wait.

src/daemon.c

index 5d7979d..c72aa30 100644 (file)
@@ -62,12 +62,29 @@ static void write_pidfile(int pid_fd)
     }
 }
 
+int child_got_signal_from_us = 0;
 pid_t child_pid = 0;
-static void kill_child_handler(int num)
+static void normal_stop_handler(int num)
 {
     if (child_pid)
     {
+        /* tell child to terminate . ensure keepalive stops running -
+           let wait(2) wait once - so we exit AFTER the child */
+        child_got_signal_from_us = 1;
         kill(child_pid, num);
+    }
+}
+
+static void graceful_stop_handler(int num)
+{
+    if (child_pid)
+    {
+        /* tell our child to stop listening and wait some in time
+           in the hope that it has stopped listening by then. Then
+           we exit - quite possibly the child is still running - serving
+           remaining requests */
+        kill(child_pid, num);
+        sleep(2);
         _exit(0);
     }
 }
@@ -83,10 +100,10 @@ static void keepalive(void (*work)(void *data), void *data)
     /* keep signals in their original state and make sure that some signals
        to parent process also gets sent to the child.. 
     */
-    old_sighup = signal(SIGHUP, kill_child_handler);
-    old_sigterm = signal(SIGTERM, kill_child_handler);
-    old_sigusr1 = signal(SIGUSR1, kill_child_handler);
-    while (cont)
+    old_sighup = signal(SIGHUP, normal_stop_handler);
+    old_sigterm = signal(SIGTERM, normal_stop_handler);
+    old_sigusr1 = signal(SIGUSR1, graceful_stop_handler);
+    while (cont && !child_got_signal_from_us)
     {
         pid_t p = fork();
         pid_t p1;