[master] 2bd280a34 cache_transport: change vtr_deliver_f to return vtr_deliver_e

Nils Goroll nils.goroll at uplex.de
Mon Nov 25 17:30:04 UTC 2024


commit 2bd280a341213b7a8bf66c5a1c0ec52d9abf90d5
Author: Nils Goroll <nils.goroll at uplex.de>
Date:   Fri Nov 1 16:13:55 2024 +0100

    cache_transport: change vtr_deliver_f to return vtr_deliver_e
    
    This allows the transport's delivery function to disembark the thread by
    returning VTR_D_DISEMBARK. In this case, CNT_Request() needs to be called at a
    later time to continue.
    
    It is the vtr_deliver_f's responsibility to clear req->wrk because only it can
    ensure proper synchronization with another thread which might already be
    running.

diff --git a/bin/varnishd/cache/cache_esi_deliver.c b/bin/varnishd/cache/cache_esi_deliver.c
index 158251337..6a336b549 100644
--- a/bin/varnishd/cache/cache_esi_deliver.c
+++ b/bin/varnishd/cache/cache_esi_deliver.c
@@ -867,7 +867,7 @@ ved_close(struct req *req, int error)
 
 /*--------------------------------------------------------------------*/
 
-static void v_matchproto_(vtr_deliver_f)
+static enum vtr_deliver_e v_matchproto_(vtr_deliver_f)
 ved_deliver(struct req *req, int wantbody)
 {
 	int i = 0;
@@ -888,17 +888,17 @@ ved_deliver(struct req *req, int wantbody)
 	if (FEATURE(FEATURE_ESI_INCLUDE_ONERROR) &&
 	    status != 200 && status != 204) {
 		ved_close(req, ecx->abrt);
-		return;
+		return (VTR_D_DONE);
 	}
 
 	if (wantbody == 0) {
 		ved_close(req, 0);
-		return;
+		return (VTR_D_DONE);
 	}
 
 	if (req->boc == NULL && ObjGetLen(req->wrk, req->objcore) == 0) {
 		ved_close(req, 0);
-		return;
+		return (VTR_D_DONE);
 	}
 
 	if (http_GetHdr(req->resp, H_Content_Encoding, &p))
@@ -922,7 +922,7 @@ ved_deliver(struct req *req, int wantbody)
 			 * XXX change error argument to 1
 			 */
 			ved_close(req, 0);
-			return;
+			return (VTR_D_DONE);
 		}
 
 		INIT_OBJ(foo, VED_FOO_MAGIC);
@@ -948,4 +948,5 @@ ved_deliver(struct req *req, int wantbody)
 		req->doclose = SC_REM_CLOSE;
 
 	ved_close(req, i && ecx->abrt ? 1 : 0);
+	return (VTR_D_DONE);
 }
diff --git a/bin/varnishd/cache/cache_req_fsm.c b/bin/varnishd/cache/cache_req_fsm.c
index bc4568911..bbcb3824f 100644
--- a/bin/varnishd/cache/cache_req_fsm.c
+++ b/bin/varnishd/cache/cache_req_fsm.c
@@ -430,6 +430,8 @@ cnt_synth(struct worker *wrk, struct req *req)
 static enum req_fsm_nxt v_matchproto_(req_state_f)
 cnt_transmit(struct worker *wrk, struct req *req)
 {
+	enum req_fsm_nxt nxt = REQ_FSM_MORE;
+	enum vtr_deliver_e dnxt;
 	uint16_t status;
 	int sendbody, head;
 	intmax_t clval;
@@ -441,6 +443,7 @@ cnt_transmit(struct worker *wrk, struct req *req)
 	AZ(req->stale_oc);
 	AZ(req->res_mode);
 	AZ(req->boc);
+	req->req_step = R_STP_FINISH;
 
 	/* Grab a ref to the bo if there is one (=streaming) */
 	req->boc = HSH_RefBoc(req->objcore);
@@ -498,10 +501,13 @@ cnt_transmit(struct worker *wrk, struct req *req)
 		}
 		if (req->resp_len == 0)
 			sendbody = 0;
-		req->transport->deliver(req, sendbody);
+		dnxt = req->transport->deliver(req, sendbody);
+		if (dnxt == VTR_D_DISEMBARK)
+			nxt = REQ_FSM_DISEMBARK;
+		else
+			assert(dnxt == VTR_D_DONE);
 	}
-	req->req_step = R_STP_FINISH;
-	return (REQ_FSM_MORE);
+	return (nxt);
 }
 
 static enum req_fsm_nxt v_matchproto_(req_state_f)
@@ -1180,6 +1186,7 @@ CNT_Request(struct req *req)
 	 */
 	assert(
 	    req->req_step == R_STP_LOOKUP ||
+	    req->req_step == R_STP_FINISH ||
 	    req->req_step == R_STP_TRANSPORT);
 
 	AN(VXID_TAG(req->vsl->wid) & VSL_CLIENTMARKER);
