From 309b3ed39ad8ac939b038f9a9f566b738209251b Mon Sep 17 00:00:00 2001 From: phk Date: Mon, 26 Jun 2006 08:58:08 +0000 Subject: [PATCH] Now that we approach the time where objects have to be destroyed again, 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 | 1 + varnish-cache/bin/varnishd/cache.h | 40 +++++--- varnish-cache/bin/varnishd/cache_fetch.c | 4 + varnish-cache/bin/varnishd/cache_hash.c | 97 +++++++++++++++++++ varnish-cache/bin/varnishd/cache_main.c | 6 +- varnish-cache/bin/varnishd/cache_pool.c | 29 +----- varnish-cache/bin/varnishd/hash_simple_list.c | 10 +- 7 files changed, 141 insertions(+), 46 deletions(-) create mode 100644 varnish-cache/bin/varnishd/cache_hash.c diff --git a/varnish-cache/bin/varnishd/Makefile.am b/varnish-cache/bin/varnishd/Makefile.am index 3fcb4416..070ed754 100644 --- a/varnish-cache/bin/varnishd/Makefile.am +++ b/varnish-cache/bin/varnishd/Makefile.am @@ -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 \ diff --git a/varnish-cache/bin/varnishd/cache.h b/varnish-cache/bin/varnishd/cache.h index 60af0aa5..1aae9c86 100644 --- a/varnish-cache/bin/varnishd/cache.h +++ b/varnish-cache/bin/varnishd/cache.h @@ -4,14 +4,22 @@ #include +#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; diff --git a/varnish-cache/bin/varnishd/cache_fetch.c b/varnish-cache/bin/varnishd/cache_fetch.c index 2966496b..9b22615b 100644 --- a/varnish-cache/bin/varnishd/cache_fetch.c +++ b/varnish-cache/bin/varnishd/cache_fetch.c @@ -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 index 00000000..ffa0fa9f --- /dev/null +++ b/varnish-cache/bin/varnishd/cache_hash.c @@ -0,0 +1,97 @@ +/* + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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(); +} diff --git a/varnish-cache/bin/varnishd/cache_main.c b/varnish-cache/bin/varnishd/cache_main.c index 46b0136b..ada0e103 100644 --- a/varnish-cache/bin/varnishd/cache_main.c +++ b/varnish-cache/bin/varnishd/cache_main.c @@ -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); diff --git a/varnish-cache/bin/varnishd/cache_pool.c b/varnish-cache/bin/varnishd/cache_pool.c index cb74cc5d..ed9fad7b 100644 --- a/varnish-cache/bin/varnishd/cache_pool.c +++ b/varnish-cache/bin/varnishd/cache_pool.c @@ -12,7 +12,6 @@ #include #include #include -#include #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); } diff --git a/varnish-cache/bin/varnishd/hash_simple_list.c b/varnish-cache/bin/varnishd/hash_simple_list.c index aebe2612..63e7375a 100644 --- a/varnish-cache/bin/varnishd/hash_simple_list.c +++ b/varnish-cache/bin/varnishd/hash_simple_list.c @@ -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; -- 2.39.5