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

Postpone allocating the actual object until we have received the

headers and vcl_fetch{} has told os what to do with it.



git-svn-id: http://www.varnish-cache.org/svn/trunk/varnish-cache@3845 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent b1900783
......@@ -396,6 +396,7 @@ struct sess {
struct vbe_conn *vbe;
struct bereq *bereq;
struct object *obj;
struct objcore *objcore;
struct objhead *objhead;
struct VCL_conf *vcl;
......
......@@ -378,6 +378,7 @@ cnt_fetch(struct sess *sp)
{
int i;
struct http *hp, *hp2;
struct object *o;
char *b;
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
......@@ -387,9 +388,6 @@ cnt_fetch(struct sess *sp)
AN(sp->director);
AZ(sp->vbe);
sp->obj->xid = sp->xid;
WS_Assert(sp->obj->ws_o);
i = FetchHdr(sp);
/*
......@@ -402,7 +400,11 @@ cnt_fetch(struct sess *sp)
sp->err_code = 503;
sp->step = STP_ERROR;
VBE_free_bereq(&sp->bereq);
HSH_Drop(sp);
if (sp->objhead) {
CHECK_OBJ_NOTNULL(sp->objhead, OBJHEAD_MAGIC);
CHECK_OBJ_NOTNULL(sp->objcore, OBJCORE_MAGIC);
HSH_DerefObjCore(sp);
}
AZ(sp->obj);
return (0);
}
......@@ -440,6 +442,21 @@ cnt_fetch(struct sess *sp)
VCL_fetch_method(sp);
o = HSH_NewObject(sp, sp->handling != VCL_RET_DELIVER);
if (sp->objhead != NULL) {
CHECK_OBJ_NOTNULL(sp->objhead, OBJHEAD_MAGIC);
CHECK_OBJ_NOTNULL(sp->objcore, OBJCORE_MAGIC);
sp->objcore->obj = o;
o->objcore = sp->objcore;
o->objhead = sp->objhead;
sp->objhead = NULL; /* refcnt follows pointer. */
}
sp->obj = o;
BAN_NewObj(sp->obj);
sp->obj->xid = sp->xid;
sp->obj->response = sp->err_code;
sp->obj->cacheable = sp->bereq->cacheable;
sp->obj->ttl = sp->bereq->ttl;
......@@ -448,6 +465,7 @@ cnt_fetch(struct sess *sp)
sp->obj->cacheable = 0;
sp->obj->age = sp->bereq->age;
sp->obj->entered = sp->bereq->entered;
WS_Assert(sp->obj->ws_o);
/* Filter into object */
hp = sp->bereq->beresp;
......@@ -602,6 +620,9 @@ cnt_hit(struct sess *sp)
/* Drop our object, we won't need it */
HSH_Deref(sp->wrk, &sp->obj);
sp->objcore = NULL;
AZ(sp->objhead);
sp->objhead = NULL;
switch(sp->handling) {
case VCL_RET_PASS:
......@@ -675,6 +696,7 @@ cnt_lookup(struct sess *sp)
return (1);
}
CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC);
/* If we inserted a new object it's a miss */
......@@ -682,14 +704,8 @@ cnt_lookup(struct sess *sp)
VSL_stats->cache_miss++;
AZ(oc->obj);
o = HSH_NewObject(sp, 0);
o->objhead = oh;
o->objcore = oc;
oc->obj = o;
sp->obj = o;
BAN_NewObj(o);
sp->objhead = oh;
sp->objcore = oc;
sp->step = STP_MISS;
return (0);
}
......@@ -702,6 +718,8 @@ cnt_lookup(struct sess *sp)
VSL_stats->cache_hitpass++;
WSP(sp, SLT_HitPass, "%u", sp->obj->xid);
HSH_Deref(sp->wrk, &sp->obj);
sp->objcore = NULL;
sp->objhead = NULL;
sp->step = STP_PASS;
return (0);
}
......@@ -740,27 +758,29 @@ cnt_miss(struct sess *sp)
{
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC);
CHECK_OBJ_NOTNULL(sp->vcl, VCL_CONF_MAGIC);
AZ(sp->obj);
AN(sp->objcore);
AN(sp->objhead);
http_FilterHeader(sp, HTTPH_R_FETCH);
VCL_miss_method(sp);
AZ(sp->obj->cacheable);
switch(sp->handling) {
case VCL_RET_ERROR:
HSH_Drop(sp);
HSH_DerefObjCore(sp);
VBE_free_bereq(&sp->bereq);
sp->step = STP_ERROR;
return (0);
case VCL_RET_PASS:
HSH_Drop(sp);
VBE_free_bereq(&sp->bereq);
HSH_DerefObjCore(sp);
sp->step = STP_PASS;
return (0);
case VCL_RET_FETCH:
sp->step = STP_FETCH;
return (0);
case VCL_RET_RESTART:
HSH_DerefObjCore(sp);
VBE_free_bereq(&sp->bereq);
INCOMPL();
default:
......@@ -818,8 +838,6 @@ cnt_pass(struct sess *sp)
}
assert(sp->handling == VCL_RET_PASS);
sp->acct_req.pass++;
HSH_Prealloc(sp);
sp->obj = HSH_NewObject(sp, 1);
sp->sendbody = 1;
sp->step = STP_FETCH;
return (0);
......
......@@ -319,11 +319,14 @@ FetchHdr(struct sess *sp)
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
CHECK_OBJ_NOTNULL(sp->wrk, WORKER_MAGIC);
CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC);
CHECK_OBJ_NOTNULL(sp->bereq, BEREQ_MAGIC);
AN(sp->director);
if (sp->obj->objcore != NULL) /* pass has no objcore */
AN(ObjIsBusy(sp->obj));
AZ(sp->obj);
if (sp->objcore != NULL) { /* pass has no objcore */
CHECK_OBJ_NOTNULL(sp->objcore, OBJCORE_MAGIC);
AN(sp->objhead); /* details in hash_slinger.h */
AN(sp->objcore->flags & OC_F_BUSY);
}
AN(sp->bereq);
/* Transmit request */
......
......@@ -308,6 +308,8 @@ HSH_Lookup(struct sess *sp, struct objhead **poh)
busy_oc = NULL;
grace_oc = NULL;
VTAILQ_FOREACH(oc, &oh->objcs, list) {
/* Must be at least our own ref + the objcore we examine */
assert(oh->refcnt > 1);
CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
if (oc->flags & OC_F_BUSY) {
......@@ -359,6 +361,7 @@ HSH_Lookup(struct sess *sp, struct objhead **poh)
o->refcnt++;
if (o->hits < INT_MAX)
o->hits++;
assert(oh->refcnt > 1);
Lck_Unlock(&oh->mtx);
assert(hash->deref(oh));
*poh = oh;
......@@ -454,10 +457,10 @@ HSH_Unbusy(const struct sess *sp)
Lck_Lock(&oh->mtx);
}
o->objcore->flags &= ~OC_F_BUSY;
if (oh != NULL)
if (oh != NULL) {
hsh_rush(oh);
if (oh != NULL)
Lck_Unlock(&oh->mtx);
}
}
void
......@@ -474,6 +477,29 @@ HSH_Ref(struct object *o)
Lck_Unlock(&oh->mtx);
}
void
HSH_DerefObjCore(struct sess *sp)
{
struct objhead *oh;
struct objcore *oc;
CHECK_OBJ_NOTNULL(sp->objhead, OBJHEAD_MAGIC);
CHECK_OBJ_NOTNULL(sp->objcore, OBJCORE_MAGIC);
oh = sp->objhead;
sp->objhead = NULL;
oc = sp->objcore;
sp->objcore = NULL;
Lck_Lock(&oh->mtx);
VTAILQ_REMOVE(&oh->objcs, oc, list);
Lck_Unlock(&oh->mtx);
assert(oh->refcnt > 0);
if (hash->deref(oh))
return;
HSH_DeleteObjHead(sp->wrk, oh);
}
void
HSH_Deref(const struct worker *w, struct object **oo)
{
......@@ -492,7 +518,7 @@ HSH_Deref(const struct worker *w, struct object **oo)
assert(o->refcnt > 0);
r = --o->refcnt;
} else {
CHECK_OBJ(oh, OBJHEAD_MAGIC);
CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC);
oc = o->objcore;
CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
......@@ -525,6 +551,7 @@ HSH_Deref(const struct worker *w, struct object **oo)
STV_free(o->objstore);
else
FREE_OBJ(o);
o = NULL;
w->stats->n_object--;
if (oh == NULL) {
......@@ -540,6 +567,7 @@ HSH_Deref(const struct worker *w, struct object **oo)
HSH_DeleteObjHead(w, oh);
}
void
HSH_Init(void)
{
......
......@@ -63,6 +63,7 @@ double HSH_Grace(double g);
void HSH_Init(void);
void HSH_AddString(struct sess *sp, const char *str);
void HSH_Prepare(struct sess *sp, unsigned hashcount);
void HSH_DerefObjCore(struct sess *sp);
#ifdef VARNISH_CACHE_CHILD
......
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