diff --git a/bin/varnishd/cache/cache_transport.h b/bin/varnishd/cache/cache_transport.h
index d5cd3d428..6fd297739 100644
--- a/bin/varnishd/cache/cache_transport.h
+++ b/bin/varnishd/cache/cache_transport.h
@@ -38,7 +38,13 @@
 struct req;
 struct boc;
 
-typedef void vtr_deliver_f (struct req *, int sendbody);
+enum vtr_deliver_e {
+	VTR_D_INVAL = 0,
+	VTR_D_DONE = 1,
+	VTR_D_DISEMBARK
+};
+
+typedef enum vtr_deliver_e vtr_deliver_f (struct req *, int sendbody);
 typedef void vtr_req_body_f (struct req *);
 typedef void vtr_sess_panic_f (struct vsb *, const struct sess *);
 typedef void vtr_req_panic_f (struct vsb *, const struct req *);
diff --git a/bin/varnishd/http1/cache_http1.h b/bin/varnishd/http1/cache_http1.h
index 7aadb5cfa..85203295f 100644
--- a/bin/varnishd/http1/cache_http1.h
+++ b/bin/varnishd/http1/cache_http1.h
@@ -42,7 +42,7 @@ extern const int HTTP1_Req[3];
 extern const int HTTP1_Resp[3];
 
 /* cache_http1_deliver.c */
-void V1D_Deliver(struct req *, int sendbody);
+enum vtr_deliver_e V1D_Deliver(struct req *, int sendbody);
 
 /* cache_http1_pipe.c */
 struct v1p_acct {
diff --git a/bin/varnishd/http1/cache_http1_deliver.c b/bin/varnishd/http1/cache_http1_deliver.c
index ab3826a92..9015f3cc0 100644
--- a/bin/varnishd/http1/cache_http1_deliver.c
+++ b/bin/varnishd/http1/cache_http1_deliver.c
@@ -34,6 +34,7 @@
 #include "cache/cache_varnishd.h"
 #include "cache/cache_filter.h"
 #include "cache_http1.h"
+#include "cache/cache_transport.h"
 
 #include "vtcp.h"
 
@@ -67,7 +68,7 @@ v1d_error(struct req *req, struct v1l **v1lp, const char *msg)
 /*--------------------------------------------------------------------
  */
 
-void v_matchproto_(vtr_deliver_f)
+enum vtr_deliver_e v_matchproto_(vtr_deliver_f)
 V1D_Deliver(struct req *req, int sendbody)
 {
 	struct vrt_ctx ctx[1];
@@ -99,7 +100,7 @@ V1D_Deliver(struct req *req, int sendbody)
 
 	if (v1l == NULL) {
 		v1d_error(req, &v1l, "Failure to init v1d (workspace_thread overflow)");
-		return;
+		return (VTR_D_DONE);
 	}
 
 	if (sendbody) {
@@ -116,23 +117,23 @@ V1D_Deliver(struct req *req, int sendbody)
 		VCL_Req2Ctx(ctx, req);
 		if (VDP_Push(ctx, req->vdc, req->ws, VDP_v1l, v1l)) {
 			v1d_error(req, &v1l, "Failure to push v1d processor");
-			return;
+			return (VTR_D_DONE);
 		}
 	}
 
 	if (WS_Overflowed(req->ws)) {
 		v1d_error(req, &v1l, "workspace_client overflow");
-		return;
+		return (VTR_D_DONE);
 	}
 
 	if (WS_Overflowed(req->sp->ws)) {
 		v1d_error(req, &v1l, "workspace_session overflow");
-		return;
+		return (VTR_D_DONE);
 	}
 
 	if (WS_Overflowed(req->wrk->aws)) {
 		v1d_error(req, &v1l, "workspace_thread overflow");
-		return;
+		return (VTR_D_DONE);
 	}
 
 	hdrbytes = HTTP1_Write(v1l, req->resp, HTTP1_Resp);
@@ -156,4 +157,5 @@ V1D_Deliver(struct req *req, int sendbody)
 		sc = SC_REM_CLOSE;
 	if (sc != SC_NULL)
 		Req_Fail(req, sc);
+	return (VTR_D_DONE);
 }
diff --git a/bin/varnishd/http2/cache_http2_deliver.c b/bin/varnishd/http2/cache_http2_deliver.c
index b80b91924..401301243 100644
--- a/bin/varnishd/http2/cache_http2_deliver.c
+++ b/bin/varnishd/http2/cache_http2_deliver.c
@@ -292,7 +292,7 @@ h2_build_headers(struct vsb *resp, struct req *req)
 	}
 }
 
-void v_matchproto_(vtr_deliver_f)
+enum vtr_deliver_e v_matchproto_(vtr_deliver_f)
 h2_deliver(struct req *req, int sendbody)
 {
 	size_t sz;
@@ -349,4 +349,5 @@ h2_deliver(struct req *req, int sendbody)
 	}
 
 	req->acct.resp_bodybytes += VDP_Close(req->vdc, req->objcore, req->boc);
+	return (VTR_D_DONE);
 }


More information about the varnish-commit mailing list