[PATCH] Do not queue the accept tasks until all initialization has been done.

Martin Blix Grydeland martin at varnish-software.com
Mon Nov 19 11:10:10 CET 2012


This resolves the race where the pools might accept connections and
start processing them before a lot of the initialization routines has
finished.
---
 bin/varnishd/cache/cache.h      |    1 +
 bin/varnishd/cache/cache_main.c |    3 +++
 bin/varnishd/cache/cache_pool.c |   41 +++++++++++++++++++++++++++++++++------
 3 files changed, 39 insertions(+), 6 deletions(-)

diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h
index 6d4fe86..1383ffb 100644
--- a/bin/varnishd/cache/cache.h
+++ b/bin/varnishd/cache/cache.h
@@ -940,6 +940,7 @@ void PipeRequest(struct req *req);
 
 /* cache_pool.c */
 void Pool_Init(void);
+void Pool_Accept(void);
 void Pool_Work_Thread(void *priv, struct worker *w);
 int Pool_Task(struct pool *pp, struct pool_task *task, enum pool_how how);
 
diff --git a/bin/varnishd/cache/cache_main.c b/bin/varnishd/cache/cache_main.c
index ac36308..a7e4260 100644
--- a/bin/varnishd/cache/cache_main.c
+++ b/bin/varnishd/cache/cache_main.c
@@ -228,6 +228,9 @@ child_main(void)
 	if (FEATURE(FEATURE_WAIT_SILO))
 		SMP_Ready();
 
+	/* Start the accept tasks */
+	Pool_Accept();
+
 	CLI_Run();
 
 	STV_close();
diff --git a/bin/varnishd/cache/cache_pool.c b/bin/varnishd/cache/cache_pool.c
index 0e0d9dd..fa2248d 100644
--- a/bin/varnishd/cache/cache_pool.c
+++ b/bin/varnishd/cache/cache_pool.c
@@ -66,6 +66,7 @@ struct pool {
 	struct taskhead			idle_queue;
 	struct taskhead			front_queue;
 	struct taskhead			back_queue;
+	unsigned			accepting;
 	unsigned			nthr;
 	unsigned			dry;
 	unsigned			lqueue;
@@ -76,6 +77,7 @@ struct pool {
 
 static struct lock		pool_mtx;
 static pthread_t		thr_pool_herder;
+static unsigned			pool_accepting = 0;
 
 /*--------------------------------------------------------------------
  */
@@ -412,8 +414,6 @@ static struct pool *
 pool_mkpool(unsigned pool_no)
 {
 	struct pool *pp;
-	struct listen_sock *ls;
-	struct poolsock *ps;
 
 	ALLOC_OBJ(pp, POOL_MAGIC);
 	if (pp == NULL)
@@ -428,6 +428,23 @@ pool_mkpool(unsigned pool_no)
 	AZ(pthread_cond_init(&pp->herder_cond, NULL));
 	AZ(pthread_create(&pp->herder_thr, NULL, pool_herder, pp));
 
+	return (pp);
+}
+
+/*--------------------------------------------------------------------
+ * Queue the acceptor task
+ */
+
+static void
+pool_queueaccept(struct pool *pp)
+{
+	struct listen_sock *ls;
+	struct poolsock *ps;
+
+	AZ(pp->accepting);
+	pp->accepting = 1;
+
+	/* Queue accept tasks for the sockets */
 	VTAILQ_FOREACH(ls, &heritage.socks, list) {
 		if (ls->sock < 0)
 			continue;
@@ -438,8 +455,6 @@ pool_mkpool(unsigned pool_no)
 		ps->task.priv = ps;
 		AZ(Pool_Task(pp, &ps->task, POOL_QUEUE_BACK));
 	}
-
-	return (pp);
 }
 
 /*--------------------------------------------------------------------
@@ -472,11 +487,17 @@ pool_poolherder(void *priv)
 		/* XXX: remove pools */
 		if (0)
 			SES_DeletePool(NULL);
-		(void)sleep(1);
 		u = 0;
-		VTAILQ_FOREACH(pp, &pools, list)
+		VTAILQ_FOREACH(pp, &pools, list) {
+			if (pool_accepting && !pp->accepting)
+				pool_queueaccept(pp);
 			u += pp->lqueue;
+		}
 		VSC_C_main->thread_queue_len = u;
+		if (pool_accepting)
+			VTIM_sleep(1.);
+		else
+			VTIM_sleep(.1);
 	}
 	NEEDLESS_RETURN(NULL);
 }
@@ -484,6 +505,14 @@ pool_poolherder(void *priv)
 /*--------------------------------------------------------------------*/
 
 void
+Pool_Accept(void)
+{
+
+	ASSERT_CLI();
+	pool_accepting = 1;
+}
+
+void
 Pool_Init(void)
 {
 
-- 
1.7.9.5




More information about the varnish-dev mailing list