[master] 78be839 Give ObjIterate() a "final" argument, to indicate that storage can be released after the iteration.

Poul-Henning Kamp phk at FreeBSD.org
Sat Mar 12 01:29:04 CET 2016


commit 78be839b94fc87a650d60403d4d65e50b0f0217d
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Fri Mar 11 23:26:44 2016 +0000

    Give ObjIterate() a "final" argument, to indicate that storage
    can be released after the iteration.
    
    Implement the non-streaming case of final.

diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h
index b01fd66..44f1c81 100644
--- a/bin/varnishd/cache/cache.h
+++ b/bin/varnishd/cache/cache.h
@@ -861,7 +861,7 @@ struct objcore * ObjNew(struct worker *);
 void ObjDestroy(struct worker *, struct objcore **);
 typedef int objiterate_f(void *priv, int flush, const void *ptr, ssize_t len);
 int ObjIterate(struct worker *, struct objcore *,
-    void *priv, objiterate_f *func);
+    void *priv, objiterate_f *func, int final);
 int ObjGetSpace(struct worker *, struct objcore *, ssize_t *sz, uint8_t **ptr);
 void ObjExtend(struct worker *, struct objcore *, ssize_t l);
 uint64_t ObjWaitExtend(const struct worker *, const struct objcore *,
diff --git a/bin/varnishd/cache/cache_deliver_proc.c b/bin/varnishd/cache/cache_deliver_proc.c
index 4f2af67..343852d 100644
--- a/bin/varnishd/cache/cache_deliver_proc.c
+++ b/bin/varnishd/cache/cache_deliver_proc.c
@@ -126,5 +126,6 @@ VDP_DeliverObj(struct req *req)
 {
 
 	CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
-	return (ObjIterate(req->wrk, req->objcore, req, vdp_objiterator));
+	return (ObjIterate(req->wrk, req->objcore, req, vdp_objiterator,
+	    req->objcore->flags & OC_F_PRIVATE ? 1 : 0));
 }
diff --git a/bin/varnishd/cache/cache_esi_deliver.c b/bin/varnishd/cache/cache_esi_deliver.c
index 5f4326f..ec8c309 100644
--- a/bin/varnishd/cache/cache_esi_deliver.c
+++ b/bin/varnishd/cache/cache_esi_deliver.c
@@ -722,7 +722,7 @@ ved_stripgzip(struct req *req, const struct boc *boc)
 	dbits = WS_Alloc(req->ws, 8);
 	AN(dbits);
 	foo.dbits = dbits;
-	(void)ObjIterate(req->wrk, req->objcore, &foo, ved_objiterate);
+	(void)ObjIterate(req->wrk, req->objcore, &foo, ved_objiterate, 0);
 	/* XXX: error check ?? */
 	(void)ved_bytes(req, foo.preq, VDP_FLUSH, NULL, 0);
 
diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c
index 5c6084d..fb7c638 100644
--- a/bin/varnishd/cache/cache_fetch.c
+++ b/bin/varnishd/cache/cache_fetch.c
@@ -769,7 +769,7 @@ vbf_stp_condfetch(struct worker *wrk, struct busyobj *bo)
 		ObjSetState(wrk, bo->fetch_objcore, BOS_STREAM);
 	}
 
-	if (ObjIterate(wrk, bo->stale_oc, bo, vbf_objiterator))
+	if (ObjIterate(wrk, bo->stale_oc, bo, vbf_objiterator, 0))
 		(void)VFP_Error(bo->vfc, "Template object failed");
 
 	if (bo->stale_oc->flags & OC_F_FAILED)
