r3845 - trunk/varnish-cache/bin/varnishd

phk at projects.linpro.no phk at projects.linpro.no
Sat Feb 28 22:56:49 CET 2009


Author: phk
Date: 2009-02-28 22:56:49 +0100 (Sat, 28 Feb 2009)
New Revision: 3845

Modified:
   trunk/varnish-cache/bin/varnishd/cache.h
   trunk/varnish-cache/bin/varnishd/cache_center.c
   trunk/varnish-cache/bin/varnishd/cache_fetch.c
   trunk/varnish-cache/bin/varnishd/cache_hash.c
   trunk/varnish-cache/bin/varnishd/hash_slinger.h
Log:
Postpone allocating the actual object until we have received the
headers and vcl_fetch{} has told os what to do with it.



Modified: trunk/varnish-cache/bin/varnishd/cache.h
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache.h	2009-02-28 21:21:14 UTC (rev 3844)
+++ trunk/varnish-cache/bin/varnishd/cache.h	2009-02-28 21:56:49 UTC (rev 3845)
@@ -396,6 +396,7 @@
 	struct vbe_conn		*vbe;
 	struct bereq		*bereq;
 	struct object		*obj;
+	struct objcore		*objcore;
 	struct objhead		*objhead;
 	struct VCL_conf		*vcl;
 

Modified: trunk/varnish-cache/bin/varnishd/cache_center.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_center.c	2009-02-28 21:21:14 UTC (rev 3844)
+++ trunk/varnish-cache/bin/varnishd/cache_center.c	2009-02-28 21:56:49 UTC (rev 3845)
@@ -378,6 +378,7 @@
 {
 	int i;
 	struct http *hp, *hp2;
+	struct object *o;
 	char *b;
 
 	CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
@@ -387,9 +388,6 @@
 	AN(sp->director);
 	AZ(sp->vbe);
 
-	sp->obj->xid = sp->xid;
-	WS_Assert(sp->obj->ws_o);
-
 	i = FetchHdr(sp);
 
 	/*
@@ -402,7 +400,11 @@
 		sp->err_code = 503;
 		sp->step = STP_ERROR;
 		VBE_free_bereq(&sp->bereq);
-		HSH_Drop(sp);
+		if (sp->objhead) {
+			CHECK_OBJ_NOTNULL(sp->objhead, OBJHEAD_MAGIC);
+			CHECK_OBJ_NOTNULL(sp->objcore, OBJCORE_MAGIC);
+			HSH_DerefObjCore(sp);
+		}
 		AZ(sp->obj);
 		return (0);
 	}
@@ -440,6 +442,21 @@
 
 	VCL_fetch_method(sp);
 
+	o = HSH_NewObject(sp, sp->handling != VCL_RET_DELIVER);
+
+	if (sp->objhead != NULL) {
+		CHECK_OBJ_NOTNULL(sp->objhead, OBJHEAD_MAGIC);
+		CHECK_OBJ_NOTNULL(sp->objcore, OBJCORE_MAGIC);
+		sp->objcore->obj = o;
+		o->objcore = sp->objcore;
+		o->objhead = sp->objhead;
+		sp->objhead = NULL;	/* refcnt follows pointer. */
+	}
+	sp->obj = o;
+
+	BAN_NewObj(sp->obj);
+
+	sp->obj->xid = sp->xid;
 	sp->obj->response = sp->err_code;
 	sp->obj->cacheable = sp->bereq->cacheable;
 	sp->obj->ttl = sp->bereq->ttl;
@@ -448,6 +465,7 @@
 		sp->obj->cacheable = 0;
 	sp->obj->age = sp->bereq->age;
 	sp->obj->entered = sp->bereq->entered;
+	WS_Assert(sp->obj->ws_o);
 
 	/* Filter into object */
 	hp = sp->bereq->beresp;
@@ -602,6 +620,9 @@
 
 	/* Drop our object, we won't need it */
 	HSH_Deref(sp->wrk, &sp->obj);
+	sp->objcore = NULL;
+	AZ(sp->objhead);
+	sp->objhead = NULL;
 
 	switch(sp->handling) {
 	case VCL_RET_PASS:
@@ -675,6 +696,7 @@
 		return (1);
 	}
 
+	CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
 	CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC);
 
 	/* If we inserted a new object it's a miss */
@@ -682,14 +704,8 @@
 		VSL_stats->cache_miss++;
 
 		AZ(oc->obj);
-		o = HSH_NewObject(sp, 0);
-
-		o->objhead = oh;
-		o->objcore = oc;
-		oc->obj = o;
-		sp->obj = o;
-
-		BAN_NewObj(o);
+		sp->objhead = oh;
+		sp->objcore = oc;
 		sp->step = STP_MISS;
 		return (0);
 	}
@@ -702,6 +718,8 @@
 		VSL_stats->cache_hitpass++;
 		WSP(sp, SLT_HitPass, "%u", sp->obj->xid);
 		HSH_Deref(sp->wrk, &sp->obj);
+		sp->objcore = NULL;
+		sp->objhead = NULL;
 		sp->step = STP_PASS;
 		return (0);
 	}
@@ -740,27 +758,29 @@
 {
 
 	CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
-	CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC);
 	CHECK_OBJ_NOTNULL(sp->vcl, VCL_CONF_MAGIC);
 
+	AZ(sp->obj);
+	AN(sp->objcore);
+	AN(sp->objhead);
 	http_FilterHeader(sp, HTTPH_R_FETCH);
 	VCL_miss_method(sp);
