r622 - trunk/varnish-cache/bin/varnishd

phk at projects.linpro.no phk at projects.linpro.no
Thu Aug 3 13:46:52 CEST 2006


Author: phk
Date: 2006-08-03 13:46:52 +0200 (Thu, 03 Aug 2006)
New Revision: 622

Modified:
   trunk/varnish-cache/bin/varnishd/mgt_child.c
Log:
Imlement stopping and restarting of child process.

Not as useful as it will be yet, see ticket 22



Modified: trunk/varnish-cache/bin/varnishd/mgt_child.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/mgt_child.c	2006-08-03 11:45:23 UTC (rev 621)
+++ trunk/varnish-cache/bin/varnishd/mgt_child.c	2006-08-03 11:46:52 UTC (rev 622)
@@ -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_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 @@
 	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 @@
 		AZ(close(heritage.fds[0]));
 		AZ(close(heritage.fds[3]));
 
+		setproctitle("Varnish-Chld");
 		child_main();
 
 		exit (1);
@@ -98,13 +103,18 @@
 	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 @@
 static void
 stop_child(void)
 {
+	int i;
 
-	exit(2);
-	/* kill child, if relevant */
-	/* join child_listen_thread */
-	/* join child_poker_thread */
-	/* close heritage.fds */
-	/* close child_fds */
+	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);
+	}
+
+	assert(child_pid == -2);
+
+	AZ(close(child_fds[0]));
+	child_fds[0] = -1;
+	child_pid = -1;
+	printf("Child stopped\n");
 }
 
 /*--------------------------------------------------------------------*/
@@ -134,13 +176,29 @@
 	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 @@
 {
 	struct timespec to;
 	struct sigaction sac;
-	int i, dstarts = 0;
+	int i;
 
-#if 1
+	mgr_pid = getpid();
+
 	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 @@
 mgt_start_child(void)
 {
 
+	dstarts = 0;
 	child_should_run = 1;
 	AZ(pthread_cond_signal(&child_cv));
 }




More information about the varnish-commit mailing list