r5558 - trunk/varnish-cache/bin/varnishd

phk at varnish-cache.org phk at varnish-cache.org
Sat Nov 20 22:40:43 CET 2010


Author: phk
Date: 2010-11-20 22:40:42 +0100 (Sat, 20 Nov 2010)
New Revision: 5558

Modified:
   trunk/varnish-cache/bin/varnishd/cache_center.c
   trunk/varnish-cache/bin/varnishd/stevedore.c
   trunk/varnish-cache/bin/varnishd/stevedore.h
Log:
This is really complicated to explain, but quite simple behind all
the gunk:

A persistent storage method, needs to know about "struct object" in
addition to regular storage allocations, in order to track ttl and
ban information etc.

Therefore, when we create an object, we call into the stevedore.c
to do so with STV_NewObject(), it picks an stevedore, and calls
the ->allocobj() method, which will allocate some storage, call
STV_MkObject() to turn it into an object, which can then be
fondled, before passing it back to STV_NewObject() an from there
to cache_center.c::cnt_fetch().

Non-persistent stevedores, don't define ->allocobj() and when
initialized by stevedore.c, get a suitable default function.

XXX: next steps, remove objcore argument from stv->alloc() and
remove stv->object() method entirely, now that we have a proper
calling order.





Modified: trunk/varnish-cache/bin/varnishd/cache_center.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_center.c	2010-11-19 06:51:11 UTC (rev 5557)
+++ trunk/varnish-cache/bin/varnishd/cache_center.c	2010-11-20 21:40:42 UTC (rev 5558)
@@ -557,7 +557,8 @@
 		AZ(sp->objcore);
 	}
 
-	l = http_EstimateWS(sp->wrk->beresp, sp->pass ? HTTPH_R_PASS : HTTPH_A_INS, &nhttp);
+	l = http_EstimateWS(sp->wrk->beresp,
+	    sp->pass ? HTTPH_R_PASS : HTTPH_A_INS, &nhttp);
 
 	if (vary != NULL)
 		l += varyl;
@@ -571,18 +572,8 @@
 	 */
 
 	sp->obj = STV_NewObject(sp, l, sp->wrk->ttl, nhttp);
+	CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC);
 
-	if (sp->objhead != NULL) {
-		CHECK_OBJ_NOTNULL(sp->objhead, OBJHEAD_MAGIC);
-		CHECK_OBJ_NOTNULL(sp->objcore, OBJCORE_MAGIC);
-		sp->objcore->priv = sp->obj; /* XXX */
-		sp->obj->objcore = sp->objcore;
-		sp->objcore->objhead = sp->objhead;
-		sp->objhead = NULL;	/* refcnt follows pointer. */
-		sp->objcore = NULL;	/* refcnt follows pointer. */
-		BAN_NewObj(sp->obj);
-	}
-
 	if (vary != NULL) {
 		sp->obj->vary =
 		    (void *)WS_Alloc(sp->obj->http->ws, varyl);
@@ -609,7 +600,8 @@
 
 	hp2->logtag = HTTP_Obj;
 	http_CopyResp(hp2, hp);
-	http_FilterFields(sp->wrk, sp->fd, hp2, hp, sp->pass ? HTTPH_R_PASS : HTTPH_A_INS);
+	http_FilterFields(sp->wrk, sp->fd, hp2, hp,
+	    sp->pass ? HTTPH_R_PASS : HTTPH_A_INS);
 	http_CopyHome(sp->wrk, sp->fd, hp2);
 
 	if (http_GetHdr(hp, H_Last_Modified, &b))
@@ -633,8 +625,13 @@
 		return (0);
 	}
 
-	if (sp->wrk->cacheable)
+	if (sp->wrk->cacheable) {
+		/*
+		 * Needs ttl & ban to be in order.
+		 * XXX call oc->updatemeta() instead ?
+		 */
 		STV_Object(sp);
+	}
 
 	if (sp->wrk->do_esi)
 		ESI_Parse(sp);

Modified: trunk/varnish-cache/bin/varnishd/stevedore.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/stevedore.c	2010-11-19 06:51:11 UTC (rev 5557)
+++ trunk/varnish-cache/bin/varnishd/stevedore.c	2010-11-20 21:40:42 UTC (rev 5558)
@@ -53,7 +53,7 @@
 
 static const struct stevedore * volatile stv_next;
 
