[master] 18fd12a Make idle workers give up their VCL after a minute without work

Poul-Henning Kamp phk at varnish-cache.org
Fri Nov 15 08:42:42 CET 2013


commit 18fd12a2fd6c6aca506f699140c1b842cca24a84
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Thu Nov 14 22:57:22 2013 +0000

    Make idle workers give up their VCL after a minute without work
    
    Inspired by:  An old patch from Mithrandir I found in my mailbox

diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h
index ddf9fa2..a4a8e99 100644
--- a/bin/varnishd/cache/cache.h
+++ b/bin/varnishd/cache/cache.h
@@ -1047,7 +1047,7 @@ void Lck__Assert(const struct lock *lck, int held);
 /* public interface: */
 void LCK_Init(void);
 void Lck_Delete(struct lock *lck);
-int Lck_CondWait(pthread_cond_t *cond, struct lock *lck, struct timespec *ts);
+int Lck_CondWait(pthread_cond_t *cond, struct lock *lck, double);
 
 #define Lck_New(a, b) Lck__New(a, b, #b)
 #define Lck_Lock(a) Lck__Lock(a, __func__, __FILE__, __LINE__)
diff --git a/bin/varnishd/cache/cache_busyobj.c b/bin/varnishd/cache/cache_busyobj.c
index 38da061..1e735b2 100644
--- a/bin/varnishd/cache/cache_busyobj.c
+++ b/bin/varnishd/cache/cache_busyobj.c
@@ -235,7 +235,7 @@ VBO_waitlen(struct busyobj *bo, ssize_t l)
 	while (1) {
 		if (bo->fetch_obj->len > l || bo->state >= BOS_FINISHED)
 			break;
-		(void)Lck_CondWait(&bo->cond, &bo->mtx, NULL);
+		(void)Lck_CondWait(&bo->cond, &bo->mtx, 0);
 	}
 	l = bo->fetch_obj->len;
 	Lck_Unlock(&bo->mtx);
@@ -260,7 +260,7 @@ VBO_waitstate(struct busyobj *bo, enum busyobj_state_e want)
 	while (1) {
 		if (bo->state >= want)
 			break;
-		(void)Lck_CondWait(&bo->cond, &bo->mtx, NULL);
+		(void)Lck_CondWait(&bo->cond, &bo->mtx, 0);
 	}
 	Lck_Unlock(&bo->mtx);
 }
diff --git a/bin/varnishd/cache/cache_expire.c b/bin/varnishd/cache/cache_expire.c
index e3feee9..88d49fb 100644
--- a/bin/varnishd/cache/cache_expire.c
+++ b/bin/varnishd/cache/cache_expire.c
@@ -564,7 +564,6 @@ exp_thread(struct worker *wrk, void *priv)
 	struct objcore *oc;
 	double t = 0, tnext = 0;
 	struct exp_priv *ep;
-	struct timespec ts;
 
 	CAST_OBJ_NOTNULL(ep, priv, EXP_PRIV_MAGIC);
 	ep->wrk = wrk;
@@ -581,9 +580,7 @@ exp_thread(struct worker *wrk, void *priv)
 		} else if (tnext > t) {
 			VSL_Flush(&ep->vsl, 0);
 			WRK_SumStat(wrk);
-			ts.tv_nsec = (long)(modf(tnext, &t) * 1e9);
-			ts.tv_sec = (long)t;
-			(void)Lck_CondWait(&ep->condvar, &ep->mtx, &ts);
+			(void)Lck_CondWait(&ep->condvar, &ep->mtx, tnext);
 		}
 		Lck_Unlock(&ep->mtx);
 
diff --git a/bin/varnishd/cache/cache_lck.c b/bin/varnishd/cache/cache_lck.c
index 9b8444c..54203af 100644
--- a/bin/varnishd/cache/cache_lck.c
+++ b/bin/varnishd/cache/cache_lck.c
@@ -36,6 +36,7 @@
 #include "config.h"
 
 #include <stdlib.h>
+#include <math.h>
 
 #include "cache.h"
 
@@ -139,19 +140,23 @@ Lck__Assert(const struct lock *lck, int held)
 }
 
 int __match_proto__()
-Lck_CondWait(pthread_cond_t *cond, struct lock *lck, struct timespec *ts)
+Lck_CondWait(pthread_cond_t *cond, struct lock *lck, double when)
 {
 	struct ilck *ilck;
 	int retval = 0;
+	struct timespec ts;
+	double t;
 
 	CAST_OBJ_NOTNULL(ilck, lck->priv, ILCK_MAGIC);
 	AN(ilck->held);
 	assert(pthread_equal(ilck->owner, pthread_self()));
 	ilck->held = 0;
-	if (ts == NULL) {
+	if (when == 0) {
 		AZ(pthread_cond_wait(cond, &ilck->mtx));
 	} else {
-		retval = pthread_cond_timedwait(cond, &ilck->mtx, ts);
+		ts.tv_nsec = (long)(modf(when, &t) * 1e9);
+		ts.tv_sec = (long)t;
+		retval = pthread_cond_timedwait(cond, &ilck->mtx, &ts);
 		assert(retval == 0 || retval == ETIMEDOUT);
 	}
 	AZ(ilck->held);
diff --git a/bin/varnishd/cache/cache_pool.c b/bin/varnishd/cache/cache_pool.c
index 4308fb3..b22fe09 100644
--- a/bin/varnishd/cache/cache_pool.c
+++ b/bin/varnishd/cache/cache_pool.c
@@ -246,6 +246,7 @@ Pool_Work_Thread(void *priv, struct worker *wrk)
 	struct pool *pp;
 	int stats_clean;
 	struct pool_task *tp;
+	int i;
 
 	CAST_OBJ_NOTNULL(pp, priv, POOL_MAGIC);
 	wrk->pool = pp;
@@ -277,7 +278,12 @@ Pool_Work_Thread(void *priv, struct worker *wrk)
 			VTAILQ_INSERT_HEAD(&pp->idle_queue, &wrk->task, list);
 			if (!stats_clean)
 				WRK_SumStat(wrk);
-			(void)Lck_CondWait(&wrk->cond, &pp->mtx, NULL);
+			do {
+				i = Lck_CondWait(&wrk->cond, &pp->mtx,
+				    wrk->vcl == NULL ?  0 : wrk->lastused+60.);
+				if (i == ETIMEDOUT)
+					VCL_Rel(&wrk->vcl);
+			} while (i);
 			tp = &wrk->task;
 		}
 		Lck_Unlock(&pp->mtx);
@@ -405,7 +411,7 @@ pool_herder(void *priv)
 
 		Lck_Lock(&pp->mtx);
 		if (!pp->dry) {
-			(void)Lck_CondWait(&pp->herder_cond, &pp->mtx, NULL);
+			(void)Lck_CondWait(&pp->herder_cond, &pp->mtx, 0);
 		} else {
 			/* XXX: unsafe counters */
 			VSC_C_main->threads_limited++;



More information about the varnish-commit mailing list