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) ...@@ -534,7 +534,7 @@ ban_lurker(struct sess *sp, void *priv)
o = oc_getobj(sp->wrk, oc); o = oc_getobj(sp->wrk, oc);
i = ban_check_object(o, sp, 0); i = ban_check_object(o, sp, 0);
WSP(sp, SLT_Debug, "lurker: %p %g %d", oc, o->ttl, i); 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); TIM_sleep(params->ban_lurker_sleep);
} }
NEEDLESS_RETURN(NULL); NEEDLESS_RETURN(NULL);
......
...@@ -203,7 +203,7 @@ cnt_deliver(struct sess *sp) ...@@ -203,7 +203,7 @@ cnt_deliver(struct sess *sp)
RES_WriteObj(sp); RES_WriteObj(sp);
AZ(sp->wrk->wfd); AZ(sp->wrk->wfd);
HSH_Deref(sp->wrk, &sp->obj); (void)HSH_Deref(sp->wrk, NULL, &sp->obj);
sp->wrk->resp = NULL; sp->wrk->resp = NULL;
sp->step = STP_DONE; sp->step = STP_DONE;
return (0); return (0);
...@@ -471,7 +471,7 @@ cnt_fetch(struct sess *sp) ...@@ -471,7 +471,7 @@ cnt_fetch(struct sess *sp)
if (sp->objcore != NULL) { if (sp->objcore != NULL) {
CHECK_OBJ_NOTNULL(sp->objhead, OBJHEAD_MAGIC); CHECK_OBJ_NOTNULL(sp->objhead, OBJHEAD_MAGIC);
CHECK_OBJ_NOTNULL(sp->objcore, OBJCORE_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->objhead = NULL;
sp->objcore = NULL; sp->objcore = NULL;
} }
...@@ -532,7 +532,7 @@ cnt_fetch(struct sess *sp) ...@@ -532,7 +532,7 @@ cnt_fetch(struct sess *sp)
sp->wrk->cacheable = 0; sp->wrk->cacheable = 0;
} else if (!sp->wrk->cacheable) { } else if (!sp->wrk->cacheable) {
if (sp->objhead != NULL) { if (sp->objhead != NULL) {
HSH_DerefObjCore(sp->wrk, sp->objcore); AZ(HSH_Deref(sp->wrk, sp->objcore, NULL));
sp->objhead = NULL; sp->objhead = NULL;
sp->objcore = NULL; sp->objcore = NULL;
} }
...@@ -751,7 +751,7 @@ cnt_hit(struct sess *sp) ...@@ -751,7 +751,7 @@ cnt_hit(struct sess *sp)
} }
/* Drop our object, we won't need it */ /* 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; sp->objcore = NULL;
AZ(sp->objhead); AZ(sp->objhead);
...@@ -844,7 +844,7 @@ cnt_lookup(struct sess *sp) ...@@ -844,7 +844,7 @@ cnt_lookup(struct sess *sp)
if (oc->flags & OC_F_PASS) { if (oc->flags & OC_F_PASS) {
sp->wrk->stats.cache_hitpass++; sp->wrk->stats.cache_hitpass++;
WSP(sp, SLT_HitPass, "%u", sp->obj->xid); 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->objcore = NULL;
sp->objhead = NULL; sp->objhead = NULL;
sp->step = STP_PASS; sp->step = STP_PASS;
...@@ -901,13 +901,13 @@ cnt_miss(struct sess *sp) ...@@ -901,13 +901,13 @@ cnt_miss(struct sess *sp)
VCL_miss_method(sp); VCL_miss_method(sp);
switch(sp->handling) { switch(sp->handling) {
case VCL_RET_ERROR: case VCL_RET_ERROR:
HSH_DerefObjCore(sp->wrk, sp->objcore); AZ(HSH_Deref(sp->wrk, sp->objcore, NULL));
sp->objhead = NULL; sp->objhead = NULL;
sp->objcore = NULL; sp->objcore = NULL;
sp->step = STP_ERROR; sp->step = STP_ERROR;
return (0); return (0);
case VCL_RET_PASS: case VCL_RET_PASS:
HSH_DerefObjCore(sp->wrk, sp->objcore); AZ(HSH_Deref(sp->wrk, sp->objcore, NULL));
sp->objhead = NULL; sp->objhead = NULL;
sp->objcore = NULL; sp->objcore = NULL;
sp->step = STP_PASS; sp->step = STP_PASS;
...@@ -916,7 +916,7 @@ cnt_miss(struct sess *sp) ...@@ -916,7 +916,7 @@ cnt_miss(struct sess *sp)
sp->step = STP_FETCH; sp->step = STP_FETCH;
return (0); return (0);
case VCL_RET_RESTART: case VCL_RET_RESTART:
HSH_DerefObjCore(sp->wrk, sp->objcore); AZ(HSH_Deref(sp->wrk, sp->objcore, NULL));
sp->objhead = NULL; sp->objhead = NULL;
sp->objcore = NULL; sp->objcore = NULL;
INCOMPL(); INCOMPL();
......
...@@ -292,13 +292,13 @@ exp_timer(struct sess *sp, void *priv) ...@@ -292,13 +292,13 @@ exp_timer(struct sess *sp, void *priv)
AN(o); AN(o);
WSL(sp->wrk, SLT_ExpKill, 0, "%u %d", WSL(sp->wrk, SLT_ExpKill, 0, "%u %d",
o->xid, (int)(o->ttl - t)); o->xid, (int)(o->ttl - t));
HSH_Deref(sp->wrk, &o); (void)HSH_Deref(sp->wrk, NULL, &o);
} else { } else {
WSL(sp->wrk, SLT_ExpKill, 1, "-1 %d", WSL(sp->wrk, SLT_ExpKill, 1, "-1 %d",
(int)(oc->timer_when - t)); (int)(oc->timer_when - t));
oc->priv = NULL; oc->priv = NULL;
HSH_DerefObjCore(sp->wrk, oc); AZ(HSH_Deref(sp->wrk, oc, NULL));
sp->wrk->stats.n_vampireobject--; sp->wrk->stats.n_vampireobject--;
} }
} }
...@@ -354,7 +354,7 @@ EXP_NukeOne(const struct sess *sp, const struct lru *lru) ...@@ -354,7 +354,7 @@ EXP_NukeOne(const struct sess *sp, const struct lru *lru)
o = oc_getobj(sp->wrk, oc); o = oc_getobj(sp->wrk, oc);
WSL(sp->wrk, SLT_ExpKill, 0, "%u LRU", o->xid); WSL(sp->wrk, SLT_ExpKill, 0, "%u LRU", o->xid);
HSH_Deref(sp->wrk, &o); (void)HSH_Deref(sp->wrk, NULL, &o);
return (1); return (1);
} }
......
...@@ -585,7 +585,7 @@ HSH_Purge(const struct sess *sp, struct objhead *oh, double ttl, double grace) ...@@ -585,7 +585,7 @@ HSH_Purge(const struct sess *sp, struct objhead *oh, double ttl, double grace)
if (!isnan(grace)) if (!isnan(grace))
o->grace = grace; o->grace = grace;
EXP_Rearm(o); EXP_Rearm(o);
HSH_Deref(sp->wrk, &o); (void)HSH_Deref(sp->wrk, NULL, &o);
} }
WS_Release(sp->wrk->ws, 0); WS_Release(sp->wrk->ws, 0);
} }
...@@ -613,7 +613,7 @@ HSH_Drop(struct sess *sp) ...@@ -613,7 +613,7 @@ HSH_Drop(struct sess *sp)
o->cacheable = 0; o->cacheable = 0;
if (o->objcore != NULL) /* Pass has no objcore */ if (o->objcore != NULL) /* Pass has no objcore */
HSH_Unbusy(sp); HSH_Unbusy(sp);
HSH_Deref(sp->wrk, &sp->obj); (void)HSH_Deref(sp->wrk, NULL, &sp->obj);
} }
void void
...@@ -662,28 +662,84 @@ HSH_Ref(struct objcore *oc) ...@@ -662,28 +662,84 @@ HSH_Ref(struct objcore *oc)
Lck_Unlock(&oh->mtx); 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; struct objhead *oh;
unsigned r;
CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC); if (oc != NULL) {
oh = oc->objhead; AZ(oo);
CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC); 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); Lck_Lock(&oh->mtx);
VTAILQ_REMOVE(&oh->objcs, oc, list); assert(oh->refcnt > 0);
if (oc->flags & OC_F_BUSY) assert(oc->refcnt > 0);
hsh_rush(oh); r = --oc->refcnt;
Lck_Unlock(&oh->mtx); if (!r)
oc->objhead = NULL; VTAILQ_REMOVE(&oh->objcs, oc, list);
assert(oh->refcnt > 0); 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); FREE_OBJ(oc);
wrk->stats.n_objectcore--; w->stats.n_objectcore--;
if (!hash->deref(oh)) /* Drop our ref on the objhead */
HSH_DeleteObjHead(wrk, oh); 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) ...@@ -722,67 +778,6 @@ HSH_FindBan(const struct sess *sp, struct objcore **oc)
*oc = oc2; *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 void
HSH_Init(void) HSH_Init(void)
......
...@@ -61,7 +61,6 @@ void HSH_Drop(struct sess *sp); ...@@ -61,7 +61,6 @@ void HSH_Drop(struct sess *sp);
double HSH_Grace(double g); double HSH_Grace(double g);
void HSH_Init(void); void HSH_Init(void);
void HSH_AddString(const struct sess *sp, const char *str); 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); void HSH_FindBan(const struct sess *sp, struct objcore **oc);
struct objcore *HSH_Insert(const struct sess *sp); struct objcore *HSH_Insert(const struct sess *sp);
void HSH_Purge(const struct sess *, struct objhead *, double ttl, double grace); void HSH_Purge(const struct sess *, struct objhead *, double ttl, double grace);
...@@ -94,7 +93,7 @@ struct objhead { ...@@ -94,7 +93,7 @@ struct objhead {
}; };
void HSH_DeleteObjHead(struct worker *w, struct objhead *oh); 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 */ #endif /* VARNISH_CACHE_CHILD */
extern const struct hash_slinger hsl_slinger; 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