[master] d4ac001 Add WRW support for chunked encoding.

Poul-Henning Kamp phk at varnish-cache.org
Thu Mar 24 15:01:31 CET 2011


commit d4ac001ad8c959bd9b755454a3975c0d20b5ba0a
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Thu Mar 24 12:24:22 2011 +0000

    Add WRW support for chunked encoding.

diff --git a/bin/varnishd/cache.h b/bin/varnishd/cache.h
index 840c774..423d452 100644
--- a/bin/varnishd/cache.h
+++ b/bin/varnishd/cache.h
@@ -256,6 +256,8 @@ struct wrw {
 	unsigned		siov;
 	unsigned		niov;
 	ssize_t			liov;
+	ssize_t			cliov;
+	unsigned		ciov;	/* Chunked header marker */
 };
 
 struct worker {
@@ -787,6 +789,7 @@ int WRK_QueueSession(struct sess *sp);
 void WRK_SumStat(struct worker *w);
 
 #define WRW_IsReleased(w)	((w)->wrw.wfd == NULL)
+void WRW_Chunked(struct worker *w);
 void WRW_Reserve(struct worker *w, int *fd);
 unsigned WRW_Flush(struct worker *w);
 unsigned WRW_FlushRelease(struct worker *w);
diff --git a/bin/varnishd/cache_wrw.c b/bin/varnishd/cache_wrw.c
index f6ddec8..d43ea78 100644
--- a/bin/varnishd/cache_wrw.c
+++ b/bin/varnishd/cache_wrw.c
@@ -45,6 +45,7 @@
 #include "svnid.h"
 SVNID("$Id$")
 
+#include <stdio.h>
 #include <sys/types.h>
 #include <sys/uio.h>
 
@@ -80,6 +81,7 @@ WRW_Reserve(struct worker *w, int *fd)
 	wrw->werr = 0;
 	wrw->liov = 0;
 	wrw->niov = 0;
+	wrw->ciov = wrw->siov;
 	wrw->wfd = fd;
 }
 
@@ -90,9 +92,11 @@ WRW_Release(struct worker *w)
 
 	CHECK_OBJ_NOTNULL(w, WORKER_MAGIC);
 	wrw = &w->wrw;
+	AN(wrw->wfd);
 	wrw->werr = 0;
 	wrw->liov = 0;
 	wrw->niov = 0;
+	wrw->ciov = wrw->siov;
 	wrw->wfd = NULL;
 }
 
@@ -101,11 +105,28 @@ WRW_Flush(struct worker *w)
 {
 	ssize_t i;
 	struct wrw *wrw;
+	char cbuf[32];
 
 	CHECK_OBJ_NOTNULL(w, WORKER_MAGIC);
 	wrw = &w->wrw;
 	AN(wrw->wfd);
+
+	/* For chunked, there must be one slot reserved for the chunked tail */
+	if (wrw->ciov < wrw->siov)
+		assert(wrw->niov < wrw->siov);
+
 	if (*wrw->wfd >= 0 && wrw->niov > 0 && wrw->werr == 0) {
+		if (wrw->ciov < wrw->siov && wrw->liov > 0) {
+			bprintf(cbuf, "%jx\r\n", (intmax_t)wrw->cliov);
+			i = strlen(cbuf);
+			wrw->iov[wrw->ciov].iov_base = cbuf;
+			wrw->iov[wrw->ciov].iov_len = i;
+			wrw->liov += i;
+
+			wrw->iov[wrw->niov].iov_base = cbuf + i - 2;
+			wrw->iov[wrw->niov++].iov_len = 2;
+			wrw->liov += 2;
+		}
 		i = writev(*wrw->wfd, wrw->iov, wrw->niov);
 		if (i != wrw->liov) {
 			wrw->werr++;
@@ -115,7 +136,10 @@ WRW_Flush(struct worker *w)
 		}
 	}
 	wrw->liov = 0;
+	wrw->cliov = 0;
 	wrw->niov = 0;
+	if (wrw->ciov < wrw->siov)
+		wrw->ciov = wrw->niov++;
 	return (wrw->werr);
 }
 
@@ -160,15 +184,38 @@ WRW_Write(struct worker *w, const void *ptr, int len)
 		return (0);
 	if (len == -1)
 		len = strlen(ptr);
-	if (wrw->niov == wrw->siov)
+	if (wrw->niov == wrw->siov + (wrw->ciov < wrw->siov ? 1 : 0))
 		(void)WRW_Flush(w);
 	wrw->iov[wrw->niov].iov_base = TRUST_ME(ptr);
 	wrw->iov[wrw->niov].iov_len = len;
 	wrw->liov += len;
+	if (wrw->ciov < wrw->siov)
+		wrw->cliov += len;
 	wrw->niov++;
 	return (len);
 }
 
+void
+WRW_Chunked(struct worker *w)
+{
+	struct wrw *wrw;
+
+	CHECK_OBJ_NOTNULL(w, WORKER_MAGIC);
+	wrw = &w->wrw;
+
+	assert(wrw->ciov == wrw->siov);
+	/*
+	 * If there are not space for chunked header, a chunk of data and
+	 * a chunk tail, we might as well flush right away.
+	 */
+	if (wrw->niov + 3 >= wrw->siov)
+		(void)WRW_Flush(w);
+	wrw->ciov = wrw->niov++;
+	wrw->cliov = wrw->liov;
+	assert(wrw->ciov < wrw->siov);
+}
+
+
 #ifdef SENDFILE_WORKS
 void
 WRW_Sendfile(struct worker *w, int fd, off_t off, unsigned len)



More information about the varnish-commit mailing list