[master] b44b1e9 Integrate the previous three ObjIter* functions into ObjIterate()

Poul-Henning Kamp phk at FreeBSD.org
Thu Dec 10 01:23:28 CET 2015


commit b44b1e94d9eddc3701e6e3ac053b36e4848e82f7
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Thu Dec 10 00:20:06 2015 +0000

    Integrate the previous three ObjIter* functions into ObjIterate()

diff --git a/bin/varnishd/cache/cache_obj.c b/bin/varnishd/cache/cache_obj.c
index f7c0712..206cf03 100644
--- a/bin/varnishd/cache/cache_obj.c
+++ b/bin/varnishd/cache/cache_obj.c
@@ -31,7 +31,7 @@
  *	ObjExtend	Commit space
  *	ObjDone		Object completed
  *	ObjGetLen	Len of committed space
- *	ObjIter		Iterate over committed space
+ *	ObjIterate	Iterate over committed space
  *	ObjReserveAttr	Attr will be set later
  *	ObjSetAttr	Set attr now
  *	ObjGetAttr	Get attr no
@@ -70,196 +70,102 @@ obj_getobj(struct worker *wrk, struct objcore *oc)
 }
 
 /*====================================================================
- * ObjIterBegin()
- * ObjIter()
- * ObjIterEnd()
+ * ObjIterate()
  *
- * 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.
  */
 
-enum objiter_status {
-	OIS_DONE,
-	OIS_DATA,
-	OIS_STREAM,
-	OIS_ERROR,
-};
-
-struct objiter {
-	unsigned			magic;
-#define OBJITER_MAGIC			0x745fb151
-	struct busyobj			*bo;
-	struct objcore			*oc;
-	struct object			*obj;
-	struct storage			*st;
-	struct worker			*wrk;
-	ssize_t				len;
-	struct storage			*checkpoint;
-	ssize_t				checkpoint_len;
-};
-
-static void *
-ObjIterBegin(struct worker *wrk, struct objcore *oc)
+int
+ObjIterate(struct worker *wrk, struct objcore *oc,
+    void *priv, objiterate_f *func)
 {
-	struct objiter *oi;
+	struct busyobj *bo;
 	struct object *obj;
+	struct storage *st;
+	struct storage *checkpoint = NULL;
+	ssize_t checkpoint_len = 0;
+	ssize_t len = 0;
+	int ret = 0;
+	ssize_t ol;
+	ssize_t nl;
+	ssize_t sl;
+	void *p;
+	ssize_t l;
+	const struct storeobj_methods *om = obj_getmethods(oc);
 
-	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
+	if (om->objiterator != NULL)
+		return (om->objiterator(wrk, oc, priv, func));
 
-	CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
 	obj = obj_getobj(wrk, oc);
 	CHECK_OBJ_NOTNULL(obj, OBJECT_MAGIC);
-	ALLOC_OBJ(oi, OBJITER_MAGIC);
-	if (oi == NULL)
-		return (oi);
-	oi->oc = oc;
-	oi->obj = obj;
-	oi->wrk = wrk;
-	oi->bo = HSH_RefBusy(oc);
-	return (oi);
-}
 
