[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