[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