-static enum objiter_status
-ObjIter(void *oix, void **p, ssize_t *l)
-{
-	struct objiter *oi;
-	ssize_t ol;
-	ssize_t nl;
-	ssize_t sl;
+	bo = HSH_RefBusy(oc);
+
+	if (bo == NULL) {
+		VTAILQ_FOREACH(st, &obj->list, list)
+			if (func(priv, 0, st->ptr, st->len))
+				return (-1);
+		return (0);
+	}
+
+	p = NULL;
+	l = 0;
 
-	AN(oix);
-	AN(p);
-	AN(l);
-
-	CAST_OBJ_NOTNULL(oi, oix, OBJITER_MAGIC);
-	CHECK_OBJ_NOTNULL(oi->obj, OBJECT_MAGIC);
-	*p = NULL;
-	*l = 0;
-
-	if (oi->bo == NULL) {
-		if (oi->st == NULL)
-			oi->st = VTAILQ_FIRST(&oi->obj->list);
-		else
-			oi->st = VTAILQ_NEXT(oi->st, list);
-		while(oi->st != NULL && oi->st->len == 0)
-			oi->st = VTAILQ_NEXT(oi->st, list);
-		if (oi->st != NULL) {
-			*p = oi->st->ptr;
-			*l = oi->st->len;
-			assert(*l > 0);
-			return (OIS_DATA);
+	while (1) {
+		ol = len;
+		nl = VBO_waitlen(wrk, bo, ol);
+		if (bo->state == BOS_FAILED) {
+			ret = -1;
+			break;
 		}
-		return (OIS_DONE);
-	} else {
-		ol = oi->len;
-		while (1) {
-			nl = VBO_waitlen(oi->wrk, oi->bo, ol);
-			if (nl != ol)
+		if (nl == ol) {
+			if (bo->state == BOS_FINISHED)
 				break;
-			if (oi->bo->state == BOS_FINISHED)
-				return (OIS_DONE);
-			if (oi->bo->state == BOS_FAILED)
-				return (OIS_ERROR);
+			continue;
 		}
-		Lck_Lock(&oi->bo->mtx);
-		AZ(VTAILQ_EMPTY(&oi->obj->list));
-		if (oi->checkpoint == NULL) {
-			oi->st = VTAILQ_FIRST(&oi->obj->list);
+		Lck_Lock(&bo->mtx);
+		AZ(VTAILQ_EMPTY(&obj->list));
+		if (checkpoint == NULL) {
+			st = VTAILQ_FIRST(&obj->list);
 			sl = 0;
 		} else {
-			oi->st = oi->checkpoint;
-			sl = oi->checkpoint_len;
-			ol -= oi->checkpoint_len;
+			st = checkpoint;
+			sl = checkpoint_len;
+			ol -= checkpoint_len;
 		}
-		while (oi->st != NULL) {
-			if (oi->st->len > ol) {
-				*p = oi->st->ptr + ol;
-				*l = oi->st->len - ol;
-				oi->len += *l;
+		while (st != NULL) {
+			if (st->len > ol) {
+				p = st->ptr + ol;
+				l = st->len - ol;
+				len += l;
 				break;
 			}
-			ol -= oi->st->len;
+			ol -= st->len;
 			assert(ol >= 0);
-			nl -= oi->st->len;
+			nl -= st->len;
 			assert(nl > 0);
-			sl += oi->st->len;
-			oi->st = VTAILQ_NEXT(oi->st, list);
-			if (VTAILQ_NEXT(oi->st, list) != NULL) {
-				oi->checkpoint = oi->st;
-				oi->checkpoint_len = sl;
+			sl += st->len;
+			st = VTAILQ_NEXT(st, list);
+			if (VTAILQ_NEXT(st, list) != NULL) {
+				checkpoint = st;
+				checkpoint_len = sl;
 			}
 		}
-		CHECK_OBJ_NOTNULL(oi->obj, OBJECT_MAGIC);
-		CHECK_OBJ_NOTNULL(oi->st, STORAGE_MAGIC);
-		oi->st = VTAILQ_NEXT(oi->st, list);
-		if (oi->st != NULL && oi->st->len == 0)
-			oi->st = NULL;
-		Lck_Unlock(&oi->bo->mtx);
-		assert(*l > 0 || oi->bo->state == BOS_FINISHED);
-		return (oi->st != NULL ? OIS_DATA : OIS_STREAM);
-	}
-}
-
-static void
-ObjIterEnd(void **oix)
-{
-	struct objiter *oi;
-
-	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);
-}
-
-int
-ObjIterate(struct worker *wrk, struct objcore *oc,
-    void *priv, objiterate_f *func)
-{
-	void *oi;
-	enum objiter_status ois;
-	void *ptr;
-	ssize_t len;
-	const struct storeobj_methods *om = obj_getmethods(oc);
-
-	if (om->objiterator != NULL)
-		return (om->objiterator(wrk, oc, priv, func));
-
-	oi = ObjIterBegin(wrk, oc);
-	do {
-		ois = ObjIter(oi, &ptr, &len);
-		switch(ois) {
-		case OIS_DONE:
-			AZ(len);
-			break;
-		case OIS_ERROR:
-			break;
-		case OIS_DATA:
-			if (func(priv, 0, ptr, len))
-				ois = OIS_ERROR;
-			break;
-		case OIS_STREAM:
-			if (func(priv, 1, ptr, len))
-				ois = OIS_ERROR;
+		CHECK_OBJ_NOTNULL(obj, OBJECT_MAGIC);
+		CHECK_OBJ_NOTNULL(st, STORAGE_MAGIC);
+		st = VTAILQ_NEXT(st, list);
+		if (st != NULL && st->len == 0)
+			st = NULL;
+		Lck_Unlock(&bo->mtx);
+		assert(l > 0 || bo->state == BOS_FINISHED);
+		if (func(priv, st != NULL ? 0 : 1, p, l)) {
+			ret = -1;
 			break;
-		default:
-			WRONG("Wrong OIS value");
 		}
-	} while (ois == OIS_DATA || ois == OIS_STREAM);
-	ObjIterEnd(&oi);
-	return (ois == OIS_DONE ? 0 : -1);
+	}
+	if (oc->flags & OC_F_PASS)
+		bo->abandon = 1;
+	VBO_DerefBusyObj(wrk, &bo);
+	return (ret);
 }
 
 /*--------------------------------------------------------------------



More information about the varnish-commit mailing list