[master] 8489546 Introduce the object iterator functions, which will hide the nasty synchronization bits of streaming.

Poul-Henning Kamp phk at varnish-cache.org
Tue Aug 27 09:48:49 CEST 2013


commit 8489546fceb56753ca44b95cca03a558088a62f5
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Tue Aug 27 07:48:17 2013 +0000

    Introduce the object iterator functions, which will hide the
    nasty synchronization bits of streaming.

diff --git a/bin/varnishd/Makefile.am b/bin/varnishd/Makefile.am
index b1f54ed..4759414 100644
--- a/bin/varnishd/Makefile.am
+++ b/bin/varnishd/Makefile.am
@@ -34,6 +34,7 @@ varnishd_SOURCES = \
 	cache/cache_lck.c \
 	cache/cache_main.c \
 	cache/cache_mempool.c \
+	cache/cache_obj.c \
 	cache/cache_panic.c \
 	cache/cache_pipe.c \
 	cache/cache_pool.c \
diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h
index b4037c4..1626351 100644
--- a/bin/varnishd/cache/cache.h
+++ b/bin/varnishd/cache/cache.h
@@ -129,6 +129,7 @@ struct vsb;
 struct waitinglist;
 struct worker;
 struct wrw;
+struct objiter;
 
 #define DIGEST_LEN		32
 
@@ -983,6 +984,11 @@ void MPL_Destroy(struct mempool **mpp);
 void *MPL_Get(struct mempool *mpl, unsigned *size);
 void MPL_Free(struct mempool *mpl, void *item);
 
+/* cache_obj.c */
+struct objiter *ObjIterBegin(struct object *);
+int ObjIter(struct objiter *, void **, ssize_t *);
+void ObjIterEnd(struct objiter **);
+
 /* cache_panic.c */
 void PAN_Init(void);
 const char *body_status_2str(enum body_status e);
diff --git a/bin/varnishd/cache/cache_obj.c b/bin/varnishd/cache/cache_obj.c
new file mode 100644
index 0000000..65f443b
--- /dev/null
+++ b/bin/varnishd/cache/cache_obj.c
@@ -0,0 +1,80 @@
+/*-
+ * Copyright (c) 2013 Varnish Software AS
+ * All rights reserved.
+ *
+ * Author: Poul-Henning Kamp <phk at phk.freebsd.dk>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+
+#include "cache.h"
+
+struct objiter {
+	unsigned			magic;
+#define OBJITER_MAGIC			0x745fb151
+	struct object			*obj;
+	struct storage			*st;
+};
+
+struct objiter *
+ObjIterBegin(struct object *obj)
+{
+	struct objiter *oi;
+
+	CHECK_OBJ_NOTNULL(obj, OBJECT_MAGIC);
+	ALLOC_OBJ(oi, OBJITER_MAGIC);
+	if (oi != NULL)
+		oi->obj = obj;
+	return (oi);
+}
+
+int
+ObjIter(struct objiter *oi, void **p, ssize_t *l)
+{
+
+	CHECK_OBJ_NOTNULL(oi, OBJITER_MAGIC);
+	AN(p);
+	AN(l);
+
+	if (oi->st == NULL)
+		oi->st = VTAILQ_FIRST(&oi->obj->store);
+	else
+		oi->st = VTAILQ_NEXT(oi->st, list);
+	if (oi->st != NULL) {
+		*p = oi->st->ptr;
+		*l = oi->st->len;
+		return (1);
+	}
+	return (0);
+}
+
+void
+ObjIterEnd(struct objiter **oi)
+{
+
+	CHECK_OBJ_NOTNULL((*oi), OBJITER_MAGIC);
+	FREE_OBJ((*oi));
+}
diff --git a/bin/varnishd/cache/cache_response.c b/bin/varnishd/cache/cache_response.c
index b49f405..5e9f997 100644
--- a/bin/varnishd/cache/cache_response.c
+++ b/bin/varnishd/cache/cache_response.c
@@ -161,9 +161,11 @@ RES_BuildHttp(struct req *req)
 static void
 res_WriteGunzipObj(struct req *req)
 {
-	struct storage *st;
 	unsigned u = 0;
 	struct vgz *vg;
+	struct objiter *oi;
+	void *ptr;
+	ssize_t len;
 	int i;
 
 	CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
@@ -171,18 +173,21 @@ res_WriteGunzipObj(struct req *req)
 	vg = VGZ_NewUngzip(req->vsl, "U D -");
 	AZ(VGZ_WrwInit(vg));
 
-	VTAILQ_FOREACH(st, &req->obj->store, list) {
+	oi = ObjIterBegin(req->obj);
+	XXXAN(oi);
+
+	while (ObjIter(oi, &ptr, &len)) {
 		CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
-		CHECK_OBJ_NOTNULL(st, STORAGE_MAGIC);
-		u += st->len;
+		u += len;
 
-		i = VGZ_WrwGunzip(req, vg, st->ptr, st->len);
+		i = VGZ_WrwGunzip(req, vg, ptr, len);
 		/* XXX: error check */
 		(void)i;
 	}
 	VGZ_WrwFlush(req, vg);
 	(void)VGZ_Destroy(&vg);
 	assert(u == req->obj->len);
+	ObjIterEnd(&oi);
 }
 
 /*--------------------------------------------------------------------*/
@@ -191,39 +196,41 @@ static void
 res_WriteDirObj(struct req *req, ssize_t low, ssize_t high)
 {
 	ssize_t u = 0;
-	size_t ptr, off, len;
-	struct storage *st;
+	ssize_t idx, skip, len;
+	struct objiter *oi;
+	void *ptr;
 
 	CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
 
-	ptr = 0;
-	VTAILQ_FOREACH(st, &req->obj->store, list) {
-		CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
-		CHECK_OBJ_NOTNULL(st, STORAGE_MAGIC);
-		u += st->len;
-		len = st->len;
-		off = 0;
-		if (ptr + len <= low) {
+	oi = ObjIterBegin(req->obj);
+	XXXAN(oi);
+
+	idx = 0;
+	while (ObjIter(oi, &ptr, &len)) {
+		u += len;
+		skip = 0;
+		if (idx + len <= low) {
 			/* This segment is too early */
-			ptr += len;
+			idx += len;
 			continue;
 		}
-		if (ptr < low) {
+		if (idx < low) {
 			/* Chop front of segment off */
-			off += (low - ptr);
-			len -= (low - ptr);
-			ptr += (low - ptr);
+			skip += (low - idx);
+			len -= (low - idx);
+			idx += (low - idx);
 		}
-		if (ptr + len > high)
+		if (idx + len > high)
 			/* Chop tail of segment off */
-			len = 1 + high - ptr;
+			len = 1 + high - idx;
 
-		ptr += len;
+		idx += len;
 
 		req->acct_req.bodybytes += len;
-		(void)WRW_Write(req->wrk, st->ptr + off, len);
+		(void)WRW_Write(req->wrk, (char*)ptr + skip, len);
 	}
 	assert(u == req->obj->len);
+	ObjIterEnd(&oi);
 }
 
 /*--------------------------------------------------------------------



More information about the varnish-commit mailing list