-static const struct stevedore *stv_transient;
+static struct stevedore *stv_transient;
 
 /*********************************************************************
  * NB! Dirty trick alert:
@@ -143,46 +143,52 @@
 }
 
 
-/*********************************************************************/
+/*********************************************************************
+ * Structure used to transport internal knowledge from STV_NewObject()
+ * to STV_MkObject().  Nobody else should mess with this struct.
+ */
 
+struct stv_objsecrets {
+	unsigned	magic;
+#define STV_OBJ_SECRETES_MAGIC	0x78c87247
+	unsigned 	nhttp;
+	unsigned 	lhttp;
+	unsigned	wsl;
+	double 		ttl;
+};
+
+/*********************************************************************
+ * This function is called by stevedores ->allocobj() method, which
+ * very often will be stv_default_allocobj() below, to convert a slab
+ * of storage into object which the stevedore can then register in its
+ * internal state, before returning it to STV_NewObject().
+ * As you probably guessed: All this for persistence.
+ */
+
 struct object *
-STV_NewObject(const struct sess *sp, unsigned wsl, double ttl, unsigned nhttp)
+STV_MkObject(struct sess *sp, void *ptr, unsigned ltot,
+    struct stv_objsecrets *soc)
 {
 	struct object *o;
-	struct storage *st;
-	unsigned lhttp;
+	unsigned l;
 
-	(void)ttl;
-	assert(wsl > 0);
-	wsl = PRNDUP(wsl);
+	CHECK_OBJ_NOTNULL(soc, STV_OBJ_SECRETES_MAGIC);
 
-	lhttp = HTTP_estimate(nhttp);
-	lhttp = PRNDUP(lhttp);
+	assert(PAOK(ptr));
+	assert(ltot >= sizeof *o + soc->lhttp + soc->wsl);
 
-	if (!sp->wrk->cacheable) {
-		o = malloc(sizeof *o + wsl + lhttp);
-		XXXAN(o);
-		st = NULL;
-	} else {
-		st = stv_alloc(sp, sizeof *o + wsl + lhttp, sp->objcore);
-		XXXAN(st);
-		xxxassert(st->space >= (sizeof *o + wsl + lhttp));
-
-		st->len = st->space;
-
-		o = (void *)st->ptr; /* XXX: align ? */
-
-		wsl = PRNDDN(st->space - (sizeof *o + lhttp));
-	}
-
+	o = ptr; 
 	memset(o, 0, sizeof *o);
 	o->magic = OBJECT_MAGIC;
 
-	assert(PAOK(wsl));
-	assert(PAOK(lhttp));
+	l = PRNDDN(ltot - (sizeof *o + soc->lhttp));
+	assert(l >= soc->wsl);
 
-	o->http = HTTP_create(o + 1, nhttp);
-	WS_Init(o->ws_o, "obj", (char *)(o + 1) + lhttp, wsl);
+	assert(PAOK(soc->wsl));
+	assert(PAOK(soc->lhttp));
+
+	o->http = HTTP_create(o + 1, soc->nhttp);
+	WS_Init(o->ws_o, "obj", (char *)(o + 1) + soc->lhttp, soc->wsl);
 	WS_Assert(o->ws_o);
 
 	http_Setup(o->http, o->ws_o);
@@ -191,10 +197,78 @@
 	o->entered = NAN;
 	VTAILQ_INIT(&o->store);
 	sp->wrk->stats.n_object++;
+
+	if (sp->objhead != NULL) {
+		CHECK_OBJ_NOTNULL(sp->objhead, OBJHEAD_MAGIC);
+		CHECK_OBJ_NOTNULL(sp->objcore, OBJCORE_MAGIC);
+		sp->objcore->priv = o; /* XXX */
+		o->objcore = sp->objcore;
+		sp->objcore->objhead = sp->objhead;
+		sp->objhead = NULL;     /* refcnt follows pointer. */
+		sp->objcore = NULL;     /* refcnt follows pointer. */
+		BAN_NewObj(o);
+	}
+	return (o);
+}
+
+/*********************************************************************
+ * This is the default ->allocobj() which all stevedores who do not
+ * implement persistent storage can rely on.
+ */
+
+static struct object *
+stv_default_allocobj(struct stevedore *stv, struct sess *sp, unsigned ltot,
+    struct stv_objsecrets *soc)
+{
+	struct object *o;
+	struct storage *st;
+
+	(void)stv;		/* XXX */
+	CHECK_OBJ_NOTNULL(soc, STV_OBJ_SECRETES_MAGIC);
+	st = stv_alloc(sp, ltot, sp->objcore);
+	XXXAN(st);
+	xxxassert(st->space >= ltot);
+	ltot = st->len = st->space;
+	o = STV_MkObject(sp, st->ptr, ltot, soc);
+	CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC);
 	o->objstore = st;
 	return (o);
 }
 
