]> err.no Git - varnish/commitdiff
Imlement stopping and restarting of child process.
authorphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Thu, 3 Aug 2006 11:46:52 +0000 (11:46 +0000)
committerphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Thu, 3 Aug 2006 11:46:52 +0000 (11:46 +0000)
Not as useful as it will be yet, see ticket 22

git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@622 d4fa192b-c00b-0410-8231-f00ffab90ce4

varnish-cache/bin/varnishd/mgt_child.c

index ccffc5c68c3c30ad306824ea6ee4aecd7ae11417..71fa133e5cf0df8b93d35c5e9dea13ff10146b88 100644 (file)
@@ -23,6 +23,7 @@
 #include "mgt.h"
 
 static pid_t           child_pid = -1;
+static pid_t           mgr_pid;
 static int             child_fds[2];
 static unsigned        child_should_run;
 static pthread_t       child_listen_thread;
@@ -30,20 +31,24 @@ static pthread_t    child_poker_thread;
 static pthread_mutex_t child_mtx;
 static pthread_cond_t  child_cv;
 static unsigned                child_ticker;
+static unsigned                gotint;
+static unsigned                dstarts;
 
 /*--------------------------------------------------------------------*/
 
 static void *
 child_listener(void *arg)
 {
-       FILE *f;
+       int i;
        char buf[BUFSIZ];
 
        (void)arg;
 
-       f = fdopen(child_fds[0], "r");
-       assert(f != NULL);
-       while (fgets(buf, sizeof buf, f)) {
+       while (1) {
+               i = read(child_fds[0], buf, sizeof buf - 1);
+               if (i <= 0)
+                       break;
+               buf[i] = '\0';
                printf("Child said: %s", buf);
        }
        return (NULL);
@@ -77,7 +82,6 @@ start_child(void)
        if (i < 0) 
                errx(1, "Could not fork child");
        if (i == 0) {
-               AZ(pthread_single_np());
                /* Redirect stdin/out/err */
                AZ(close(0));
                i = open("/dev/null", O_RDONLY);
@@ -90,6 +94,7 @@ start_child(void)
                AZ(close(heritage.fds[0]));
                AZ(close(heritage.fds[3]));
 
+               setproctitle("Varnish-Chld");
                child_main();
 
                exit (1);
@@ -98,13 +103,18 @@ start_child(void)
        printf("start child pid %d\n", i);
 
        AZ(close(child_fds[1]));
+       child_fds[1] = -1;
 
+       mgt_cli_start_child(heritage.fds[0], heritage.fds[3]);
        AZ(close(heritage.fds[1]));
+       heritage.fds[1] = -1;
        AZ(close(heritage.fds[2]));
-       mgt_cli_start_child(heritage.fds[0], heritage.fds[3]);
+       heritage.fds[2] = -1;
        child_pid = i;
        AZ(pthread_create(&child_listen_thread, NULL, child_listener, NULL));
+       AZ(pthread_detach(child_listen_thread));
        AZ(pthread_create(&child_poker_thread, NULL, child_poker, NULL));
+       AZ(pthread_detach(child_poker_thread));
 }
 
 /*--------------------------------------------------------------------*/
@@ -112,13 +122,45 @@ start_child(void)
 static void
 stop_child(void)
 {
+       int i;
+
+       assert(child_pid != -1);
+
+       printf("Stop child\n");
+       AZ(pthread_cancel(child_poker_thread));
+       mgt_cli_stop_child();
+
+       /* We tell the child to die gracefully by closing the CLI */
+       AZ(close(heritage.fds[0]));
+       heritage.fds[0] = -1;
+       AZ(close(heritage.fds[3]));
+       heritage.fds[3] = -1;
+
+       /*
+        * Give it one second to die, then wack it hard
+        * then another second and then we get real angry
+        */
+       for (i = 0; i < 30; i++) {
+               printf("Waiting %d %d\n",i, child_pid);
+               if (child_pid == -2)
+                       break;
+               if (i == 10) {
+                       printf("Giving cacher SIGINT\n");
+                       kill(child_pid, SIGINT);
+               }
+               if (i == 20) {
+                       printf("Giving cacher SIGKILL\n");
+                       kill(child_pid, SIGKILL);
+               }
+               usleep(100000);
+       }
 
-       exit(2);
-       /* kill child, if relevant */
-       /* join child_listen_thread */
-       /* join child_poker_thread */
-       /* close heritage.fds */
-       /* close child_fds */
+       assert(child_pid == -2);
+
+       AZ(close(child_fds[0]));
+       child_fds[0] = -1;
+       child_pid = -1;
+       printf("Child stopped\n");
 }
 
 /*--------------------------------------------------------------------*/
@@ -134,13 +176,29 @@ mgt_sigchld(int arg)
        if (r == child_pid) {
                printf("Cache child died pid=%d status=0x%x\n",
                    r, status);
-               child_pid = -1;
+               child_pid = -2;
        } else {
                printf("Unknown child died pid=%d status=0x%x\n",
                    r, status);
        }
 }
 
+/*--------------------------------------------------------------------*/
+
+static void
+mgt_sigint(int arg)
+{
+
+       (void)arg;
+       if (getpid() != mgr_pid) {
+               printf("Got SIGINT\n");
+               exit (2);
+       }
+       printf("Manager got SIGINT\n");
+       gotint = 1;
+       child_should_run = 0;
+}
+
 /*--------------------------------------------------------------------
  * This thread is the master thread in the management process.
  * The relatively simple task is to start and stop the child process
@@ -152,29 +210,49 @@ mgt_run(int dflag)
 {
        struct timespec to;
        struct sigaction sac;
-       int i, dstarts = 0;
+       int i;
+
+       mgr_pid = getpid();
 
-#if 1
        if (dflag)
                mgt_cli_setup(0, 1, 1);
-#else
-       dflag = 0;
-#endif
 
        sac.sa_handler = mgt_sigchld;
-       sac.sa_flags = SA_NOCLDSTOP;
+       sac.sa_flags = SA_RESTART | SA_NOCLDSTOP;
        AZ(sigaction(SIGCHLD, &sac, NULL));
+
+       sac.sa_handler = mgt_sigint;
+       sac.sa_flags = SA_RESTART;
+       AZ(sigaction(SIGINT, &sac, NULL));
+       AZ(sigaction(SIGTERM, &sac, NULL));
+
+       setproctitle("Varnish-Mgr");
+
+       sac.sa_handler = SIG_IGN;
+       sac.sa_flags = SA_RESTART;
+       AZ(sigaction(SIGPIPE, &sac, NULL));
+       AZ(sigaction(SIGHUP, &sac, NULL));
+
        child_should_run = !dflag;
 
        AZ(pthread_cond_init(&child_cv, NULL));
        AZ(pthread_mutex_init(&child_mtx, NULL));
 
        while (1) {
+               if (child_should_run && child_pid == -2)
+                       stop_child();
                if (!child_should_run && child_pid != -1)
                        stop_child();
-               else if (child_should_run && child_pid == -1) {
-                       if (dflag && dstarts)
+               if (gotint) {
+                       printf("Manager died due to sigint\n");
+                       exit(2);
+               }
+               if (child_should_run && child_pid == -1) {
+                       if (dflag && dstarts) {
+                               printf(
+                                   "Manager not autostarting in debug mode\n");
                                exit(2);
+                       }
                        start_child();
                        dstarts = 1;
                }
@@ -200,6 +278,7 @@ void
 mgt_start_child(void)
 {
 
+       dstarts = 0;
        child_should_run = 1;
        AZ(pthread_cond_signal(&child_cv));
 }