[master] c74bd5f Simplify delivery by making a private objcore in vcl_synth{}

Poul-Henning Kamp phk at FreeBSD.org
Tue Oct 21 13:10:45 CEST 2014


commit c74bd5f8af46f3a5374d364db33373c44049b862
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Tue Oct 21 11:10:10 2014 +0000

    Simplify delivery by making a private objcore in vcl_synth{}

diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h
index 0748d66..185b3e8 100644
--- a/bin/varnishd/cache/cache.h
+++ b/bin/varnishd/cache/cache.h
@@ -743,7 +743,6 @@ extern const int HTTP1_Resp[3];
 /* cache_http1_deliver.c */
 unsigned V1D_FlushReleaseAcct(struct req *req);
 void V1D_Deliver(struct req *, struct busyobj *);
-void V1D_Deliver_Synth(struct req *req);
 
 /* cache_http1_pipe.c */
 void V1P_Init(void);
diff --git a/bin/varnishd/cache/cache_req_fsm.c b/bin/varnishd/cache/cache_req_fsm.c
index 30507ff..9c2627a 100644
--- a/bin/varnishd/cache/cache_req_fsm.c
+++ b/bin/varnishd/cache/cache_req_fsm.c
@@ -108,7 +108,6 @@ cnt_deliver(struct worker *wrk, struct req *req)
 		wrk->handling = VCL_RET_DELIVER;
 
 	if (wrk->handling != VCL_RET_DELIVER) {
-		assert(req->objcore == req->objcore);
 		(void)HSH_DerefObjCore(wrk, &req->objcore);
 		http_Teardown(req->resp);
 
@@ -155,14 +154,8 @@ cnt_deliver(struct worker *wrk, struct req *req)
 	if (http_HdrIs(req->resp, H_Connection, "close"))
 		req->doclose = SC_RESP_CLOSE;
 
-	if (req->objcore->flags & OC_F_PASS) {
-		/*
-		 * No point in saving the body if it is hit-for-pass,
-		 * but we can't yank it until the fetching thread has
-		 * finished/abandoned also.
-		 */
-		while (req->objcore->busyobj != NULL)
-			(void)usleep(100000);
+	if ((req->objcore->flags & OC_F_PASS) && bo != NULL) {
+		VBO_waitstate(bo, BOS_FINISHED);
 		ObjSlim(wrk, req->objcore);
 	}
 
@@ -194,6 +187,7 @@ cnt_synth(struct worker *wrk, struct req *req)
 	if (req->err_code < 100 || req->err_code > 999)
 		req->err_code = 501;
 
+
 	HTTP_Setup(req->resp, req->ws, req->vsl, SLT_RespMethod);
 	h = req->resp;
 	VTIM_format(now, date);
@@ -212,6 +206,9 @@ cnt_synth(struct worker *wrk, struct req *req)
 
 	AZ(VSB_finish(req->synth_body));
 
+	/* Discard any lingering request body before delivery */
+	(void)VRB_Ignore(req);
+
 	if (wrk->handling == VCL_RET_RESTART) {
 		HTTP_Setup(h, req->ws, req->vsl, SLT_RespMethod);
 		VSB_delete(req->synth_body);
@@ -224,16 +221,30 @@ cnt_synth(struct worker *wrk, struct req *req)
 	if (http_HdrIs(req->resp, H_Connection, "close"))
 		req->doclose = SC_RESP_CLOSE;
 
-	/* Discard any lingering request body before delivery */
-	(void)VRB_Ignore(req);
+	req->objcore = HSH_Private(wrk);
+	CHECK_OBJ_NOTNULL(req->objcore, OBJCORE_MAGIC);
+	if (STV_NewObject(req->objcore, wrk, TRANSIENT_STORAGE, 1024)) {
+		ssize_t sz, szl;
+		uint8_t *ptr;
+
+		szl = VSB_len(req->synth_body);
+		assert(szl >= 0);
+		if (szl > 0) {
+			sz = szl;
+			AN(ObjGetSpace(wrk, req->objcore, &sz, &ptr));
+			assert(sz >= szl);
+			memcpy(ptr, VSB_data(req->synth_body), szl);
+			ObjExtend(wrk, req->objcore, szl);
+		}
+		VSB_delete(req->synth_body);
+		req->synth_body = NULL;
 
-	V1D_Deliver_Synth(req);
+		V1D_Deliver(req, NULL);
+		(void)HSH_DerefObjCore(wrk, &req->objcore);
+	}
 
 	VSLb_ts_req(req, "Resp", W_TIM_real(wrk));
 
-	VSB_delete(req->synth_body);
-	req->synth_body = NULL;
-
 	req->err_code = 0;
 	req->err_reason = NULL;
 	return (REQ_FSM_DONE);
diff --git a/bin/varnishd/http1/cache_http1_deliver.c b/bin/varnishd/http1/cache_http1_deliver.c
index 3f0f341..08d3264 100644
--- a/bin/varnishd/http1/cache_http1_deliver.c
+++ b/bin/varnishd/http1/cache_http1_deliver.c
@@ -176,6 +176,7 @@ v1d_WriteDirObj(struct req *req)
 
 	oi = ObjIterBegin(req->wrk, req->objcore);
 	XXXAN(oi);
+	AZ(req->synth_body);
 
 	do {
 		ois = ObjIter(req->objcore, oi, &ptr, &len);
@@ -365,99 +366,3 @@ V1D_Deliver(struct req *req, struct busyobj *bo)
 	if ((V1D_FlushReleaseAcct(req) || ois != OIS_DONE) && req->sp->fd >= 0)
 		SES_Close(req->sp, SC_REM_CLOSE);
 }
-
-void
-V1D_Deliver_Synth(struct req *req)
-{
-	const char *r;
-
-	CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
-	AN(req->synth_body);
-
-	req->res_mode = 0;
-	if (http_IsStatus(req->resp, 304)) {
-		req->res_mode &= ~RES_LEN;
-		http_Unset(req->resp, H_Content_Length);
-		req->wantbody = 0;
-	} else {
-		req->res_mode |= RES_LEN;
-		http_Unset(req->resp, H_Content_Length);
-		http_PrintfHeader(req->resp, "Content-Length: %zd",
-		    VSB_len(req->synth_body));
-	}
-
-	if (req->esi_level > 0) {
-		/* Included ESI object, always CHUNKED or EOF */
-		req->res_mode &= ~RES_LEN;
-		req->res_mode |= RES_ESI_CHILD;
-	}
-
-	if (!(req->res_mode & (RES_LEN|RES_CHUNKED|RES_EOF))) {
-		/* We havn't chosen yet, do so */
-		if (!req->wantbody) {
-			/* Nothing */
-		} else if (req->http->protover >= 11) {
-			req->res_mode |= RES_CHUNKED;
-		} else {
-			req->res_mode |= RES_EOF;
-			req->doclose = SC_TX_EOF;
-		}
-	}
-	VSLb(req->vsl, SLT_Debug, "RES_MODE %x", req->res_mode);
-
-	if (!(req->res_mode & RES_LEN))
-		http_Unset(req->resp, H_Content_Length);
-
-	if (req->res_mode & RES_GUNZIP)
-		http_Unset(req->resp, H_Content_Encoding);
-
-	if (req->res_mode & RES_CHUNKED)
-		http_SetHeader(req->resp, "Transfer-Encoding: chunked");
-
-	http_SetHeader(req->resp,
-	    req->doclose ? "Connection: close" : "Connection: keep-alive");
-
-	req->vdps[0] = v1d_bytes;
-	req->vdp_nxt = 0;
-
-	if (
-	    req->wantbody &&
-	    !(req->res_mode & RES_ESI_CHILD) &&
-	    cache_param->http_range_support &&
-	    http_IsStatus(req->resp, 200)) {
-		http_SetHeader(req->resp, "Accept-Ranges: bytes");
-		if (http_GetHdr(req->http, H_Range, &r))
-			v1d_dorange(req, NULL, r);
-	}
-
-	WRW_Reserve(req->wrk, &req->sp->fd, req->vsl, req->t_prev);
-
-	/*
-	 * Send HTTP protocol header, unless interior ESI object
-	 */
-	if (!(req->res_mode & RES_ESI_CHILD))
-		req->resp_hdrbytes +=
-		    HTTP1_Write(req->wrk, req->resp, HTTP1_Resp);
-
-	if (req->res_mode & RES_CHUNKED)
-		WRW_Chunked(req->wrk);
-
-	if (!req->wantbody) {
-		/* This was a HEAD or conditional request */
-#if 0
-	XXX: Missing pretend GZIP for esi-children
-	} else if (req->res_mode & RES_ESI_CHILD && req->gzip_resp) {
-		ESI_DeliverChild(req);
-#endif
-	} else {
-		(void)VDP_bytes(req, VDP_FLUSH, VSB_data(req->synth_body),
-		    VSB_len(req->synth_body));
-		(void)VDP_bytes(req, VDP_FINISH,  NULL, 0);
-	}
-
-	if (req->res_mode & RES_CHUNKED && !(req->res_mode & RES_ESI_CHILD))
-		WRW_EndChunk(req->wrk);
-
-	if (V1D_FlushReleaseAcct(req) && req->sp->fd >= 0)
-		SES_Close(req->sp, SC_REM_CLOSE);
-}
diff --git a/bin/varnishtest/tests/r01284.vtc b/bin/varnishtest/tests/r01284.vtc
index d613ab8..7c0502d 100644
--- a/bin/varnishtest/tests/r01284.vtc
+++ b/bin/varnishtest/tests/r01284.vtc
@@ -44,8 +44,8 @@ client c1 {
 	delay 1
 } -run
 
-# Three failures, one for obj2, one for vcl_backend_error{}
-varnish v1 -expect SMA.Transient.c_fail == 2
+# Three failures, one for obj2, one for vcl_backend_error{}, one for synth objcore
+varnish v1 -expect SMA.Transient.c_fail == 3
 
 client c1 {
 	# Check that Varnish is still alive



More information about the varnish-commit mailing list