]> err.no Git - varnish/commitdiff
Add a bit of garbage collection to yesterdays change: Passed objects need
authorphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Wed, 7 Mar 2007 10:38:20 +0000 (10:38 +0000)
committerphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Wed, 7 Mar 2007 10:38:20 +0000 (10:38 +0000)
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

varnish-cache/bin/varnishd/cache.h
varnish-cache/bin/varnishd/cache_center.c
varnish-cache/bin/varnishd/cache_hash.c

index 5090ecd21a1b811fcfa42b6f0ee55f0bd0177a4e..4f58bbd6d70d12be2eba0d0b12b612ad6c2fbb01 100644 (file)
@@ -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);
index 2e0107d38d1eab5bd0aea15a29f19672d4f9aceb..c7dc74b7b604473eb585eca8c99ba1b8f137866b 100644 (file)
@@ -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);
index d19474626d39322934b621ff594474fc991d334b..56eee23c633e364a4576d591ab49c43856ac7872 100644 (file)
@@ -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;