]> err.no Git - varnish/commitdiff
Now that we approach the time where objects have to be destroyed again,
authorphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Mon, 26 Jun 2006 08:58:08 +0000 (08:58 +0000)
committerphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Mon, 26 Jun 2006 08:58:08 +0000 (08:58 +0000)
we need to move the data structures into the right shape.

Push hashing into cache_hash.c

Add objhead structure to hold the various hits for "Vary:" headers.

git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@233 d4fa192b-c00b-0410-8231-f00ffab90ce4

varnish-cache/bin/varnishd/Makefile.am
varnish-cache/bin/varnishd/cache.h
varnish-cache/bin/varnishd/cache_fetch.c
varnish-cache/bin/varnishd/cache_hash.c [new file with mode: 0644]
varnish-cache/bin/varnishd/cache_main.c
varnish-cache/bin/varnishd/cache_pool.c
varnish-cache/bin/varnishd/hash_simple_list.c

index 3fcb4416ae7e031e77d9133c5a1b80d99528092c..070ed754733a27be1117c3400015a09f84b6597c 100644 (file)
@@ -9,6 +9,7 @@ varnishd_SOURCES = \
        cache_backend.c \
        cache_expire.c \
        cache_fetch.c \
+       cache_hash.c \
        cache_http.c \
        cache_main.c \
        cache_pool.c \
index 60af0aa59c969415504b799dcb3c025698699f4d..1aae9c864ae72c7e04d0d504164ebf69668890b0 100644 (file)
@@ -4,14 +4,22 @@
 
 #include <sys/queue.h>
 
+#include "vcl_returns.h"
+
+#define VCA_ADDRBUFSIZE                32      /* Sizeof ascii network address */
+
 struct event_base;
 struct sbuf;
+struct sess;
+struct object;
+struct objhead;
 
 #ifdef EV_TIMEOUT
 struct worker {
        struct event_base       *eb;
        struct event            e1, e2;
        struct sbuf             *sb;
+       struct objhead          *nobjhead;
        struct object           *nobj;
 };
 #else
@@ -21,9 +29,9 @@ struct worker;
 /* Hashing -----------------------------------------------------------*/
 
 typedef void hash_init_f(void);
