[master] eac60c9 Stash the predictive Vary: string in malloc space, we need to get the req workspace un-reserved before we can call vcl_lookup{} and we can't tell if we need the predictive Vary: until vcl_lookup{} tells us.

Poul-Henning Kamp phk at varnish-cache.org
Tue Aug 13 14:05:29 CEST 2013


commit eac60c98bcbe1bfcfa9f2cb425144f685a95ea51
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Tue Aug 13 12:04:38 2013 +0000

    Stash the predictive Vary: string in malloc space, we need to get
    the req workspace un-reserved before we can call vcl_lookup{} and
    we can't tell if we need the predictive Vary: until vcl_lookup{}
    tells us.

diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h
index eaaffb7..02d5b21 100644
--- a/bin/varnishd/cache/cache.h
+++ b/bin/varnishd/cache/cache.h
@@ -1043,7 +1043,8 @@ int VRY_Create(struct busyobj *bo, struct vsb **psb);
 int VRY_Match(struct req *, const uint8_t *vary);
 void VRY_Validate(const uint8_t *vary);
 void VRY_Prep(struct req *);
-void VRY_Finish(struct req *req, struct busyobj *bo);
+enum vry_finish_flag { KEEP, DISCARD };
+void VRY_Finish(struct req *req, enum vry_finish_flag);
 
 /* cache_vcl.c */
 void VCL_Init(void);
diff --git a/bin/varnishd/cache/cache_busyobj.c b/bin/varnishd/cache/cache_busyobj.c
index a23c791..962cc3c 100644
--- a/bin/varnishd/cache/cache_busyobj.c
+++ b/bin/varnishd/cache/cache_busyobj.c
@@ -197,6 +197,9 @@ VBO_DerefBusyObj(struct worker *wrk, struct busyobj **pbo)
 
 	VCL_Rel(&bo->vcl);
 
+	if (bo->vary != NULL)
+		free(bo->vary);
+
 	memset(&bo->refcount, 0,
 	    sizeof *bo - offsetof(struct busyobj, refcount));
 
diff --git a/bin/varnishd/cache/cache_req_fsm.c b/bin/varnishd/cache/cache_req_fsm.c
index cd55a7a..be3b147 100644
--- a/bin/varnishd/cache/cache_req_fsm.c
+++ b/bin/varnishd/cache/cache_req_fsm.c
@@ -440,6 +440,11 @@ cnt_lookup(struct worker *wrk, struct req *req)
 		return (REQ_FSM_DISEMBARK);
 	}
 
+	if (boc == NULL)
+		VRY_Finish(req, DISCARD);
+	else
+		VRY_Finish(req, KEEP);
+
 	AZ(req->objcore);
 	if (lr == HSH_MISS) {
 		/* Found nothing */
@@ -463,7 +468,6 @@ cnt_lookup(struct worker *wrk, struct req *req)
 		AZ(boc);
 		(void)HSH_Deref(&wrk->stats, oc, NULL);
 		req->objcore = NULL;
-		VRY_Finish(req, NULL);
 		wrk->stats.cache_hitpass++;
 		req->req_step = R_STP_PASS;
 		return (REQ_FSM_MORE);
@@ -492,6 +496,8 @@ cnt_lookup(struct worker *wrk, struct req *req)
 		VSLb(req->vsl, SLT_Debug, "XXX EXPBUSY drop boc\n");
 		(void)HSH_Deref(&wrk->stats, boc, NULL);
 		boc = NULL;
+		free(req->vary_b);
+		req->vary_b = NULL;
 		break;
 	case HSH_HIT:
 		/* Found hit */
@@ -512,8 +518,6 @@ cnt_lookup(struct worker *wrk, struct req *req)
 	CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC);
 	req->obj = o;
 
-	VRY_Finish(req, NULL);
-
 	wrk->stats.cache_hit++;
 	VSLb(req->vsl, SLT_Hit, "%u", req->obj->vxid);
 
@@ -580,7 +584,8 @@ cnt_miss(struct worker *wrk, struct req *req)
 	bo = VBO_GetBusyObj(wrk, req);
 	CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
 	req->busyobj = bo;
-	VRY_Finish(req, bo);
+	bo->vary = req->vary_b;
+	req->vary_b = NULL;
 
 	VCL_miss_method(req->vcl, wrk, req, NULL, req->http->ws);
 	switch (wrk->handling) {
@@ -886,7 +891,7 @@ cnt_purge(struct worker *wrk, struct req *req)
 	assert (lr == HSH_MISS);
 	AZ(oc);
 	CHECK_OBJ_NOTNULL(boc, OBJCORE_MAGIC);
-	VRY_Finish(req, NULL);
+	VRY_Finish(req, DISCARD);
 
 	HSH_Purge(wrk, boc->objhead, 0, 0);
 
diff --git a/bin/varnishd/cache/cache_vary.c b/bin/varnishd/cache/cache_vary.c
index 1ec8548..08736c6 100644
--- a/bin/varnishd/cache/cache_vary.c
+++ b/bin/varnishd/cache/cache_vary.c
@@ -56,6 +56,8 @@
 
 #include "config.h"
 
+#include <stdlib.h>
+
 #include "cache.h"
 
 #include "vct.h"
@@ -213,6 +215,9 @@ vry_cmp(const uint8_t *v1, const uint8_t *v2)
 
 /**********************************************************************
  * Prepare predictive vary string
+ *
+ * XXX: Strictly speaking vary_b and vary_e could be replaced with
+ * XXX: req->ws->{f,r}.   Space in struct req vs. code-readability...
  */
 
 void
@@ -238,24 +243,22 @@ VRY_Prep(struct req *req)
  */
 
 void
-VRY_Finish(struct req *req, struct busyobj *bo)
+VRY_Finish(struct req *req, enum vry_finish_flag flg)
 {
-
-	if (bo != NULL) {
-		CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
-		VRY_Validate(req->vary_b);
-		if (req->vary_l != NULL) {
-			bo->vary = WS_Copy(bo->ws,
-			    req->vary_b, req->vary_l - req->vary_b);
-			AN(bo->vary);
-			VRY_Validate(bo->vary);
-		} else
-			bo->vary = NULL;
+	uint8_t *p = NULL;
+
+	VRY_Validate(req->vary_b);
+	if (flg == KEEP && req->vary_l != NULL) {
+		p = malloc(req->vary_l - req->vary_b);
+		if (p != NULL) {
+			memcpy(p, req->vary_b, req->vary_l - req->vary_b);
+			VRY_Validate(p);
+		}
 	}
 	WS_Release(req->ws, 0);
-	req->vary_b = NULL;
 	req->vary_l = NULL;
 	req->vary_e = NULL;
+	req->vary_b = p;
 }
 
 /**********************************************************************



More information about the varnish-commit mailing list