[master] 6c9c80e Start to make all the Obj* functions overridable by stevedores, begining with the ObjIter set. Have them consistently take objcore as first argument and replace "struct objiter*" into a void* cookie of the stevedores choice.

Poul-Henning Kamp phk at FreeBSD.org
Mon Sep 15 22:25:59 CEST 2014


commit 6c9c80e2ef28e9365b729892578c3f0a5404dfe7
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Mon Sep 15 20:24:39 2014 +0000

    Start to make all the Obj* functions overridable by stevedores,
    begining with the ObjIter set.  Have them consistently take objcore
    as first argument and replace "struct objiter*" into a void* cookie
    of the stevedores choice.

diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h
index f463397..62e3485 100644
--- a/bin/varnishd/cache/cache.h
+++ b/bin/varnishd/cache/cache.h
@@ -113,7 +113,6 @@ struct mempool;
 struct objcore;
 struct object;
 struct objhead;
-struct objiter;
 struct pool;
 struct poolparam;
 struct req;
@@ -991,9 +990,9 @@ enum objiter_status {
 	OIS_STREAM,
 	OIS_ERROR,
 };
-struct objiter *ObjIterBegin(struct worker *, struct objcore *);
-enum objiter_status ObjIter(struct objiter *, void **, ssize_t *);
-void ObjIterEnd(struct objiter **);
+void *ObjIterBegin(struct objcore *, struct worker *);
+enum objiter_status ObjIter(struct objcore *, void *, void **, ssize_t *);
+void ObjIterEnd(struct objcore *, void **);
 int ObjGetSpace(struct objcore *, struct vsl_log *vsl,
     struct dstat *, ssize_t *sz, uint8_t **ptr);
 void ObjExtend(struct objcore *, struct dstat *, ssize_t l);
diff --git a/bin/varnishd/cache/cache_esi_deliver.c b/bin/varnishd/cache/cache_esi_deliver.c
index d272bfc..e315e82 100644
--- a/bin/varnishd/cache/cache_esi_deliver.c
+++ b/bin/varnishd/cache/cache_esi_deliver.c
@@ -261,7 +261,7 @@ ESI_Deliver(struct req *req)
 	ssize_t dl;
 	const void *dp;
 	int i;
-	struct objiter *oi;
+	void *oi;
 	enum objiter_status ois;
 	void *sp;
 	uint8_t *pp;
@@ -309,8 +309,8 @@ ESI_Deliver(struct req *req)
 		AZ(dl);
 	}
 
-	oi = ObjIterBegin(req->wrk, req->objcore);
-	ois = ObjIter(oi, &sp, &sl);
+	oi = ObjIterBegin(req->objcore, req->wrk);
+	ois = ObjIter(req->objcore, oi, &sp, &sl);
 	assert(ois != OIS_ERROR);
 	pp = sp;
 
@@ -380,7 +380,8 @@ ESI_Deliver(struct req *req)
 				}
 				pp += l2;
 				if (sl == 0) {
-					ois = ObjIter(oi, &sp, &sl);
+					ois = ObjIter(req->objcore, oi,
+					    &sp, &sl);
 					assert(ois != OIS_ERROR);
 					pp = sp;
 				}
@@ -404,7 +405,8 @@ ESI_Deliver(struct req *req)
 				l -= l2;
 				pp += l2;
 				if (sl == 0) {
-					ois = ObjIter(oi, &sp, &sl);
+					ois = ObjIter(req->objcore, oi,
+					    &sp, &sl);
 					assert(ois != OIS_ERROR);
 					pp = sp;
 				}
@@ -455,7 +457,7 @@ ESI_Deliver(struct req *req)
 		req->resp_bodybytes += WRW_Write(req->wrk, tailbuf, 13);
 	}
 	(void)WRW_Flush(req->wrk);