+/*********************************************************************/
+
+struct object *
+STV_NewObject(struct sess *sp, unsigned wsl, double ttl, unsigned nhttp)
+{
+	struct object *o;
+	struct stevedore *stv;
+	unsigned lhttp, ltot;
+	struct stv_objsecrets soc;
+
+	assert(wsl > 0);
+	wsl = PRNDUP(wsl);
+
+	lhttp = HTTP_estimate(nhttp);
+	lhttp = PRNDUP(lhttp);
+
+	soc.magic = STV_OBJ_SECRETES_MAGIC;
+	soc.nhttp = nhttp;
+	soc.lhttp = lhttp;
+	soc.wsl = wsl;
+	soc.ttl = ttl;
+
+	ltot = sizeof *o + wsl + lhttp;
+
+	if (!sp->wrk->cacheable)
+		stv = stv_transient;
+	else
+		stv = stv_pick_stevedore();
+	AN(stv->allocobj);
+	o = stv->allocobj(stv, sp, ltot, &soc);
+	CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC);
+	return (o);
+}
+
 /*---------------------------------------------------------------------
  * Default objcore methods
  */
@@ -361,6 +435,8 @@
 	*stv = *stv2;
 	AN(stv->name);
 	AN(stv->alloc);
+	if (stv->allocobj == NULL)
+		stv->allocobj = stv_default_allocobj;
 
 	if (p == NULL)
 		bprintf(stv->ident, "s%u", seq++);

Modified: trunk/varnish-cache/bin/varnishd/stevedore.h
===================================================================
--- trunk/varnish-cache/bin/varnishd/stevedore.h	2010-11-19 06:51:11 UTC (rev 5557)
+++ trunk/varnish-cache/bin/varnishd/stevedore.h	2010-11-20 21:40:42 UTC (rev 5558)
@@ -34,6 +34,7 @@
 struct iovec;
 struct object;
 struct objcore;
+struct stv_objsecrets;
 
 typedef void storage_init_f(struct stevedore *, int ac, char * const *av);
 typedef void storage_open_f(const struct stevedore *);
@@ -42,6 +43,8 @@
 typedef void storage_trim_f(struct storage *, size_t size);
 typedef void storage_free_f(struct storage *);
 typedef void storage_object_f(const struct sess *sp);
+typedef struct object *storage_allocobj_f(struct stevedore *, struct sess *sp,
+    unsigned ltot, struct stv_objsecrets *);
 typedef void storage_close_f(const struct stevedore *);
 
 
@@ -57,6 +60,7 @@
 	storage_free_f		*free;		/* --//-- */
 	storage_object_f	*object;	/* --//-- */
 	storage_close_f		*close;		/* --//-- */
+	storage_allocobj_f	*allocobj;	/* --//-- */
 
 	struct lru		*lru;
 
@@ -67,7 +71,10 @@
 	char			ident[16];	/* XXX: match vsm_chunk.ident */
 };
 
-struct object *STV_NewObject(const struct sess *sp, unsigned len, double ttl,
+struct object *STV_MkObject(struct sess *sp, void *ptr, unsigned ltot,
+    struct stv_objsecrets *soc);
+
+struct object *STV_NewObject(struct sess *sp, unsigned len, double ttl,
     unsigned nhttp);
 struct storage *STV_alloc(const struct sess *sp, size_t size);
 void STV_trim(struct storage *st, size_t size);




More information about the varnish-commit mailing list