[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