diff --git a/bin/varnishd/cache/cache_obj.c b/bin/varnishd/cache/cache_obj.c
index 37ed6f5..46fd0fc 100644
--- a/bin/varnishd/cache/cache_obj.c
+++ b/bin/varnishd/cache/cache_obj.c
@@ -178,14 +178,14 @@ ObjDestroy(struct worker *wrk, struct objcore **p)
 
 int
 ObjIterate(struct worker *wrk, struct objcore *oc,
-    void *priv, objiterate_f *func)
+    void *priv, objiterate_f *func, int final)
 {
 	const struct obj_methods *om = obj_getmethods(oc);
 
 	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
 	AN(func);
 	AN(om->objiterator);
-	return (om->objiterator(wrk, oc, priv, func));
+	return (om->objiterator(wrk, oc, priv, func, final));
 }
 
 /*====================================================================
diff --git a/bin/varnishd/cache/cache_obj.h b/bin/varnishd/cache/cache_obj.h
index 007d32f..bdb6795 100644
--- a/bin/varnishd/cache/cache_obj.h
+++ b/bin/varnishd/cache/cache_obj.h
@@ -35,7 +35,7 @@ typedef void objsetstate_f(struct worker *, const struct objcore *,
     enum boc_state_e);
 
 typedef int objiterator_f(struct worker *, struct objcore *,
-    void *priv, objiterate_f *func);
+    void *priv, objiterate_f *func, int final);
 typedef int objgetspace_f(struct worker *, struct objcore *,
      ssize_t *sz, uint8_t **ptr);
 typedef void objextend_f(struct worker *, struct objcore *, ssize_t l);
diff --git a/bin/varnishd/cache/cache_req_body.c b/bin/varnishd/cache/cache_req_body.c
index 1986ffd..ec57a42 100644
--- a/bin/varnishd/cache/cache_req_body.c
+++ b/bin/varnishd/cache/cache_req_body.c
@@ -165,7 +165,7 @@ VRB_Iterate(struct req *req, objiterate_f *func, void *priv)
 	switch(req->req_body_status) {
 	case REQ_BODY_CACHED:
 		if (req->req_bodybytes > 0 &&
-		    ObjIterate(req->wrk, req->body_oc, priv, func))
+		    ObjIterate(req->wrk, req->body_oc, priv, func, 0))
 			return (-1);
 		return (0);
 	case REQ_BODY_NONE:
diff --git a/bin/varnishd/storage/storage_simple.c b/bin/varnishd/storage/storage_simple.c
index afc246e..c0f8c09 100644
--- a/bin/varnishd/storage/storage_simple.c
+++ b/bin/varnishd/storage/storage_simple.c
@@ -227,12 +227,13 @@ sml_objfree(struct worker *wrk, struct objcore *oc)
 
 static int __match_proto__(objiterate_f)
 sml_iterator(struct worker *wrk, struct objcore *oc,
-    void *priv, objiterate_f *func)
+    void *priv, objiterate_f *func, int final)
 {
 	struct boc *boc;
 	struct object *obj;
 	struct storage *st;
 	struct storage *checkpoint = NULL;
+	const struct stevedore *stv;
 	ssize_t checkpoint_len = 0;
 	ssize_t len = 0;
 	int ret = 0;
@@ -244,9 +245,24 @@ sml_iterator(struct worker *wrk, struct objcore *oc,
 
 	obj = sml_getobj(wrk, oc);
 	CHECK_OBJ_NOTNULL(obj, OBJECT_MAGIC);
+	stv = oc->stobj->stevedore;
+	CHECK_OBJ_NOTNULL(stv, STEVEDORE_MAGIC);
 
 	boc = HSH_RefBoc(oc);
 
+	/* Attemt to catch if final was already used */
+	assert(boc != NULL || !VTAILQ_EMPTY(&obj->list));
+
+	if (boc == NULL && final) {
+		while (!VTAILQ_EMPTY(&obj->list)) {
+			st = VTAILQ_FIRST(&obj->list);
+			if (ret == 0 && func(priv, 1, st->ptr, st->len))
+				ret = -1;
+			VTAILQ_REMOVE(&obj->list, st, list);
+			sml_stv_free(stv, st);
+		}
+		return (ret);
+	}
 	if (boc == NULL) {
 		VTAILQ_FOREACH(st, &obj->list, list) {
 			AN(st->len);



More information about the varnish-commit mailing list