From: phk Date: Thu, 20 Jul 2006 08:25:53 +0000 (+0000) Subject: Move the delivery functions from acceptor to response X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5fd6ab0a11d020a49a0323ddeab804fedf5256e9;p=varnish Move the delivery functions from acceptor to response git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@511 d4fa192b-c00b-0410-8231-f00ffab90ce4 --- diff --git a/varnish-cache/bin/varnishd/cache.h b/varnish-cache/bin/varnishd/cache.h index b0391ce1..a14ec761 100644 --- a/varnish-cache/bin/varnishd/cache.h +++ b/varnish-cache/bin/varnishd/cache.h @@ -247,9 +247,6 @@ struct backend { /* cache_acceptor.c */ -void vca_write(struct sess *sp, void *ptr, size_t len); -void vca_write_obj(struct worker *w, struct sess *sp); -void vca_flush(struct sess *sp); void vca_return_session(struct sess *sp); void vca_close_session(struct sess *sp, const char *why); void VCA_Init(void); @@ -339,6 +336,9 @@ void VSL(enum shmlogtag tag, unsigned id, const char *fmt, ...); /* cache_response.c */ void RES_Error(struct worker *w, struct sess *sp, int error, const char *msg); +void RES_Flush(struct sess *sp); +void RES_Write(struct sess *sp, void *ptr, size_t len); +void RES_WriteObj(struct worker *w, struct sess *sp); /* cache_vcl.c */ void VCL_Init(void); diff --git a/varnish-cache/bin/varnishd/cache_acceptor.c b/varnish-cache/bin/varnishd/cache_acceptor.c index 1d34afca..a6a890f3 100644 --- a/varnish-cache/bin/varnishd/cache_acceptor.c +++ b/varnish-cache/bin/varnishd/cache_acceptor.c @@ -37,88 +37,6 @@ static unsigned xids; static struct event accept_e[2 * HERITAGE_NSOCKS]; static TAILQ_HEAD(,sess) sesshead = TAILQ_HEAD_INITIALIZER(sesshead); - -/*-------------------------------------------------------------------- - * Write data to client - * We try to use writev() if possible in order to minimize number of - * syscalls made and packets sent. It also just might allow the worker - * thread to complete the request without holding stuff locked. - */ - -void -vca_flush(struct sess *sp) -{ - int i; - - if (sp->fd < 0 || sp->wrk->niov == 0) - return; - i = writev(sp->fd, sp->wrk->iov, sp->wrk->niov); - if (i != sp->wrk->liov) - vca_close_session(sp, "remote closed"); - sp->wrk->liov = 0; - sp->wrk->niov = 0; -} - -void -vca_write(struct sess *sp, void *ptr, size_t len) -{ - - if (sp->fd < 0 || len == 0) - return; - if (sp->wrk->niov == MAX_IOVS) - vca_flush(sp); - if (sp->fd < 0) - return; - sp->wrk->iov[sp->wrk->niov].iov_base = ptr; - sp->wrk->iov[sp->wrk->niov++].iov_len = len; - sp->wrk->liov += len; -} - -void -vca_write_obj(struct worker *w, struct sess *sp) -{ - struct storage *st; - unsigned u = 0; - uint64_t bytes = 0; - - - VSL(SLT_Status, sp->fd, "%u", sp->obj->response); - VSL(SLT_Length, sp->fd, "%u", sp->obj->len); - - vca_write(sp, sp->obj->header, strlen(sp->obj->header)); - - sbuf_clear(w->sb); - sbuf_printf(w->sb, "Age: %u\r\n", - sp->obj->age + sp->t_req - sp->obj->entered); - sbuf_printf(w->sb, "Via: 1.1 varnish\r\n"); - sbuf_printf(w->sb, "X-Varnish: xid %u\r\n", sp->obj->xid); - if (strcmp(sp->http->proto, "HTTP/1.1")) - sbuf_printf(w->sb, "Connection: close\r\n"); - sbuf_printf(w->sb, "\r\n"); - sbuf_finish(w->sb); - vca_write(sp, sbuf_data(w->sb), sbuf_len(w->sb)); - bytes += sbuf_len(w->sb); - /* XXX: conditional request handling */ - if (!strcmp(sp->http->req, "GET")) { - TAILQ_FOREACH(st, &sp->obj->store, list) { - u += st->len; - if (st->stevedore->send == NULL) { - vca_write(sp, st->ptr, st->len); - continue; - } - st->stevedore->send(st, sp, - sp->wrk->iov, sp->wrk->niov, sp->wrk->liov); - sp->wrk->niov = 0; - sp->wrk->liov = 0; - } - assert(u == sp->obj->len); - } - SES_ChargeBytes(sp, bytes + u); - vca_flush(sp); -} - -/*--------------------------------------------------------------------*/ - static void vca_tick(int a, short b, void *c) { diff --git a/varnish-cache/bin/varnishd/cache_center.c b/varnish-cache/bin/varnishd/cache_center.c index b19a4f78..93049355 100644 --- a/varnish-cache/bin/varnishd/cache_center.c +++ b/varnish-cache/bin/varnishd/cache_center.c @@ -61,7 +61,7 @@ static int cnt_deliver(struct sess *sp) { - vca_write_obj(sp->wrk, sp); + RES_WriteObj(sp->wrk, sp); HSH_Deref(sp->obj); sp->obj = NULL; sp->step = STP_DONE; @@ -253,7 +253,7 @@ cnt_hit(struct sess *sp) sp->handling = VCL_RET_PASS; if (sp->handling == VCL_RET_DELIVER) { - vca_write_obj(sp->wrk, sp); + RES_WriteObj(sp->wrk, sp); HSH_Deref(sp->obj); sp->obj = NULL; sp->step = STP_DONE; diff --git a/varnish-cache/bin/varnishd/cache_pass.c b/varnish-cache/bin/varnishd/cache_pass.c index fed9bd79..23530fd2 100644 --- a/varnish-cache/bin/varnishd/cache_pass.c +++ b/varnish-cache/bin/varnishd/cache_pass.c @@ -46,8 +46,8 @@ pass_straight(struct sess *sp, int fd, struct http *hp, char *bi) if (i == 0 && bi == NULL) return (1); assert(i > 0); - vca_write(sp, buf, i); - vca_flush(sp); + RES_Write(sp, buf, i); + RES_Flush(sp); cl -= i; } return (0); @@ -92,7 +92,7 @@ pass_chunked(struct sess *sp, int fd, struct http *hp) if (u == 0) break; - vca_write(sp, p, q - p); + RES_Write(sp, p, q - p); p = q; @@ -104,28 +104,28 @@ pass_chunked(struct sess *sp, int fd, struct http *hp) } if (bp - p < j) j = bp - p; - vca_write(sp, p, j); + RES_Write(sp, p, j); p += j; u -= j; } while (u > 0) { if (http_GetTail(hp, u, &b, &e)) { j = e - b; - vca_write(sp, q, j); + RES_Write(sp, q, j); u -= j; } else break; } - vca_flush(sp); + RES_Flush(sp); while (u > 0) { j = u; if (j > sizeof buf) j = sizeof buf; i = read(fd, buf, j); assert(i > 0); - vca_write(sp, buf, i); + RES_Write(sp, buf, i); u -= i; - vca_flush(sp); + RES_Flush(sp); } } return (0); @@ -150,7 +150,7 @@ PassBody(struct worker *w, struct sess *sp) http_BuildSbuf(sp->fd, Build_Reply, w->sb, hp); sbuf_cat(w->sb, "\r\n"); sbuf_finish(w->sb); - vca_write(sp, sbuf_data(w->sb), sbuf_len(w->sb)); + RES_Write(sp, sbuf_data(w->sb), sbuf_len(w->sb)); if (http_GetHdr(hp, "Content-Length", &b)) cls = pass_straight(sp, vc->fd, hp, b); @@ -161,7 +161,7 @@ PassBody(struct worker *w, struct sess *sp) else { cls = pass_straight(sp, vc->fd, hp, NULL); } - vca_flush(sp); + RES_Flush(sp); if (http_GetHdr(hp, "Connection", &b) && !strcasecmp(b, "close")) cls = 1; diff --git a/varnish-cache/bin/varnishd/cache_response.c b/varnish-cache/bin/varnishd/cache_response.c index 458a5017..7c07ecb0 100644 --- a/varnish-cache/bin/varnishd/cache_response.c +++ b/varnish-cache/bin/varnishd/cache_response.c @@ -3,10 +3,12 @@ */ #include /* XXX: for NULL ?? */ +#include /* XXX: for NULL ?? */ #include #include #include "libvarnish.h" +#include "shmlog.h" #include "cache.h" @@ -60,7 +62,87 @@ RES_Error(struct worker *w, struct sess *sp, int error, const char *msg) " \r\n" "\r\n"); sbuf_finish(w->sb); - vca_write(sp, sbuf_data(w->sb), sbuf_len(w->sb)); - vca_flush(sp); + RES_Write(sp, sbuf_data(w->sb), sbuf_len(w->sb)); + RES_Flush(sp); vca_close_session(sp, msg); } + + +/*-------------------------------------------------------------------- + * Write data to client + * We try to use writev() if possible in order to minimize number of + * syscalls made and packets sent. It also just might allow the worker + * thread to complete the request without holding stuff locked. + */ + +void +RES_Flush(struct sess *sp) +{ + int i; + + if (sp->fd < 0 || sp->wrk->niov == 0) + return; + i = writev(sp->fd, sp->wrk->iov, sp->wrk->niov); + if (i != sp->wrk->liov) + vca_close_session(sp, "remote closed"); + sp->wrk->liov = 0; + sp->wrk->niov = 0; +} + +void +RES_Write(struct sess *sp, void *ptr, size_t len) +{ + + if (sp->fd < 0 || len == 0) + return; + if (sp->wrk->niov == MAX_IOVS) + RES_Flush(sp); + if (sp->fd < 0) + return; + sp->wrk->iov[sp->wrk->niov].iov_base = ptr; + sp->wrk->iov[sp->wrk->niov++].iov_len = len; + sp->wrk->liov += len; +} + +void +RES_WriteObj(struct worker *w, struct sess *sp) +{ + struct storage *st; + unsigned u = 0; + uint64_t bytes = 0; + + + VSL(SLT_Status, sp->fd, "%u", sp->obj->response); + VSL(SLT_Length, sp->fd, "%u", sp->obj->len); + + RES_Write(sp, sp->obj->header, strlen(sp->obj->header)); + + sbuf_clear(w->sb); + sbuf_printf(w->sb, "Age: %u\r\n", + sp->obj->age + sp->t_req - sp->obj->entered); + sbuf_printf(w->sb, "Via: 1.1 varnish\r\n"); + sbuf_printf(w->sb, "X-Varnish: xid %u\r\n", sp->obj->xid); + if (strcmp(sp->http->proto, "HTTP/1.1")) + sbuf_printf(w->sb, "Connection: close\r\n"); + sbuf_printf(w->sb, "\r\n"); + sbuf_finish(w->sb); + RES_Write(sp, sbuf_data(w->sb), sbuf_len(w->sb)); + bytes += sbuf_len(w->sb); + /* XXX: conditional request handling */ + if (!strcmp(sp->http->req, "GET")) { + TAILQ_FOREACH(st, &sp->obj->store, list) { + u += st->len; + if (st->stevedore->send == NULL) { + RES_Write(sp, st->ptr, st->len); + continue; + } + st->stevedore->send(st, sp, + sp->wrk->iov, sp->wrk->niov, sp->wrk->liov); + sp->wrk->niov = 0; + sp->wrk->liov = 0; + } + assert(u == sp->obj->len); + } + SES_ChargeBytes(sp, bytes + u); + RES_Flush(sp); +}