Commit eac60c98 authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

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.
parent df22bd22
......@@ -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);
......
......@@ -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));
......
......@@ -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);
......
......@@ -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;
}
/**********************************************************************
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment