]> err.no Git - varnish/commitdiff
Start releasing objects when they expire
authorphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Mon, 26 Jun 2006 14:33:49 +0000 (14:33 +0000)
committerphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Mon, 26 Jun 2006 14:33:49 +0000 (14:33 +0000)
git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@235 d4fa192b-c00b-0410-8231-f00ffab90ce4

varnish-cache/bin/varnishd/cache.h
varnish-cache/bin/varnishd/cache_expire.c
varnish-cache/bin/varnishd/cache_fetch.c
varnish-cache/bin/varnishd/cache_hash.c
varnish-cache/bin/varnishd/cache_pool.c
varnish-cache/bin/varnishd/hash_simple_list.c

index 8f1cac6a8fe285cb0c70261d53e01a3020cd79b3..e4f353d570cb1063f4fd5b8a7fb9d7851f7c61fb 100644 (file)
@@ -30,7 +30,7 @@ struct worker;
 
 typedef void hash_init_f(void);
 typedef struct objhead *hash_lookup_f(const char *key, struct objhead *nobj);
-typedef void hash_deref_f(struct objhead *obj);
+typedef int hash_deref_f(struct objhead *obj);
 
 struct hash_slinger {
        const char              *name;
@@ -155,7 +155,7 @@ int FetchSession(struct worker *w, struct sess *sp);
 /* cache_hash.c */
 struct object *HSH_Lookup(struct worker *w, struct http *h);
 void HSH_Unbusy(struct object *o);
-void HSH_Unref(struct object *o);
+void HSH_Deref(struct object *o);
 void HSH_Init(void);
 
 /* cache_http.c */
index 733bd611a841c14f457f5f6d66b6f99eec538d2c..8da8d4496afb609a09b4ba3ed9d95896e0bc2496 100644 (file)
@@ -52,6 +52,7 @@ exp_main(void *arg)
                printf("Root: %p %d (%d)\n", (void*)o, o->ttl, o->ttl - t);
                binheap_delete(exp_heap, 0);
                AZ(pthread_mutex_unlock(&expmtx));
+               HSH_Deref(o);
        }
 
        return ("FOOBAR");
index 9b22615bd78c116d687bbf336ed181ff3ed92368..e100d25a371b4cfed37e2ac2990a02ec75f40ae3 100644 (file)
@@ -271,10 +271,9 @@ FetchSession(struct worker *w, struct sess *sp)
        else
                VBE_RecycleFd(fd_token);
 
-       /* XXX: unbusy, and kick other sessions into action */
-       sp->obj->busy = 0;
-
-       /* XXX: if not cachable, destroy */
+       HSH_Unbusy(sp->obj);
+       if (!sp->obj->cacheable)
+               HSH_Deref(sp->obj);
 
        return (1);
 }
index 0949c8862fb19f558cdf6fc4f35532264781ff7d..389d7eef05cdb31a13625d4e578ed02c3417354b 100644 (file)
@@ -16,7 +16,6 @@
 
 static struct hash_slinger      *hash;
 
-
 struct object *
 HSH_Lookup(struct worker *w, struct http *h)
 {
@@ -25,18 +24,19 @@ HSH_Lookup(struct worker *w, struct http *h)
        char *b;
 
        assert(hash != NULL);
-       /* Make sure we have both a new objhead and object if we need them */
+       /* Precreate an objhead and object in case we need them */
        if (w->nobjhead == NULL) {
                w->nobjhead = calloc(sizeof *w->nobjhead, 1);
                assert(w->nobjhead != NULL);
                TAILQ_INIT(&w->nobjhead->objects);
+               AZ(pthread_mutex_init(&oh->mtx, NULL));
        }
        if (w->nobj == NULL) {
                w->nobj = calloc(sizeof *w->nobj, 1);
                assert(w->nobj != NULL);
                w->nobj->busy = 1;
                TAILQ_INIT(&w->nobj->store);
-               pthread_cond_init(&w->nobj->cv, NULL);
+               AZ(pthread_cond_init(&w->nobj->cv, NULL));
        }
 
        assert(http_GetURL(h, &b));
@@ -53,11 +53,19 @@ HSH_Lookup(struct worker *w, struct http *h)
                        break;
                o->refcnt--;
        }
