source: bin/varnishd/cache_hash.c @ 23303f

Revision 23303f, 2.4 KB checked in by Poul-Henning Kamp <phk@…>, 8 years ago (diff)

Start releasing objects when they expire

git-svn-id:  http://www.varnish-cache.org/svn/trunk@235 d4fa192b-c00b-0410-8231-f00ffab90ce4

  • Property mode set to 100644
Line 
1/*
2 * $Id$
3 */
4
5#include <stdio.h>
6#include <stdlib.h>
7#include <assert.h>
8#include <string.h>
9#include <sys/types.h>
10#include <fcntl.h>
11#include <event.h>
12#include <pthread.h>
13
14#include "libvarnish.h"
15#include "cache.h"
16
17static struct hash_slinger      *hash;
18
19struct object *
20HSH_Lookup(struct worker *w, struct http *h)
21{
22        struct objhead *oh;
23        struct object *o;
24        char *b;
25
26        assert(hash != NULL);
27        /* Precreate an objhead and object in case we need them */
28        if (w->nobjhead == NULL) {
29                w->nobjhead = calloc(sizeof *w->nobjhead, 1);
30                assert(w->nobjhead != NULL);
31                TAILQ_INIT(&w->nobjhead->objects);
32                AZ(pthread_mutex_init(&oh->mtx, NULL));
33        }
34        if (w->nobj == NULL) {
35                w->nobj = calloc(sizeof *w->nobj, 1);
36                assert(w->nobj != NULL);
37                w->nobj->busy = 1;
38                TAILQ_INIT(&w->nobj->store);
39                AZ(pthread_cond_init(&w->nobj->cv, NULL));
40        }
41
42        assert(http_GetURL(h, &b));
43        oh = hash->lookup(b, w->nobjhead);
44        if (oh == w->nobjhead)
45                w->nobjhead = NULL;
46        AZ(pthread_mutex_lock(&oh->mtx));
47        TAILQ_FOREACH(o, &oh->objects, list) {
48                o->refcnt++;
49                if (o->busy)
50                        AZ(pthread_cond_wait(&o->cv, &oh->mtx));
51                /* XXX: do Vary: comparison */
52                if (1)
53                        break;
54                o->refcnt--;
55        }
56        if (o != NULL) {
57                AZ(pthread_mutex_unlock(&oh->mtx));
58                hash->deref(oh);
59                return (o);
60        }
61
62        /* Insert (precreated) object in objecthead */
63        o = w->nobj;
64        w->nobj = NULL;
65        o->refcnt = 1;
66        o->objhead = oh;
67        TAILQ_INSERT_TAIL(&oh->objects, o, list);
68        /* NB: do not deref objhead the new object inherits our reference */
69        AZ(pthread_mutex_unlock(&oh->mtx));
70        return (o);
71}
72
73void
74HSH_Unbusy(struct object *o)
75{
76
77        AZ(pthread_mutex_lock(&o->objhead->mtx));
78        o->busy = 0;
79        AZ(pthread_mutex_unlock(&o->objhead->mtx));
80        AZ(pthread_cond_broadcast(&o->cv));
81}
82
83void
84HSH_Deref(struct object *o)
85{
86        struct objhead *oh;
87        struct storage *st, *stn;
88
89        oh = o->objhead;
90
91        /* drop ref on object */
92        AZ(pthread_mutex_lock(&oh->mtx));
93        if (--o->refcnt == 0)
94                TAILQ_REMOVE(&oh->objects, o, list);
95        else 
96                o = NULL;
97        AZ(pthread_mutex_unlock(&oh->mtx));
98
99        /* If still referenced, done */
100        if (o == NULL)
101                return;
102
103        AZ(pthread_cond_destroy(&o->cv));
104
105        TAILQ_FOREACH_SAFE(st, &o->store, list, stn) {
106                TAILQ_REMOVE(&o->store, st, list);
107                st->stevedore->free(st);
108        }
109        free(o);
110
111        /* Drop our ref on the objhead */
112        if (hash->deref(oh))
113                return;
114        assert(TAILQ_EMPTY(&oh->objects));
115        AZ(pthread_mutex_destroy(&oh->mtx));
116        free(oh);
117}
118
119void
120HSH_Init(void)
121{
122
123        hash = &hsl_slinger;
124        if (hash->init != NULL)
125                hash->init();
126}
Note: See TracBrowser for help on using the repository browser.