-	ObjIterEnd(&oi);
+	ObjIterEnd(req->objcore, &oi);
 }
 
 /*---------------------------------------------------------------------
@@ -475,7 +477,7 @@ ESI_DeliverChild(struct req *req)
 	uint8_t *pp;
 	uint8_t tailbuf[8];
 	enum objiter_status ois;
-	struct objiter *oi;
+	void *oi;
 	void *sp;
 	ssize_t sl, ll, dl;
 
@@ -483,13 +485,13 @@ ESI_DeliverChild(struct req *req)
 	CHECK_OBJ_NOTNULL(req->objcore, OBJCORE_MAGIC);
 
 	if (!ObjCheckFlag(req->objcore, &req->wrk->stats, OF_GZIPED)) {
-		oi = ObjIterBegin(req->wrk, req->objcore);
+		oi = ObjIterBegin(req->objcore, req->wrk);
 		do {
-			ois = ObjIter(oi, &sp, &sl);
+			ois = ObjIter(req->objcore, oi, &sp, &sl);
 			if (sl > 0)
 				ved_pretend_gzip(req, sp, sl);
 		} while (ois == OIS_DATA || ois == OIS_STREAM);
-		ObjIterEnd(&oi);
+		ObjIterEnd(req->objcore, &oi);
 		return;
 	}
 	/*
@@ -523,9 +525,9 @@ ESI_DeliverChild(struct req *req)
 	dbits = (void*)WS_Alloc(req->ws, 8);
 	AN(dbits);
 	ll = 0;
-	oi = ObjIterBegin(req->wrk, req->objcore);
+	oi = ObjIterBegin(req->objcore, req->wrk);
 	do {
-		ois = ObjIter(oi, &sp, &sl);
+		ois = ObjIter(req->objcore, oi, &sp, &sl);
 		pp = sp;
 		if (sl > 0) {
 			/* Skip over the GZIP header */
@@ -651,7 +653,7 @@ ESI_DeliverChild(struct req *req)
 			}
 		}
 	} while (ois == OIS_DATA || ois == OIS_STREAM);
-	ObjIterEnd(&oi);
+	ObjIterEnd(req->objcore, &oi);
 
 	icrc = vle32dec(tailbuf);
 	ilen = vle32dec(tailbuf + 4);
diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c
index b245b82..56e4eed 100644
--- a/bin/varnishd/cache/cache_fetch.c
+++ b/bin/varnishd/cache/cache_fetch.c
@@ -661,7 +661,7 @@ vbf_stp_fetch(struct worker *wrk, struct busyobj *bo)
 static enum fetch_step
 vbf_stp_condfetch(struct worker *wrk, struct busyobj *bo)
 {
-	struct objiter *oi;
+	void *oi;
 	void *sp;
 	ssize_t sl, al, l;
 	uint8_t *ptr;
@@ -686,9 +686,9 @@ vbf_stp_condfetch(struct worker *wrk, struct busyobj *bo)
 
 	al = 0;
 	ol = ObjGetLen(bo->ims_oc, bo->stats);
-	oi = ObjIterBegin(wrk, bo->ims_oc);
+	oi = ObjIterBegin(bo->ims_oc, wrk);
 	do {
-		ois = ObjIter(oi, &sp, &sl);
+		ois = ObjIter(bo->ims_oc, oi, &sp, &sl);
 		while (sl > 0) {
 			l = ol - al;
 			if (VFP_GetStorage(bo->vfc, &l, &ptr) != VFP_OK)
@@ -702,7 +702,7 @@ vbf_stp_condfetch(struct worker *wrk, struct busyobj *bo)
 			sl -= l;
 		}
 	} while (!bo->vfc->failed && (ois == OIS_DATA || ois == OIS_STREAM));
-	ObjIterEnd(&oi);
+	ObjIterEnd(bo->ims_oc, &oi);
 	if (bo->vfc->failed)
 		return (F_STP_FAIL);
 
diff --git a/bin/varnishd/cache/cache_http1_deliver.c b/bin/varnishd/cache/cache_http1_deliver.c
index e4d26b1..1d21ecc 100644
--- a/bin/varnishd/cache/cache_http1_deliver.c
+++ b/bin/varnishd/cache/cache_http1_deliver.c
@@ -169,16 +169,16 @@ v1d_WriteDirObj(struct req *req)
 {
 	enum objiter_status ois;
 	ssize_t len;
-	struct objiter *oi;
+	void *oi;
 	void *ptr;
 
 	CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
 
-	oi = ObjIterBegin(req->wrk, req->objcore);
+	oi = ObjIterBegin(req->objcore, req->wrk);
 	XXXAN(oi);
 
 	do {
-		ois = ObjIter(oi, &ptr, &len);
+		ois = ObjIter(req->objcore, oi, &ptr, &len);
 		switch(ois) {
 		case OIS_DONE:
 			AZ(len);
@@ -196,7 +196,7 @@ v1d_WriteDirObj(struct req *req)
 		}
 	} while (ois == OIS_DATA || ois == OIS_STREAM);
 	(void)VDP_bytes(req, VDP_FINISH,  NULL, 0);
-	ObjIterEnd(&oi);
+	ObjIterEnd(req->objcore, &oi);
 	return (ois);
 }
 
diff --git a/bin/varnishd/cache/cache_obj.c b/bin/varnishd/cache/cache_obj.c
index 6013818..af69ed3 100644
--- a/bin/varnishd/cache/cache_obj.c
+++ b/bin/varnishd/cache/cache_obj.c
@@ -67,7 +67,19 @@ obj_getobj(struct objcore *oc, struct dstat *ds)
 	return (m->getobj(oc, ds));
 }
 
