Commit 42b9d909 authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Add a bit of garbage collection to yesterdays change: Passed objects need

to have their storage properly reclaimed, including the actual content
of a obj.pass=1 cache entry, once we have sent the content to the original
requestor.


git-svn-id: http://www.varnish-cache.org/svn/trunk/varnish-cache@1278 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent 0dd910f6
......@@ -351,6 +351,7 @@ int Fetch(struct sess *sp);
/* cache_hash.c */
void HSH_Prealloc(struct sess *sp);
void HSH_Freestore(struct object *o);
struct object *HSH_Lookup(struct sess *sp);
void HSH_Unbusy(struct object *o);
void HSH_Ref(struct object *o);
......
......@@ -136,6 +136,10 @@ cnt_deliver(struct sess *sp)
{
RES_WriteObj(sp);
if (sp->obj->objhead != NULL && sp->obj->pass) {
/* we will no longer need the storage */
HSH_Freestore(sp->obj);
}
HSH_Deref(sp->obj);
sp->obj = NULL;
sp->step = STP_DONE;
......@@ -300,9 +304,10 @@ cnt_fetch(struct sess *sp)
sp->obj->pass = 1;
sp->obj->cacheable = 1;
HSH_Ref(sp->obj); /* get another, STP_DELIVER will deref */
if (sp->obj->objhead != NULL)
if (sp->obj->objhead != NULL) {
HSH_Ref(sp->obj); /* get another, STP_DELIVER will deref */
HSH_Unbusy(sp->obj);
}
sp->wrk->acct.fetch++;
sp->step = STP_DELIVER;
return (0);
......
......@@ -96,6 +96,18 @@ HSH_Prealloc(struct sess *sp)
CHECK_OBJ_NOTNULL(w->nobj, OBJECT_MAGIC);
}
void
HSH_Freestore(struct object *o)
{
struct storage *st, *stn;
TAILQ_FOREACH_SAFE(st, &o->store, list, stn) {
CHECK_OBJ_NOTNULL(st, STORAGE_MAGIC);
TAILQ_REMOVE(&o->store, st, list);
st->stevedore->free(st);
}
}
struct object *
HSH_Lookup(struct sess *sp)
{
......@@ -213,43 +225,37 @@ void
HSH_Deref(struct object *o)
{
struct objhead *oh;
struct storage *st, *stn;
unsigned r;
CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC);
oh = o->objhead;
if (oh == NULL) {
/* Pass object, not referenced anywhere */
free(o);
return;
}
CHECK_OBJ(oh, OBJHEAD_MAGIC);
if (oh != NULL) {
CHECK_OBJ(oh, OBJHEAD_MAGIC);
/* drop ref on object */
LOCK(&oh->mtx);
/* drop ref on object */
LOCK(&oh->mtx);
}
assert(o->refcnt > 0);
r = --o->refcnt;
if (!r)
TAILQ_REMOVE(&oh->objects, o, list);
UNLOCK(&oh->mtx);
if (oh != NULL) {
if (!r)
TAILQ_REMOVE(&oh->objects, o, list);
UNLOCK(&oh->mtx);
}
/* If still referenced, done */
if (r != 0)
return;
if (o->http.s != NULL) {
if (o->http.s != NULL)
free(o->http.s);
}
TAILQ_FOREACH_SAFE(st, &o->store, list, stn) {
CHECK_OBJ_NOTNULL(st, STORAGE_MAGIC);
TAILQ_REMOVE(&o->store, st, list);
st->stevedore->free(st);
}
HSH_Freestore(o);
free(o);
VSL_stats->n_object--;
if (oh == NULL)
return;
/* Drop our ref on the objhead */
if (hash->deref(oh))
return;
......
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