r3565 - trunk/varnish-cache/bin/varnishd

phk at projects.linpro.no phk at projects.linpro.no
Mon Feb 2 17:48:29 CET 2009


Author: phk
Date: 2009-02-02 17:48:28 +0100 (Mon, 02 Feb 2009)
New Revision: 3565

Modified:
   trunk/varnish-cache/bin/varnishd/cache_expire.c
Log:
Close a race where VCL tries to modify the obj.ttl at the same moment
the grim reaper has taken the object off the binheap to inspect it.



Modified: trunk/varnish-cache/bin/varnishd/cache_expire.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_expire.c	2009-01-30 14:40:32 UTC (rev 3564)
+++ trunk/varnish-cache/bin/varnishd/cache_expire.c	2009-02-02 16:48:28 UTC (rev 3565)
@@ -143,6 +143,7 @@
 	CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC);
 	oe = o->objexp;
 	CHECK_OBJ_NOTNULL(oe, OBJEXP_MAGIC);
+	Lck_AssertHeld(&exp_mtx);
 
 	if (o->prefetch < 0.0) {
 		when = o->ttl + o->prefetch;
@@ -184,8 +185,9 @@
 
 	assert(o->entered != 0 && !isnan(o->entered));
 	oe->lru_stamp = o->entered;
+	Lck_Lock(&exp_mtx);
+	assert(oe->timer_idx == BINHEAP_NOIDX);
 	(void)update_object_when(o);
-	Lck_Lock(&exp_mtx);
 	binheap_insert(exp_heap, oe);
 	assert(oe->timer_idx != BINHEAP_NOIDX);
 	VTAILQ_INSERT_TAIL(&lru, oe, list);
@@ -245,7 +247,11 @@
 		return;
 	CHECK_OBJ_NOTNULL(oe, OBJEXP_MAGIC);
 	Lck_Lock(&exp_mtx);
-	if (update_object_when(o)) {
+	/*
+	 * The hang-man might have this object of the binheap while
+	 * tending to a timer.  If so, we do not muck with it here.
+	 */
+	if (oe->timer_idx != BINHEAP_NOIDX && update_object_when(o)) {
 		/*
 		 * XXX: this could possibly be optimized by shuffling
 		 * XXX: up or down, but that leaves some very nasty
@@ -332,8 +338,9 @@
 				WSL(&ww, SLT_Debug, 0, "Attempt Prefetch %u",
 				    o->xid);
 			}
+			Lck_Lock(&exp_mtx);
+			assert(oe->timer_idx == BINHEAP_NOIDX);
 			(void)update_object_when(o);
-			Lck_Lock(&exp_mtx);
 			binheap_insert(exp_heap, oe);
 			assert(oe->timer_idx != BINHEAP_NOIDX);
 			Lck_Unlock(&exp_mtx);
@@ -347,6 +354,7 @@
 			WSL(&ww, SLT_ExpKill, 0,
 			    "%u %d", o->xid, (int)(o->ttl - t));
 			Lck_Lock(&exp_mtx);
+			assert(oe->timer_idx == BINHEAP_NOIDX);
 			VTAILQ_REMOVE(&lru, o->objexp, list);
 			oe->on_lru = 0;
 			VSL_stats->n_expired++;



More information about the varnish-commit mailing list