Commit 2e849df0 authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Rework/simplify the obj/objcore dereference logic.




git-svn-id: http://www.varnish-cache.org/svn/trunk/varnish-cache@5551 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent 6b6e5f25
......@@ -534,7 +534,7 @@ ban_lurker(struct sess *sp, void *priv)
o = oc_getobj(sp->wrk, oc);
i = ban_check_object(o, sp, 0);
WSP(sp, SLT_Debug, "lurker: %p %g %d", oc, o->ttl, i);
HSH_Deref(sp->wrk, &o);
(void)HSH_Deref(sp->wrk, NULL, &o);
TIM_sleep(params->ban_lurker_sleep);
}
NEEDLESS_RETURN(NULL);
......
......@@ -203,7 +203,7 @@ cnt_deliver(struct sess *sp)
RES_WriteObj(sp);
AZ(sp->wrk->wfd);
HSH_Deref(sp->wrk, &sp->obj);
(void)HSH_Deref(sp->wrk, NULL, &sp->obj);
sp->wrk->resp = NULL;
sp->step = STP_DONE;
return (0);
......@@ -471,7 +471,7 @@ cnt_fetch(struct sess *sp)
if (sp->objcore != NULL) {
CHECK_OBJ_NOTNULL(sp->objhead, OBJHEAD_MAGIC);
CHECK_OBJ_NOTNULL(sp->objcore, OBJCORE_MAGIC);
HSH_DerefObjCore(sp->wrk, sp->objcore);
AZ(HSH_Deref(sp->wrk, sp->objcore, NULL));
sp->objhead = NULL;
sp->objcore = NULL;
}
......@@ -532,7 +532,7 @@ cnt_fetch(struct sess *sp)
sp->wrk->cacheable = 0;
} else if (!sp->wrk->cacheable) {
if (sp->objhead != NULL) {
HSH_DerefObjCore(sp->wrk, sp->objcore);
AZ(HSH_Deref(sp->wrk, sp->objcore, NULL));
sp->objhead = NULL;
sp->objcore = NULL;
}
......@@ -751,7 +751,7 @@ cnt_hit(struct sess *sp)
}
/* Drop our object, we won't need it */
HSH_Deref(sp->wrk, &sp->obj);
(void)HSH_Deref(sp->wrk, NULL, &sp->obj);
sp->objcore = NULL;
AZ(sp->objhead);
......@@ -844,7 +844,7 @@ cnt_lookup(struct sess *sp)
if (oc->flags & OC_F_PASS) {
sp->wrk->stats.cache_hitpass++;
WSP(sp, SLT_HitPass, "%u", sp->obj->xid);
HSH_Deref(sp->wrk, &sp->obj);
(void)HSH_Deref(sp->wrk, NULL, &sp->obj);
sp->objcore = NULL;
sp->objhead = NULL;
sp->step = STP_PASS;
......@@ -901,13 +901,13 @@ cnt_miss(struct sess *sp)
VCL_miss_method(sp);
switch(sp->handling) {
case VCL_RET_ERROR:
HSH_DerefObjCore(sp->wrk, sp->objcore);
AZ(HSH_Deref(sp->wrk, sp->objcore, NULL));
sp->objhead = NULL;
sp->objcore = NULL;
sp->step = STP_ERROR;
return (0);
case VCL_RET_PASS:
HSH_DerefObjCore(sp->wrk, sp->objcore);
AZ(HSH_Deref(sp->wrk, sp->objcore, NULL));
sp->objhead = NULL;
sp->objcore = NULL;
sp->step = STP_PASS;
......@@ -916,7 +916,7 @@ cnt_miss(struct sess *sp)
sp->step = STP_FETCH;
return (0);
case VCL_RET_RESTART:
HSH_DerefObjCore(sp->wrk, sp->objcore);
AZ(HSH_Deref(sp->wrk, sp->objcore, NULL));
sp->objhead = NULL;
sp->objcore = NULL;
INCOMPL();
......
......@@ -292,13 +292,13 @@ exp_timer(struct sess *sp, void *priv)
AN(o);
WSL(sp->wrk, SLT_ExpKill, 0, "%u %d",
o->xid, (int)(o->ttl - t));
HSH_Deref(sp->wrk, &o);
(void)HSH_Deref(sp->wrk, NULL, &o);
} else {
WSL(sp->wrk, SLT_ExpKill, 1, "-1 %d",
(int)(oc->timer_when - t));
oc->priv = NULL;
HSH_DerefObjCore(sp->wrk, oc);
AZ(HSH_Deref(sp->wrk, oc, NULL));
sp->wrk->stats.n_vampireobject--;
}
}
......@@ -354,7 +354,7 @@ EXP_NukeOne(const struct sess *sp, const struct lru *lru)
o = oc_getobj(sp->wrk, oc);
WSL(sp->wrk, SLT_ExpKill, 0, "%u LRU", o->xid);
HSH_Deref(sp->wrk, &o);
(void)HSH_Deref(sp->wrk, NULL, &o);
return (1);
}
......
......@@ -585,7 +585,7 @@ HSH_Purge(const struct sess *sp, struct objhead *oh, double ttl, double grace)
if (!isnan(grace))
o->grace = grace;
EXP_Rearm(o);
HSH_Deref(sp->wrk, &o);
(void)HSH_Deref(sp->wrk, NULL, &o);
}
WS_Release(sp->wrk->ws, 0);
}
......@@ -613,7 +613,7 @@ HSH_Drop(struct sess *sp)
o->cacheable = 0;
if (o->objcore != NULL) /* Pass has no objcore */
HSH_Unbusy(sp);
HSH_Deref(sp->wrk, &sp->obj);
(void)HSH_Deref(sp->wrk, NULL, &sp->obj);
}
void
......@@ -662,28 +662,84 @@ HSH_Ref(struct objcore *oc)
Lck_Unlock(&oh->mtx);
}
void
HSH_DerefObjCore(struct worker *wrk, struct objcore *oc)
/*******************************************************************
* Dereference objcore and or object
*
* Can deal with:
* bare objcore (incomplete fetch)
* bare object (pass)
* object with objcore
* XXX later: objcore with object (?)
*
* But you can only supply one of the two arguments at a time.
*
* Returns zero if target was destroyed.
*/
int
HSH_Deref(struct worker *w, struct objcore *oc, struct object **oo)
{
struct object *o;
struct objhead *oh;
unsigned r;
CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
oh = oc->objhead;
CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC);
if (oc != NULL) {
AZ(oo);
o = NULL;
AZ(oc->priv); // XXX: for now
} else {
AZ(oc);
AN(oo);
o = *oo;
*oo = NULL;
CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC);
oc = o->objcore;
}
AZ(oc->priv);
if (oc != NULL) {
CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
oh = oc->objhead;
CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC);
Lck_Lock(&oh->mtx);
VTAILQ_REMOVE(&oh->objcs, oc, list);
if (oc->flags & OC_F_BUSY)
hsh_rush(oh);
Lck_Unlock(&oh->mtx);
oc->objhead = NULL;
assert(oh->refcnt > 0);
Lck_Lock(&oh->mtx);
assert(oh->refcnt > 0);
assert(oc->refcnt > 0);
r = --oc->refcnt;
if (!r)
VTAILQ_REMOVE(&oh->objcs, oc, list);
if (oc->flags & OC_F_BUSY)
hsh_rush(oh);
Lck_Unlock(&oh->mtx);
if (r != 0)
return (r);
}
if (o != NULL) {
if (oc != NULL)
BAN_DestroyObj(o);
AZ(o->ban);
DSL(0x40, SLT_Debug, 0, "Object %u workspace min free %u",
o->xid, WS_Free(o->ws_o));
if (o->esidata != NULL)
ESI_Destroy(o);
if (oc != NULL)
oc_freeobj(oc);
w->stats.n_object--;
}
if (oc == NULL)
return (0);
AN(oh);
FREE_OBJ(oc);
wrk->stats.n_objectcore--;
if (!hash->deref(oh))
HSH_DeleteObjHead(wrk, oh);
w->stats.n_objectcore--;
/* Drop our ref on the objhead */
assert(oh->refcnt > 0);
if (hash->deref(oh))
return (0);
HSH_DeleteObjHead(w, oh);
return (0);
}
/*******************************************************************
......@@ -722,67 +778,6 @@ HSH_FindBan(const struct sess *sp, struct objcore **oc)
*oc = oc2;
}
void
HSH_Deref(struct worker *w, struct object **oo)
{
struct object *o;
struct objhead *oh;
struct objcore *oc;
unsigned r;
AN(oo);
o = *oo;
*oo = NULL;
CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC);
oc = o->objcore;
if (oc == NULL) {
r = 0;
oh = NULL;
} else {
CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
oh = oc->objhead;
CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC);
Lck_Lock(&oh->mtx);
assert(oh->refcnt > 0);
assert(oc->refcnt > 0);
r = --oc->refcnt;
if (!r)
VTAILQ_REMOVE(&oh->objcs, oc, list);
hsh_rush(oh);
Lck_Unlock(&oh->mtx);
}
/* If still referenced, done */
if (r != 0)
return;
if (oh != NULL)
BAN_DestroyObj(o);
AZ(o->ban);
DSL(0x40, SLT_Debug, 0, "Object %u workspace min free %u",
o->xid, WS_Free(o->ws_o));
if (o->esidata != NULL)
ESI_Destroy(o);
if (o->objcore != NULL)
oc_freeobj(o->objcore);
o = NULL;
w->stats.n_object--;
if (oc == NULL) {
AZ(oh);
return;
}
AN(oh);
FREE_OBJ(oc);
w->stats.n_objectcore--;
/* Drop our ref on the objhead */
assert(oh->refcnt > 0);
if (hash->deref(oh))
return;
HSH_DeleteObjHead(w, oh);
}
void
HSH_Init(void)
......
......@@ -61,7 +61,6 @@ void HSH_Drop(struct sess *sp);
double HSH_Grace(double g);
void HSH_Init(void);
void HSH_AddString(const struct sess *sp, const char *str);
void HSH_DerefObjCore(struct worker *sp, struct objcore *oc);
void HSH_FindBan(const struct sess *sp, struct objcore **oc);
struct objcore *HSH_Insert(const struct sess *sp);
void HSH_Purge(const struct sess *, struct objhead *, double ttl, double grace);
......@@ -94,7 +93,7 @@ struct objhead {
};
void HSH_DeleteObjHead(struct worker *w, struct objhead *oh);
void HSH_Deref(struct worker *w, struct object **o);
int HSH_Deref(struct worker *w, struct objcore *oc, struct object **o);
#endif /* VARNISH_CACHE_CHILD */
extern const struct hash_slinger hsl_slinger;
......
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