[master] dd01df1 Make the http1-pipe code use the same code to send the bereq, and properly send any cached req.body along (this didn't work before).

Poul-Henning Kamp phk at FreeBSD.org
Wed Jun 24 22:45:12 CEST 2015


commit dd01df1a9138d6a2204a1a8de4e0dc727d8fc488
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Wed Jun 24 20:10:25 2015 +0000

    Make the http1-pipe code use the same code to send the bereq, and
    properly send any cached req.body along (this didn't work before).
    
    This also makes struct vbc an entirely internal affair in cache_backend,
    as it (probably) should be.

diff --git a/bin/varnishd/cache/cache_backend.c b/bin/varnishd/cache/cache_backend.c
index 5616b10..9b144f5 100644
--- a/bin/varnishd/cache/cache_backend.c
+++ b/bin/varnishd/cache/cache_backend.c
@@ -38,6 +38,7 @@
 
 #include "vrt.h"
 #include "vtcp.h"
+#include "vtim.h"
 
 #include "cache_director.h"
 #include "cache_backend.h"
@@ -223,7 +224,7 @@ vbe_dir_gethdrs(const struct director *d, struct worker *wrk,
 		if (bo->htc->vbc->state != VBC_STATE_STOLEN)
 			extrachance = 0;
 
-		i = V1F_SendReq(wrk, bo);
+		i = V1F_SendReq(wrk, bo, &bo->acct.bereq_hdrbytes, 0);
 
 		if (bo->htc->vbc->state != VBC_STATE_USED)
 			VBT_Wait(wrk, bo->htc->vbc);
@@ -289,23 +290,39 @@ vbe_dir_getip(const struct director *d, struct worker *wrk,
 static void
 vbe_dir_http1pipe(const struct director *d, struct req *req, struct busyobj *bo)
 {
-	int i;
+	int i, fd;
 	struct backend *bp;
+	struct v1p_acct v1a;
 
 	CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC);
 	CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
 	CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
 	CAST_OBJ_NOTNULL(bp, d->priv, BACKEND_MAGIC);
 
-	i = vbe_dir_getfd(req->wrk, bp, bo);
-	if (i < 0) {
+	memset(&v1a, 0, sizeof v1a);
+	req->res_mode = RES_PIPE;
+
+	fd = vbe_dir_getfd(req->wrk, bp, bo);
+	/* This is hackish... */
+	v1a.req = req->acct.req_hdrbytes;
+	req->acct.req_hdrbytes = 0;
+
+	if (fd < 0) {
 		VSLb(bo->vsl, SLT_FetchError, "no backend connection");
 		SES_Close(req->sp, SC_RX_TIMEOUT);
-		return;
 	} else {
-		V1P_Process(req, bo, i, bp->vsc);
+		i = V1F_SendReq(req->wrk, bo, &v1a.bereq, 1);
+		VSLb_ts_req(req, "Pipe", W_TIM_real(req->wrk));
+		if (bo->htc->vbc->state == VBC_STATE_STOLEN)
+			VBT_Wait(req->wrk, bo->htc->vbc);
+		if (i == 0)
+			V1P_Process(req, fd, &v1a);
+		VSLb_ts_req(req, "PipeSess", W_TIM_real(req->wrk));
+		SES_Close(req->sp, SC_TX_PIPE);
+		bo->htc->doclose = SC_TX_PIPE;
 		vbe_dir_finish(d, req->wrk, bo);
 	}
+	V1P_Charge(req, &v1a, bp->vsc);
 }
 
 /*--------------------------------------------------------------------*/
diff --git a/bin/varnishd/http1/cache_http1.h b/bin/varnishd/http1/cache_http1.h
index 9e5a45a..66addc5 100644
--- a/bin/varnishd/http1/cache_http1.h
+++ b/bin/varnishd/http1/cache_http1.h
@@ -28,7 +28,8 @@
  */
 
 /* cache_http1_fetch.c [V1F] */
-int V1F_SendReq(struct worker *, struct busyobj *);
+int V1F_SendReq(struct worker *, struct busyobj *, uint64_t *ctr,
+    int onlycached);
 int V1F_FetchRespHdr(struct busyobj *);
 void V1F_Setup_Fetch(struct vfp_ctx *vfc, struct http_conn *htc);
 
@@ -41,8 +42,16 @@ extern const int HTTP1_Resp[3];
 vtr_deliver_f V1D_Deliver;
 
 /* cache_http1_pipe.c */
+struct v1p_acct {
+	uint64_t        req;
+	uint64_t        bereq;
+	uint64_t        in;
+	uint64_t        out;
+};
+
 void V1P_Init(void);
-void V1P_Process(struct req *, struct busyobj *, int fd, struct VSC_C_vbe *);
+void V1P_Process(struct req *, int fd, struct v1p_acct *);
+void V1P_Charge(struct req *, const struct v1p_acct *, struct VSC_C_vbe *);
 
 /* cache_http1_line.c */
 void V1L_Chunked(const struct worker *w);
diff --git a/bin/varnishd/http1/cache_http1_fetch.c b/bin/varnishd/http1/cache_http1_fetch.c
index 2fe3c18..04f3952 100644
--- a/bin/varnishd/http1/cache_http1_fetch.c
+++ b/bin/varnishd/http1/cache_http1_fetch.c
@@ -67,7 +67,7 @@ vbf_iter_req_body(struct req *req, void *priv, void *ptr, size_t l)
 }
 
 /*--------------------------------------------------------------------
- * Send request to backend, including any req.body
+ * Send request to backend, including any (cached) req.body
  *
  * Return value:
  *	 0 success
@@ -75,7 +75,8 @@ vbf_iter_req_body(struct req *req, void *priv, void *ptr, size_t l)
  */
 
 int
-V1F_SendReq(struct worker *wrk, struct busyobj *bo)
+V1F_SendReq(struct worker *wrk, struct busyobj *bo, uint64_t *ctr,
+    int onlycached)
 {
 	struct http *hp;
 	int j;
@@ -99,12 +100,13 @@ V1F_SendReq(struct worker *wrk, struct busyobj *bo)
 
 	(void)VTCP_blocking(htc->fd);	/* XXX: we should timeout instead */
 	V1L_Reserve(wrk, wrk->aws, &htc->fd, bo->vsl, bo->t_prev);
-	bo->acct.bereq_hdrbytes = HTTP1_Write(wrk, hp, HTTP1_Req);
+	*ctr += HTTP1_Write(wrk, hp, HTTP1_Req);
 
 	/* Deal with any message-body the request might (still) have */
 	i = 0;
 
-	if (bo->req != NULL) {
+	if (bo->req != NULL &&
+	    (bo->req->req_body_status == REQ_BODY_CACHED || !onlycached)) {
 		if (do_chunked)
 			V1L_Chunked(wrk);
 		i = VRB_Iterate(bo->req, vbf_iter_req_body, bo);
@@ -126,7 +128,7 @@ V1F_SendReq(struct worker *wrk, struct busyobj *bo)
 		    errno, strerror(errno));
 		VSLb_ts_busyobj(bo, "Bereq", W_TIM_real(wrk));
 		htc->doclose = SC_TX_ERROR;
-		return (1);
+		return (-1);
 	}
 	VSLb_ts_busyobj(bo, "Bereq", W_TIM_real(wrk));
 	return (0);
diff --git a/bin/varnishd/http1/cache_http1_pipe.c b/bin/varnishd/http1/cache_http1_pipe.c
index b80141c..6614a14 100644
--- a/bin/varnishd/http1/cache_http1_pipe.c
+++ b/bin/varnishd/http1/cache_http1_pipe.c
@@ -37,8 +37,6 @@
 #include "cache/cache.h"
 
 #include "vrt.h"
-#include "vtcp.h"
-#include "vtim.h"
 
 #include "cache_http1.h"
 #include "cache/cache_director.h"
@@ -46,13 +44,6 @@
 
 static struct lock pipestat_mtx;
 
-struct acct_pipe {
-	uint64_t	req;
-	uint64_t	bereq;
-	uint64_t	in;
-	uint64_t	out;
-};
-
 static int
 rdf(int fd0, int fd1, uint64_t *pcnt)
 {
@@ -73,8 +64,8 @@ rdf(int fd0, int fd1, uint64_t *pcnt)
 	return (0);
 }
 
-static void
-pipecharge(struct req *req, const struct acct_pipe *a, struct VSC_C_vbe *b)
+void
+V1P_Charge(struct req *req, const struct v1p_acct *a, struct VSC_C_vbe *b)
 {
 
 	AN(b);
@@ -95,84 +86,56 @@ pipecharge(struct req *req, const struct acct_pipe *a, struct VSC_C_vbe *b)
 }
 
 void
-V1P_Process(struct req *req, struct busyobj *bo, int fd, struct VSC_C_vbe *vsc)
+V1P_Process(struct req *req, int fd, struct v1p_acct *v1a)
 {
-	struct worker *wrk;
 	struct pollfd fds[2];
-	int i;
-	struct acct_pipe acct_pipe;
+	int i, j;
 
 	CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
 	CHECK_OBJ_NOTNULL(req->sp, SESS_MAGIC);
-	wrk = req->wrk;
-	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
-	CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
 	assert(fd > 0);
 
-	req->res_mode = RES_PIPE;
-
-	memset(&acct_pipe, 0, sizeof acct_pipe);
-	acct_pipe.req = req->acct.req_hdrbytes;
-	req->acct.req_hdrbytes = 0;
-
-	CHECK_OBJ_NOTNULL(bo->htc, HTTP_CONN_MAGIC);
-	CHECK_OBJ_NOTNULL(bo->htc->vbc, VBC_MAGIC);
-	bo->wrk = req->wrk;
-	bo->director_state = DIR_S_BODY;
-	(void)VTCP_blocking(fd);
-
-	V1L_Reserve(wrk, wrk->aws, &fd, bo->vsl, req->t_req);
-	acct_pipe.bereq += HTTP1_Write(wrk, bo->bereq, HTTP1_Req);
-
-	if (req->htc->pipeline_b != NULL)
-		acct_pipe.in += V1L_Write(wrk, req->htc->pipeline_b,
+	if (req->htc->pipeline_b != NULL) {
+		j = write(fd,  req->htc->pipeline_b,
 		    req->htc->pipeline_e - req->htc->pipeline_b);
-
-	i = V1L_FlushRelease(wrk);
-
-	VSLb_ts_req(req, "Pipe", W_TIM_real(wrk));
-
-	if (i == 0) {
-		if (bo->htc->vbc->state == VBC_STATE_STOLEN)
-			VBT_Wait(req->wrk, bo->htc->vbc);
-
-		memset(fds, 0, sizeof fds);
-		fds[0].fd = fd;
-		fds[0].events = POLLIN | POLLERR;
-		fds[1].fd = req->sp->fd;
-		fds[1].events = POLLIN | POLLERR;
-
-		while (fds[0].fd > -1 || fds[1].fd > -1) {
-			fds[0].revents = 0;
-			fds[1].revents = 0;
-			i = poll(fds, 2,
-			    (int)(cache_param->pipe_timeout * 1e3));
-			if (i < 1)
+		if (j < 0)
+			return;
+		req->htc->pipeline_b = NULL;
+		req->htc->pipeline_e = NULL;
+		v1a->in += j;
+	}
+	memset(fds, 0, sizeof fds);
+	fds[0].fd = fd;
+	fds[0].events = POLLIN | POLLERR;
+	fds[1].fd = req->sp->fd;
+	fds[1].events = POLLIN | POLLERR;
+
+	while (fds[0].fd > -1 || fds[1].fd > -1) {
+		fds[0].revents = 0;
+		fds[1].revents = 0;
+		i = poll(fds, 2,
+		    (int)(cache_param->pipe_timeout * 1e3));
+		if (i < 1)
+			break;
+		if (fds[0].revents &&
+		    rdf(fd, req->sp->fd, &v1a->out)) {
+			if (fds[1].fd == -1)
+				break;
+			(void)shutdown(fd, SHUT_RD);
+			(void)shutdown(req->sp->fd, SHUT_WR);
+			fds[0].events = 0;
+			fds[0].fd = -1;
+		}
+		if (fds[1].revents &&
+		    rdf(req->sp->fd, fd, &v1a->in)) {
+			if (fds[0].fd == -1)
 				break;
-			if (fds[0].revents &&
-			    rdf(fd, req->sp->fd, &acct_pipe.out)) {
-				if (fds[1].fd == -1)
-					break;
-				(void)shutdown(fd, SHUT_RD);
-				(void)shutdown(req->sp->fd, SHUT_WR);
-				fds[0].events = 0;
-				fds[0].fd = -1;
-			}
-			if (fds[1].revents &&
-			    rdf(req->sp->fd, fd, &acct_pipe.in)) {
-				if (fds[0].fd == -1)
-					break;
-				(void)shutdown(req->sp->fd, SHUT_RD);
-				(void)shutdown(fd, SHUT_WR);
-				fds[1].events = 0;
-				fds[1].fd = -1;
-			}
+			(void)shutdown(req->sp->fd, SHUT_RD);
+			(void)shutdown(fd, SHUT_WR);
+			fds[1].events = 0;
+			fds[1].fd = -1;
 		}
 	}
-	VSLb_ts_req(req, "PipeSess", W_TIM_real(wrk));
-	pipecharge(req, &acct_pipe, vsc);
-	SES_Close(req->sp, SC_TX_PIPE);
-	bo->htc->doclose = SC_TX_PIPE;
 }
 
 /*--------------------------------------------------------------------*/



More information about the varnish-commit mailing list