Initialize default hasher and stevedore.
Give each workerthread an object pointer to be kept populated with
a template object for when lookups miss and need to insert one.
Add libmd to get MD5, (choice of hash-algorithm to be revisited later)
Implement lookup, begin on fetch.
git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@141
d4fa192b-c00b-0410-8231-
f00ffab90ce4
$(top_builddir)/lib/libvarnish/libvarnish.la \
$(top_builddir)/lib/libvcl/libvcl.la \
$(top_builddir)/contrib/libevent/libevent.la \
- -lpthread
+ -lpthread \
+ -lmd
struct event_base *eb;
struct event e1, e2;
struct sbuf *sb;
+ struct object *nobj;
};
#else
struct worker;
extern struct hash_slinger hsl_slinger;
+extern struct hash_slinger *hash;
+
/* Storage -----------------------------------------------------------*/
struct storage {
extern struct stevedore sma_stevedore;
+extern struct stevedore *stevedore;
+
/* Prototypes etc ----------------------------------------------------*/
static struct event ev_keepalive;
static pthread_t vca_thread;
+struct hash_slinger *hash;
+struct stevedore *stevedore;
+
pthread_mutex_t sessmtx;
/*--------------------------------------------------------------------*/
eb = event_init();
assert(eb != NULL);
+ hash = &hsl_slinger;
+ hash->init();
+
+ stevedore = &sma_stevedore;
+ stevedore->init();
+
CVCL_Load(heritage.vcl_file, "boot");
cli = cli_setup(eb, heritage.fds[2], heritage.fds[1], 0, cli_proto);
*/
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <pthread.h>
#include <sys/time.h>
#include <sbuf.h>
#include <event.h>
+#include <md5.h>
#include "libvarnish.h"
+#include "shmlog.h"
#include "vcl_lang.h"
#include "cache.h"
static pthread_cond_t shdcnd;
+static int
+LookupSession(struct worker *w, struct sess *sp)
+{
+ struct object *o;
+ unsigned char key[16];
+ MD5_CTX ctx;
+
+ if (w->nobj == NULL) {
+ w->nobj = calloc(sizeof *w->nobj, 1);
+ assert(w->nobj != NULL);
+ w->nobj->busy = 1;
+ TAILQ_INIT(&w->nobj->store);
+ }
+
+ MD5Init(&ctx);
+ MD5Update(&ctx, sp->http.url, strlen(sp->http.url));
+ MD5Final(key, &ctx);
+ o = hash->lookup(key, w->nobj);
+ if (o == w->nobj)
+ w->nobj = NULL;
+ /*
+ * XXX: if obj is busy, park session on it
+ */
+
+ sp->obj = o;
+ sp->handling = HND_Unclass;
+ sp->vcl->lookup_func(sp);
+ if (sp->handling == HND_Unclass) {
+ if (o->valid && o->cacheable)
+ sp->handling = HND_Deliver;
+ else
+ sp->handling = HND_Pass;
+ }
+ return (0);
+}
+
+static int
+FetchSession(struct worker *w, struct sess *sp)
+{
+
+ assert(w == NULL);
+}
+
static void *
CacheWorker(void *priv)
{
struct sess *sp;
struct worker w;
+ int done;
memset(&w, 0, sizeof w);
w.eb = event_init();
HttpdAnalyze(sp, 1);
sp->backend = sp->vcl->default_backend;
- /* Call the VCL program */
+
+ /*
+ * Call the VCL recv function.
+ * Default action is to lookup
+ */
+ sp->handling = HND_Lookup;
+
sp->vcl->recv_func(sp);
- printf("Handling: %d\n", sp->handling);
- switch(sp->handling) {
- case HND_Unclass:
- case HND_Handle:
- case HND_Pipe:
- PipeSession(&w, sp);
- break;
- case HND_Pass:
- PassSession(&w, sp);
- break;
+ for (done = 0; !done; ) {
+ printf("Handling: %d\n", sp->handling);
+ switch(sp->handling) {
+ case HND_Lookup:
+ done = LookupSession(&w, sp);
+ break;
+ case HND_Fetch:
+ done = FetchSession(&w, sp);
+ break;
+ case HND_Pipe:
+ PipeSession(&w, sp);
+ done = 1;
+ break;
+ case HND_Pass:
+ PassSession(&w, sp);
+ done = 1;
+ break;
+ case HND_Unclass:
+ case HND_Deliver:
+ assert(sp->handling == HND_Unclass);
+ }
}
AZ(pthread_mutex_lock(&sessmtx));
}
void VCL_insert(VCL_FARGS) { }
-void VCL_fetch(VCL_FARGS) { }
-void VCL_error(VCL_FARGS, unsigned err, const char *str) { }
+
+void VCL_fetch(VCL_FARGS) {
+ sess->handling = HND_Fetch;
+ sess->done++;
+}
+
+void VCL_error(VCL_FARGS, unsigned err, const char *str) {
+}
unsigned refcnt;
unsigned valid;
unsigned cacheable;
+
+ unsigned busy;
+
+ TAILQ_HEAD(, storage) store;
};
struct sess {
enum {
HND_Unclass,
- HND_Handle,
+ HND_Deliver,
HND_Pass,
- HND_Pipe
+ HND_Pipe,
+ HND_Lookup,
+ HND_Fetch
} handling;
char done;
fputs(" unsigned refcnt;\n", f);
fputs(" unsigned valid;\n", f);
fputs(" unsigned cacheable;\n", f);
+ fputs("\n", f);
+ fputs(" unsigned busy;\n", f);
+ fputs("\n", f);
+ fputs(" TAILQ_HEAD(, storage) store;\n", f);
fputs("};\n", f);
fputs("\n", f);
fputs("struct sess {\n", f);
fputs("\n", f);
fputs(" enum {\n", f);
fputs(" HND_Unclass,\n", f);
- fputs(" HND_Handle,\n", f);
+ fputs(" HND_Deliver,\n", f);
fputs(" HND_Pass,\n", f);
- fputs(" HND_Pipe\n", f);
+ fputs(" HND_Pipe,\n", f);
+ fputs(" HND_Lookup,\n", f);
+ fputs(" HND_Fetch\n", f);
fputs(" } handling;\n", f);
fputs("\n", f);
fputs(" char done;\n", f);