-typedef struct object *hash_lookup_f(unsigned char *key, struct object *nobj);
-typedef void hash_deref_f(struct object *obj);
-typedef void hash_purge_f(struct object *obj);
+typedef struct objhead *hash_lookup_f(unsigned char *key, struct objhead *nobj);
+typedef void hash_deref_f(struct objhead *obj);
+typedef void hash_purge_f(struct objhead *obj);
 
 struct hash_slinger {
        const char              *name;
@@ -35,8 +43,6 @@ struct hash_slinger {
 
 extern struct hash_slinger hsl_slinger;
 
-extern struct hash_slinger     *hash;
-
 /* Storage -----------------------------------------------------------*/
 
 struct storage {
@@ -57,11 +63,7 @@ struct storage {
  */
 extern struct stevedore *stevedore;
 
-/* Storage -----------------------------------------------------------*/
-
-struct sess;
-
-#define VCA_ADDRBUFSIZE                32
+/* -------------------------------------------------------------------*/
 
 struct object {        
        unsigned char           hash[16];
@@ -69,16 +71,26 @@ struct object {
        unsigned                valid;
        unsigned                cacheable;
 
+       struct objhead          *objhead;
+       pthread_cond_t          cv;
+
        unsigned                busy;
        unsigned                len;
        time_t                  ttl;
 
        char                    *header;
+       TAILQ_ENTRY(object)     list;
 
        TAILQ_HEAD(, storage)   store;
 };
 
-#include "vcl_returns.h"
+struct objhead {
+       unsigned char           hash[16];
+       unsigned                refcnt;
+
+       pthread_mutex_t         mtx;
+       TAILQ_HEAD(,object)     objects;
+};
 
 struct sess {
        int                     fd;
@@ -144,6 +156,12 @@ void EXP_Init(void);
 /* cache_fetch.c */
 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_Init(void);
+
 /* cache_http.c */
 typedef void http_callback_f(void *, int good);
 struct http;
index 2966496bb4a714a57b1ad650c3a3b2c85139bcc7..9b22615bd78c116d687bbf336ed181ff3ed92368 100644 (file)
@@ -72,7 +72,9 @@ fetch_straight(struct worker *w, struct sess *sp, int fd, struct http *hp, char
 
        vca_write_obj(sp, w->sb);
 
+#if 0
        hash->deref(sp->obj);
+#endif
        return (0);
 
 }
@@ -187,7 +189,9 @@ fetch_chunked(struct worker *w, struct sess *sp, int fd, struct http *hp)
 
        vca_write_obj(sp, w->sb);
 
+#if 0
        hash->deref(sp->obj);
+#endif
 
        return (0);
 }
diff --git a/varnish-cache/bin/varnishd/cache_hash.c b/varnish-cache/bin/varnishd/cache_hash.c
new file mode 100644 (file)
index 0000000..ffa0fa9
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * $Id$
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <md5.h>
+#include <event.h>
+#include <pthread.h>
+
+#include "libvarnish.h"
+#include "cache.h"
+
+static struct hash_slinger      *hash;
+
+
+struct object *
+HSH_Lookup(struct worker *w, struct http *h)
+{
+       struct objhead *oh;
+       struct object *o;
+       unsigned char key[16];
+       MD5_CTX ctx;
+       char *b;
+
+       assert(hash != NULL);
+       /* Make sure we have both a new objhead and object if we need them */
+       if (w->nobjhead == NULL) {
+               w->nobjhead = calloc(sizeof *w->nobjhead, 1);
+               assert(w->nobjhead != NULL);
+               TAILQ_INIT(&w->nobjhead->objects);
+       }
+       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);
+       }
+
+       assert(http_GetURL(h, &b));
+       MD5Init(&ctx);
+       MD5Update(&ctx, b, strlen(b));
+       MD5Final(key, &ctx);
+       oh = hash->lookup(key, w->nobjhead);
+       if (oh == w->nobjhead)
+               w->nobjhead = NULL;
+       AZ(pthread_mutex_lock(&oh->mtx));
+       TAILQ_FOREACH(o, &oh->objects, list) {
+               o->refcnt++;
+               if (o->busy)
+                       AZ(pthread_cond_wait(&o->cv, &oh->mtx));
+               /* XXX: do Vary: comparison */
+               if (1)
+                       break;
+               o->refcnt--;
+       }
+       if (o == NULL) {
+               o = w->nobj;
+               w->nobj = NULL;
+               TAILQ_INSERT_TAIL(&oh->objects, o, list);
+       }
+       AZ(pthread_mutex_unlock(&oh->mtx));
+       return (o);
+}
+
+void
+HSH_Unbusy(struct object *o)
+{
+
+       AZ(pthread_mutex_lock(&o->objhead->mtx));
+       o->busy = 0;
+       AZ(pthread_mutex_unlock(&o->objhead->mtx));
+       AZ(pthread_cond_broadcast(&o->cv));
+}
+
+void
+HSH_Unref(struct object *o)
+{
+
+       AZ(pthread_mutex_lock(&o->objhead->mtx));
+       o->refcnt--;
+       AZ(pthread_mutex_unlock(&o->objhead->mtx));
+}
+
+void
+HSH_Init(void)
+{
+
+       hash = &hsl_slinger;
+       if (hash->init != NULL)
+               hash->init();
+}
index 46b0136b47021bb025456ea932ddc5a5888bbea6..ada0e1032ea0e9b7fb8c31404e914aa6dada02c0 100644 (file)
@@ -24,7 +24,6 @@
 
 static struct event ev_keepalive;
 
-struct hash_slinger    *hash;
 struct stevedore       *stevedore;
 
 pthread_mutex_t        sessmtx;
@@ -115,14 +114,11 @@ child_main(void)
 
        VCA_Init();
        EXP_Init();
+       HSH_Init();
 
        eb = event_init();
        assert(eb != NULL);
 
-       hash = &hsl_slinger;
-       if (hash->init != NULL)
-               hash->init();
-
        stevedore = heritage.stevedore;
        if (stevedore->open != NULL)
                stevedore->open(stevedore);
index cb74cc5d3822d75ff3eeb6b8027da36cf62e56f0..ed9fad7beb8d46be6641e3836b5e59a618d074e7 100644 (file)
@@ -12,7 +12,6 @@
 #include <sys/time.h>
 #include <sbuf.h>
 #include <event.h>
-#include <md5.h>
 
 #include "libvarnish.h"
 #include "shmlog.h"
@@ -29,33 +28,13 @@ static int
 LookupSession(struct worker *w, struct sess *sp)
 {
        struct object *o;
-       unsigned char key[16];
-       MD5_CTX ctx;
-       char *b;
-
-       /* Make sure worker thread has a fresh object at hand */
-       if (w->nobj == NULL) {
-               w->nobj = calloc(sizeof *w->nobj, 1);   
-               assert(w->nobj != NULL);
-               w->nobj->busy = 1;
-               TAILQ_INIT(&w->nobj->store);
-       }
 
-       assert(http_GetURL(sp->http, &b));
-       MD5Init(&ctx);
-       MD5Update(&ctx, b, strlen(b));
-       MD5Final(key, &ctx);
-       o = hash->lookup(key, w->nobj);
+       o = HSH_Lookup(w, sp->http);
        sp->obj = o;
-       if (o != w->nobj && o->ttl > sp->t0) {
-               /* XXX: wait while obj->busy */
-               VSL(SLT_Debug, 0, "Lookup found %p %s", o, b);
+       if (o->busy)
+               VCL_miss_method(sp);
+       else
                VCL_hit_method(sp);
-               return (0);
-       }
-       VSL(SLT_Debug, 0, "Lookup new %p %s", o, b);
-       w->nobj = NULL;
-       VCL_miss_method(sp);
        return (0);
 }
 
index aebe26125c496956615a17947c74ee4cc5a2d1f1..63e7375a85e17059f3518f48afd7219514e121af 100644 (file)
@@ -14,7 +14,7 @@
 
 struct hsl_entry {
        TAILQ_ENTRY(hsl_entry)  list;
-       struct object           *obj;
+       struct objhead          *obj;
 };
 
 static TAILQ_HEAD(, hsl_entry) hsl_head = TAILQ_HEAD_INITIALIZER(hsl_head);
@@ -27,8 +27,8 @@ hsl_init(void)
        AZ(pthread_mutex_init(&hsl_mutex, NULL));
 }
 
-static struct object *
-hsl_lookup(unsigned char *key, struct object *nobj)
+static struct objhead *
+hsl_lookup(unsigned char *key, struct objhead *nobj)
 {
        struct hsl_entry *he, *he2;
        int i;
@@ -64,7 +64,7 @@ hsl_lookup(unsigned char *key, struct object *nobj)
 }
 
 static void
-hsl_deref(struct object *obj)
+hsl_deref(struct objhead *obj)
 {
 
        AZ(pthread_mutex_lock(&hsl_mutex));
@@ -73,7 +73,7 @@ hsl_deref(struct object *obj)
 }
 
 static void
-hsl_purge(struct object *obj)
+hsl_purge(struct objhead *obj)
 {
        struct hsl_entry *he;