From: phk Date: Wed, 7 Mar 2007 10:38:20 +0000 (+0000) Subject: Add a bit of garbage collection to yesterdays change: Passed objects need X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0b805caaf20e6a7a07b981d861b600fa6a9fe40e;p=varnish 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: svn+ssh://projects.linpro.no/svn/varnish/trunk@1278 d4fa192b-c00b-0410-8231-f00ffab90ce4 --- diff --git a/varnish-cache/bin/varnishd/cache.h b/varnish-cache/bin/varnishd/cache.h index 5090ecd2..4f58bbd6 100644 --- a/varnish-cache/bin/varnishd/cache.h +++ b/varnish-cache/bin/varnishd/cache.h @@ -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); diff --git a/varnish-cache/bin/varnishd/cache_center.c b/varnish-cache/bin/varnishd/cache_center.c index 2e0107d3..c7dc74b7 100644 --- a/varnish-cache/bin/varnishd/cache_center.c +++ b/varnish-cache/bin/varnishd/cache_center.c @@ -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); diff --git a/varnish-cache/bin/varnishd/cache_hash.c b/varnish-cache/bin/varnishd/cache_hash.c index d1947462..56eee23c 100644 --- a/varnish-cache/bin/varnishd/cache_hash.c +++ b/varnish-cache/bin/varnishd/cache_hash.c @@ -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;