[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