-/*--------------------------------------------------------------------
+/*====================================================================
+ * ObjIterBegin()
+ * ObjIter()
+ * ObjIterEnd()
+ *
+ * These three allow iteration over the body of an object.
+ * The ObjIterBegin() returns a magic cookie which must be passed to
+ * ObjIter() and which ObjIterEnd() will obliterate again.
+ *
+ * These functions get slightly complicated due to unbusy but not
+ * yet completed objects (ie: when streaming).  Exactly how they
+ * interact with ObjExtend(), especially with respect to locking,
+ * is entirely up to the implementation.
  */
 
 struct objiter {
@@ -81,11 +93,15 @@ struct objiter {
 	ssize_t				len;
 };
 
-struct objiter *
-ObjIterBegin(struct worker *wrk, struct objcore *oc)
+void *
+ObjIterBegin(struct objcore *oc, struct worker *wrk)
 {
 	struct objiter *oi;
 	struct object *obj;
+	const struct storeobj_methods *om = obj_getmethods(oc);
+
+	if (om->objiterbegin != NULL)
+		return (om->objiterbegin(oc, wrk));
 
 	CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
 	obj = obj_getobj(oc, &wrk->stats);
@@ -102,12 +118,17 @@ ObjIterBegin(struct worker *wrk, struct objcore *oc)
 }
 
 enum objiter_status
-ObjIter(struct objiter *oi, void **p, ssize_t *l)
+ObjIter(struct objcore *oc, void *oix, void **p, ssize_t *l)
 {
+	struct objiter *oi;
 	ssize_t ol;
 	ssize_t nl;
+	const struct storeobj_methods *om = obj_getmethods(oc);
 
-	CHECK_OBJ_NOTNULL(oi, OBJITER_MAGIC);
+	if (om->objiter != NULL)
+		return (om->objiter(oc, oix, p, l));
+
+	CAST_OBJ_NOTNULL(oi, oix, OBJITER_MAGIC);
 	CHECK_OBJ_NOTNULL(oi->obj, OBJECT_MAGIC);
 	AN(p);
 	AN(l);
@@ -165,19 +186,27 @@ ObjIter(struct objiter *oi, void **p, ssize_t *l)
 }
 
 void
-ObjIterEnd(struct objiter **oi)
+ObjIterEnd(struct objcore *oc, void **oix)
 {
+	struct objiter *oi;
+	const struct storeobj_methods *om = obj_getmethods(oc);
+
+	if (om->objiterend != NULL) {
+		om->objiterend(oc, oix);
+		return;
+	}
 
-	AN(oi);
-	CHECK_OBJ_NOTNULL((*oi), OBJITER_MAGIC);
-	CHECK_OBJ_NOTNULL((*oi)->obj, OBJECT_MAGIC);
-	if ((*oi)->bo != NULL) {
-		if ((*oi)->oc->flags & OC_F_PASS)
-			(*oi)->bo->abandon = 1;
-		VBO_DerefBusyObj((*oi)->wrk, &(*oi)->bo);
+	AN(oc);
+	AN(oix);
+	CAST_OBJ_NOTNULL(oi, (*oix), OBJITER_MAGIC);
+	*oix = NULL;
+	CHECK_OBJ_NOTNULL(oi->obj, OBJECT_MAGIC);
+	if (oi->bo != NULL) {
+		if (oi->oc->flags & OC_F_PASS)
+			oi->bo->abandon = 1;
+		VBO_DerefBusyObj(oi->wrk, &oi->bo);
 	}
-	FREE_OBJ((*oi));
-	*oi = NULL;
+	FREE_OBJ(oi);
 }
 
 /*--------------------------------------------------------------------
diff --git a/bin/varnishd/cache/cache_req_body.c b/bin/varnishd/cache/cache_req_body.c
index 6eb2590..dadd25c 100644
--- a/bin/varnishd/cache/cache_req_body.c
+++ b/bin/varnishd/cache/cache_req_body.c
@@ -54,7 +54,7 @@ VRB_Iterate(struct req *req, req_body_iter_f *func, void *priv)
 	int i;
 	struct vfp_ctx *vfc;
 	enum vfp_status vfps = VFP_ERROR;
-	struct objiter *oi;
+	void *oi;
 	enum objiter_status ois;
 
 	CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
@@ -62,14 +62,14 @@ VRB_Iterate(struct req *req, req_body_iter_f *func, void *priv)
 
 	switch(req->req_body_status) {
 	case REQ_BODY_CACHED:
-		oi = ObjIterBegin(req->wrk, req->body_oc);
+		oi = ObjIterBegin(req->body_oc, req->wrk);
 		AN(oi);
 		do {
-			ois = ObjIter(oi, &p, &l);
+			ois = ObjIter(req->body_oc, oi, &p, &l);
 			if (l > 0 && func(req, priv, p, l))
 				break;
 		} while (ois == OIS_DATA);
-		ObjIterEnd(&oi);
+		ObjIterEnd(req->body_oc, &oi);
 		return (ois == OIS_DONE ? 0 : -1);
 	case REQ_BODY_NONE:
 		return (0);
diff --git a/bin/varnishd/storage/storage.h b/bin/varnishd/storage/storage.h
index 1e42e23..60faf9d 100644
--- a/bin/varnishd/storage/storage.h
+++ b/bin/varnishd/storage/storage.h
@@ -78,18 +78,44 @@ struct object {
 	struct storage		*esidata;
 };
 
-/* -------------------------------------------------------------------*/
+/* Methods on objcore ------------------------------------------------*/
 
-typedef struct object *getobj_f(struct objcore *oc, struct dstat *);
 typedef void updatemeta_f(struct objcore *oc, struct dstat *);
 typedef void freeobj_f(struct objcore *oc, struct dstat *);
 typedef struct lru *getlru_f(const struct objcore *oc);
 
+/*
+ * Stevedores can either be simple, and provide just this method:
+ */
+
+typedef struct object *getobj_f(struct objcore *oc, struct dstat *);
+
+/*
+ * Or the can be "complex" and provide all of these methods:
+ * (Described in comments in cache_obj.c)
+ */
+typedef void *objiterbegin_f(struct objcore *oc, struct worker *wrk);
+typedef enum objiter_status objiter_f(struct objcore *oc, void *oix,
+    void **p, ssize_t *l);
+typedef void objiterend_f(struct objcore *oc, void **oix);
+/* objgetspace */
+/* objtrimstore */
+/* objslim */
+/* objgetattr */
+/* objsetattr */
+/* objextend */
+/* objgetlen */
+
 struct storeobj_methods {
-	getobj_f	*getobj;
-	updatemeta_f	*updatemeta;
 	freeobj_f	*freeobj;
 	getlru_f	*getlru;
+	updatemeta_f	*updatemeta;
+
+	getobj_f	*getobj;
+
+	objiterbegin_f	*objiterbegin;
+	objiter_f	*objiter;
+	objiterend_f	*objiterend;
 };
 
 /* Prototypes --------------------------------------------------------*/



More information about the varnish-commit mailing list