[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