[4.0] dbaba70 If workspace_thread is not be big enough to hold all the objcore pointers that need to be purged we iterate until done.

Lasse Karstensen lkarsten at varnish-software.com
Tue Sep 23 15:09:29 CEST 2014


commit dbaba7024a9775175b588260287bf6588ed6da9e
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Mon Jul 28 10:00:15 2014 +0000

    If workspace_thread is not be big enough to hold all the objcore pointers
    that need to be purged we iterate until done.
    
    Fixes #1551
    
    Conflicts:
    	bin/varnishd/cache/cache_hash.c

diff --git a/bin/varnishd/cache/cache_hash.c b/bin/varnishd/cache/cache_hash.c
index 76ad5c3..0a94a3d 100644
--- a/bin/varnishd/cache/cache_hash.c
+++ b/bin/varnishd/cache/cache_hash.c
@@ -559,49 +559,61 @@ HSH_Purge(struct worker *wrk, struct objhead *oh, double ttl, double grace,
 double keep)
 {
 	struct objcore *oc, **ocp;
-	unsigned spc, nobj, n;
+	unsigned spc, ospc, nobj, n;
 	struct object *o;
+	int more = 0;
+
 	double now;
 
 	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
 	CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC);
-	spc = WS_Reserve(wrk->aws, 0);
-	ocp = (void*)wrk->aws->f;
-	Lck_Lock(&oh->mtx);
-	assert(oh->refcnt > 0);
-	nobj = 0;
-	now = VTIM_real();
-	VTAILQ_FOREACH(oc, &oh->objcs, list) {
-		CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
-		assert(oc->objhead == oh);
-		if (oc->flags & OC_F_BUSY) {
-			/*
-			 * We cannot purge busy objects here, because their
-			 * owners have special rights to them, and may nuke
-			 * them without concern for the refcount, which by
-			 * definition always must be one, so they don't check.
-			 */
-			continue;
+	ospc = WS_Reserve(wrk->aws, 0);
+	assert(ospc >= sizeof *ocp);
+	do {
+		more = 0;
+		spc = ospc;
+		nobj = 0;
+		ocp = (void*)wrk->aws->f;
+		Lck_Lock(&oh->mtx);
+		assert(oh->refcnt > 0);
+		now = VTIM_real();
+		VTAILQ_FOREACH(oc, &oh->objcs, list) {
+			CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
+			assert(oc->objhead == oh);
+			if (oc->flags & OC_F_BUSY) {
+				/*
+				 * We cannot purge busy objects here, because
+				 * their owners have special rights to them,
+				 * and may nuke them without concern for the
+				 * refcount, which by definition always must
+				 * be one, so they don't check.
+				 */
+				continue;
+			}
+			if (oc->exp_flags & OC_EF_DYING)
+				continue;
+			if (spc < sizeof *ocp) {
+				/* Iterate if aws is not big enough */
+				more = 1;
+				break;
+			}
+			oc->refcnt++;
+			spc -= sizeof *ocp;
+			ocp[nobj++] = oc;
 		}
-		if (oc->exp_flags & OC_EF_DYING)
-			continue;
-		xxxassert(spc >= sizeof *ocp);
-		oc->refcnt++;
-		spc -= sizeof *ocp;
-		ocp[nobj++] = oc;
-	}
-	Lck_Unlock(&oh->mtx);
+		Lck_Unlock(&oh->mtx);
 
-	for (n = 0; n < nobj; n++) {
-		oc = ocp[n];
-		CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
-		o = oc_getobj(&wrk->stats, oc);
-		if (o == NULL)
-			continue;
-		CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC);
-		EXP_Rearm(o, now, ttl, grace, keep);
-		(void)HSH_DerefObj(&wrk->stats, &o);
-	}
+		for (n = 0; n < nobj; n++) {
+			oc = ocp[n];
+			CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
+			o = oc_getobj(&wrk->stats, oc);
+			if (o == NULL)
+				continue;
+			CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC);
+			EXP_Rearm(o, now, ttl, grace, keep);
+			(void)HSH_DerefObj(&wrk->stats, &o);
+		}
+	} while (more);
 	WS_Release(wrk->aws, 0);
 	Pool_PurgeStat(nobj);
 }



More information about the varnish-commit mailing list