-	AZ(sp->obj->cacheable);
 	switch(sp->handling) {
 	case VCL_RET_ERROR:
-		HSH_Drop(sp);
+		HSH_DerefObjCore(sp);
 		VBE_free_bereq(&sp->bereq);
 		sp->step = STP_ERROR;
 		return (0);
 	case VCL_RET_PASS:
-		HSH_Drop(sp);
 		VBE_free_bereq(&sp->bereq);
+		HSH_DerefObjCore(sp);
 		sp->step = STP_PASS;
 		return (0);
 	case VCL_RET_FETCH:
 		sp->step = STP_FETCH;
 		return (0);
 	case VCL_RET_RESTART:
+		HSH_DerefObjCore(sp);
 		VBE_free_bereq(&sp->bereq);
 		INCOMPL();
 	default:
@@ -818,8 +838,6 @@
 	}
 	assert(sp->handling == VCL_RET_PASS);
 	sp->acct_req.pass++;
-	HSH_Prealloc(sp);
-	sp->obj = HSH_NewObject(sp, 1);
 	sp->sendbody = 1;
 	sp->step = STP_FETCH;
 	return (0);

Modified: trunk/varnish-cache/bin/varnishd/cache_fetch.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_fetch.c	2009-02-28 21:21:14 UTC (rev 3844)
+++ trunk/varnish-cache/bin/varnishd/cache_fetch.c	2009-02-28 21:56:49 UTC (rev 3845)
@@ -319,11 +319,14 @@
 
 	CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
 	CHECK_OBJ_NOTNULL(sp->wrk, WORKER_MAGIC);
-	CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC);
 	CHECK_OBJ_NOTNULL(sp->bereq, BEREQ_MAGIC);
 	AN(sp->director);
-	if (sp->obj->objcore != NULL)		/* pass has no objcore */
-		AN(ObjIsBusy(sp->obj));
+	AZ(sp->obj);
+	if (sp->objcore != NULL) {		/* pass has no objcore */
+		CHECK_OBJ_NOTNULL(sp->objcore, OBJCORE_MAGIC);
+		AN(sp->objhead);		/* details in hash_slinger.h */
+		AN(sp->objcore->flags & OC_F_BUSY);
+	}
 	AN(sp->bereq);
 
 	/* Transmit request */

Modified: trunk/varnish-cache/bin/varnishd/cache_hash.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_hash.c	2009-02-28 21:21:14 UTC (rev 3844)
+++ trunk/varnish-cache/bin/varnishd/cache_hash.c	2009-02-28 21:56:49 UTC (rev 3845)
@@ -308,6 +308,8 @@
 	busy_oc = NULL;
 	grace_oc = NULL;
 	VTAILQ_FOREACH(oc, &oh->objcs, list) {
+		/* Must be at least our own ref + the objcore we examine */
+		assert(oh->refcnt > 1);
 		CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
 
 		if (oc->flags & OC_F_BUSY) {
@@ -359,6 +361,7 @@
 		o->refcnt++;
 		if (o->hits < INT_MAX)
 			o->hits++;
+		assert(oh->refcnt > 1);
 		Lck_Unlock(&oh->mtx);
 		assert(hash->deref(oh));
 		*poh = oh;
@@ -454,10 +457,10 @@
 		Lck_Lock(&oh->mtx);
 	}
 	o->objcore->flags &= ~OC_F_BUSY;
-	if (oh != NULL)
+	if (oh != NULL) {
 		hsh_rush(oh);
-	if (oh != NULL)
 		Lck_Unlock(&oh->mtx);
+	}
 }
 
 void
@@ -475,6 +478,29 @@
 }
 
 void
+HSH_DerefObjCore(struct sess *sp)
+{
+	struct objhead *oh;
+	struct objcore *oc;
+
+	CHECK_OBJ_NOTNULL(sp->objhead, OBJHEAD_MAGIC);
+	CHECK_OBJ_NOTNULL(sp->objcore, OBJCORE_MAGIC);
+
+	oh = sp->objhead;
+	sp->objhead = NULL;
+	oc = sp->objcore;
+	sp->objcore = NULL;
+
+	Lck_Lock(&oh->mtx);
+	VTAILQ_REMOVE(&oh->objcs, oc, list);
+	Lck_Unlock(&oh->mtx);
+	assert(oh->refcnt > 0);
+	if (hash->deref(oh))
+		return;
+	HSH_DeleteObjHead(sp->wrk, oh);
+}
+
+void
 HSH_Deref(const struct worker *w, struct object **oo)
 {
 	struct object *o;
@@ -492,7 +518,7 @@
 		assert(o->refcnt > 0);
 		r = --o->refcnt;
 	} else {
-		CHECK_OBJ(oh, OBJHEAD_MAGIC);
+		CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC);
 
 		oc = o->objcore;
 		CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
@@ -525,6 +551,7 @@
 		STV_free(o->objstore);
 	else
 		FREE_OBJ(o);
+	o = NULL;
 	w->stats->n_object--;
 
 	if (oh == NULL) {
@@ -540,6 +567,7 @@
 	HSH_DeleteObjHead(w, oh);
 }
 
+
 void
 HSH_Init(void)
 {

Modified: trunk/varnish-cache/bin/varnishd/hash_slinger.h
===================================================================
--- trunk/varnish-cache/bin/varnishd/hash_slinger.h	2009-02-28 21:21:14 UTC (rev 3844)
+++ trunk/varnish-cache/bin/varnishd/hash_slinger.h	2009-02-28 21:56:49 UTC (rev 3845)
@@ -63,6 +63,7 @@
 void HSH_Init(void);
 void HSH_AddString(struct sess *sp, const char *str);
 void HSH_Prepare(struct sess *sp, unsigned hashcount);
+void HSH_DerefObjCore(struct sess *sp);
 
 
 #ifdef VARNISH_CACHE_CHILD



More information about the varnish-commit mailing list