Commit 282d33a5 authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Move the delivery functions from acceptor to response


git-svn-id: http://www.varnish-cache.org/svn/trunk/varnish-cache@511 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent 1152ec30
......@@ -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);
......
......@@ -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)
{
......
......@@ -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;
......
......@@ -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;
......
......@@ -3,10 +3,12 @@
*/
#include <stdio.h> /* XXX: for NULL ?? */
#include <string.h> /* XXX: for NULL ?? */
#include <sys/types.h>
#include <sys/time.h>
#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)
" </BODY>\r\n"
"</HTML>\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);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment