r3727 - branches/2.0/varnish-cache/bin/varnishd

tfheen at projects.linpro.no tfheen at projects.linpro.no
Tue Feb 10 16:10:04 CET 2009


Author: tfheen
Date: 2009-02-10 16:10:04 +0100 (Tue, 10 Feb 2009)
New Revision: 3727

Modified:
   branches/2.0/varnish-cache/bin/varnishd/cache_expire.c
Log:
Merge r3545: Don't modify the obj_timer_when field outside the binheap lock.

This hopefully finaly lays the sporadic
        assert(oe2->timer_when >= oe->timer_when);
panics to rest.



Modified: branches/2.0/varnish-cache/bin/varnishd/cache_expire.c
===================================================================
--- branches/2.0/varnish-cache/bin/varnishd/cache_expire.c	2009-02-10 15:06:31 UTC (rev 3726)
+++ branches/2.0/varnish-cache/bin/varnishd/cache_expire.c	2009-02-10 15:10:04 UTC (rev 3727)
@@ -133,27 +133,34 @@
  * When & why does the timer fire for this object ?
  */
 
-static void
+static int
 update_object_when(const struct object *o)
 {
 	struct objexp *oe;
+	double when;
+	const char *what;
 
 	CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC);
 	oe = o->objexp;
 	CHECK_OBJ_NOTNULL(oe, OBJEXP_MAGIC);
 
 	if (o->prefetch < 0.0) {
-		oe->timer_when = o->ttl + o->prefetch;
-		oe->timer_what = tmr_prefetch;
+		when = o->ttl + o->prefetch;
+		what = tmr_prefetch;
 	} else if (o->prefetch > 0.0) {
 		assert(o->prefetch <= o->ttl);
-		oe->timer_when = o->prefetch;
-		oe->timer_what = tmr_prefetch;
+		when = o->prefetch;
+		what = tmr_prefetch;
 	} else {
-		oe->timer_when = o->ttl + HSH_Grace(o->grace);
-		oe->timer_what = tmr_ttl;
+		when = o->ttl + HSH_Grace(o->grace);
+		what = tmr_ttl;
 	}
-	assert(!isnan(oe->timer_when));
+	assert(!isnan(when));
+	oe->timer_what = what;
+	if (when == oe->timer_when)
+		return (0);
+	oe->timer_when = when;
+	return (1);
 }
 
 /*--------------------------------------------------------------------
@@ -237,13 +244,20 @@
 	if (oe == NULL)
 		return;
 	CHECK_OBJ_NOTNULL(oe, OBJEXP_MAGIC);
-	update_object_when(o);
 	Lck_Lock(&exp_mtx);
-	assert(oe->timer_idx != BINHEAP_NOIDX);
-	binheap_delete(exp_heap, oe->timer_idx); /* XXX: binheap_shuffle() ? */
-	assert(oe->timer_idx == BINHEAP_NOIDX);
-	binheap_insert(exp_heap, oe);
-	assert(oe->timer_idx != BINHEAP_NOIDX);
+	if (update_object_when(o)) {
+		/*
+		 * XXX: this could possibly be optimized by shuffling
+		 * XXX: up or down, but that leaves some very nasty
+		 * XXX: corner cases, such as shuffling all the way
+		 * XXX: down the left half, then back up the right half.
+		 */
+		assert(oe->timer_idx != BINHEAP_NOIDX);
+		binheap_delete(exp_heap, oe->timer_idx);
+		assert(oe->timer_idx == BINHEAP_NOIDX);
+		binheap_insert(exp_heap, oe);
+		assert(oe->timer_idx != BINHEAP_NOIDX);
+	}
 	Lck_Unlock(&exp_mtx);
 }
 



More information about the varnish-commit mailing list