-       if (o == NULL) {
-               o = w->nobj;
-               w->nobj = NULL;
-               TAILQ_INSERT_TAIL(&oh->objects, o, list);
+       if (o != NULL) {
+               AZ(pthread_mutex_unlock(&oh->mtx));
+               hash->deref(oh);
+               return (o);
        }
+
+       /* Insert (precreated) object in objecthead */
+       o = w->nobj;
+       w->nobj = NULL;
+       o->refcnt = 1;
+       o->objhead = oh;
+       TAILQ_INSERT_TAIL(&oh->objects, o, list);
+       /* NB: do not deref objhead the new object inherits our reference */
        AZ(pthread_mutex_unlock(&oh->mtx));
        return (o);
 }
@@ -73,12 +81,39 @@ HSH_Unbusy(struct object *o)
 }
 
 void
-HSH_Unref(struct object *o)
+HSH_Deref(struct object *o)
 {
+       struct objhead *oh;
+       struct storage *st, *stn;
 
-       AZ(pthread_mutex_lock(&o->objhead->mtx));
-       o->refcnt--;
-       AZ(pthread_mutex_unlock(&o->objhead->mtx));
+       oh = o->objhead;
+
+       /* drop ref on object */
+       AZ(pthread_mutex_lock(&oh->mtx));
+       if (--o->refcnt == 0)
+               TAILQ_REMOVE(&oh->objects, o, list);
+       else 
+               o = NULL;
+       AZ(pthread_mutex_unlock(&oh->mtx));
+
+       /* If still referenced, done */
+       if (o == NULL)
+               return;
+
+       AZ(pthread_cond_destroy(&o->cv));
+
+       TAILQ_FOREACH_SAFE(st, &o->store, list, stn) {
+               TAILQ_REMOVE(&o->store, st, list);
+               st->stevedore->free(st);
+       }
+       free(o);
+
+       /* Drop our ref on the objhead */
+       if (hash->deref(oh))
+               return;
+       assert(TAILQ_EMPTY(&oh->objects));
+       AZ(pthread_mutex_destroy(&oh->mtx));
+       free(oh);
 }
 
 void
index ed9fad7beb8d46be6641e3836b5e59a618d074e7..34834b5ef5fc4f256ec10fefa6cd782520c8df25 100644 (file)
@@ -49,6 +49,8 @@ DeliverSession(struct worker *w, struct sess *sp)
            "\r\n", sp->obj->header, sp->obj->len);
 
        vca_write_obj(sp, w->sb);
+       HSH_Deref(sp->obj);
+       sp->obj = NULL;
        return (1);
 }
 
index 69c8a88f5f1a002395a6fc71d2e761bcaffbea51..d9fe9b784d819fab1d3064c391957cb27844fd09 100644 (file)
@@ -88,10 +88,11 @@ hsl_lookup(const char *key, struct objhead *nobj)
  * Dereference and if no references are left, free.
  */
 
-static void
+static int
 hsl_deref(struct objhead *obj)
 {
        struct hsl_entry *he;
+       int ret;
 
        assert(obj->hashpriv != NULL);
        he = obj->hashpriv;
@@ -100,8 +101,11 @@ hsl_deref(struct objhead *obj)
                free(he->key);
                TAILQ_REMOVE(&hsl_head, he, list);
                free(he);
-       }
+               ret = 0;
+       } else
+               ret = 1;
        AZ(pthread_mutex_unlock(&hsl_mutex));
+       return (ret);
 }
 
 /*--------------------------------------------------------------------*/