Commit 31600c2c authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

At the expense of some complexity and a small runtime overhead,

isolate the compiled code from the internal structures of the cache
process through of VRT functions.



git-svn-id: http://www.varnish-cache.org/svn/trunk@211 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent 7981186e
......@@ -2,6 +2,8 @@
* $Id$
*/
#include <sys/queue.h>
struct event_base;
struct sbuf;
......@@ -55,6 +57,73 @@ struct storage {
*/
extern struct stevedore *stevedore;
/* Storage -----------------------------------------------------------*/
struct sess;
typedef void sesscb_f(struct sess *sp);
#define VCA_ADDRBUFSIZE 32
struct object {
unsigned char hash[16];
unsigned refcnt;
unsigned valid;
unsigned cacheable;
unsigned busy;
unsigned len;
char *header;
TAILQ_HEAD(, storage) store;
};
#define HND_Error (1 << 0)
#define HND_Pipe (1 << 1)
#define HND_Pass (1 << 2)
#define HND_Lookup (1 << 3)
#define HND_Fetch (1 << 4)
#define HND_Insert (1 << 5)
#define HND_Deliver (1 << 6)
struct sess {
int fd;
/* formatted ascii client address */
char addr[VCA_ADDRBUFSIZE];
/* HTTP request */
struct http *http;
unsigned handling;
TAILQ_ENTRY(sess) list;
sesscb_f *sesscb;
struct backend *backend;
struct object *obj;
struct VCL_conf *vcl;
/* Various internal stuff */
struct event *rd_e;
struct sessmem *mem;
};
struct backend {
const char *hostname;
const char *portname;
struct addrinfo *addr;
unsigned ip;
double responsetime;
double timeout;
double bandwidth;
int down;
/* internal stuff */
struct vbe *vbe;
};
/* Prototypes etc ----------------------------------------------------*/
......
......@@ -16,6 +16,7 @@
#include <sys/uio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/queue.h>
#include <netdb.h>
......@@ -25,7 +26,6 @@
#include "config.h"
#include "compat.h"
#include "libvarnish.h"
#include "vcl_lang.h"
#include "heritage.h"
#include "shmlog.h"
#include "cache.h"
......
......@@ -16,7 +16,6 @@
#include "libvarnish.h"
#include "shmlog.h"
#include "vcl_lang.h"
#include "cache.h"
static unsigned http_bufsize = 4096;
......
......@@ -102,7 +102,7 @@ CacheWorker(void *priv)
http_Dissect(sp->http, sp->fd, 1);
sp->backend = sp->vcl->default_backend;
sp->backend = sp->vcl->backend[0];
VCL_recv_method(sp);
......
......@@ -16,9 +16,9 @@
#include "cli.h"
#include "cli_priv.h"
#include "shmlog.h"
#include "vcl_lang.h"
#include "vrt.h"
#include "libvarnish.h"
#include "vcl_lang.h"
#include "cache.h"
/*--------------------------------------------------------------------*/
......@@ -71,8 +71,58 @@ VRT_GetReq(struct sess *sp)
/*--------------------------------------------------------------------*/
void
VRT_handling(struct sess *sp, enum handling hand)
VRT_handling(struct sess *sp, unsigned hand)
{
assert(!(hand & (hand -1))); /* must be power of two */
switch (hand) {
#define FOO(a,b) case VRT_H_##a: sp->handling = HND_##b; break;
FOO(error, Error);
FOO(pipe, Pipe);
FOO(pass, Pass);
FOO(lookup, Lookup);
FOO(fetch, Fetch);
FOO(insert, Insert);
FOO(deliver, Deliver);
#undef FOO
default:
assert(hand == 0);
}
}
int
VRT_obj_valid(struct sess *sp)
{
return (sp->obj->valid);
}
int
VRT_obj_cacheable(struct sess *sp)
{
return (sp->obj->cacheable);
}
void
VRT_set_backend_hostname(struct backend *be, const char *h)
{
be->hostname = h;
}
void
VRT_set_backend_portname(struct backend *be, const char *p)
{
be->portname = p;
}
sp->handling = hand;
void
VRT_alloc_backends(struct VCL_conf *cp)
{
int i;
cp->backend = calloc(sizeof *cp->backend, cp->nbackend);
assert(cp->backend != NULL);
for (i = 0; i < cp->nbackend; i++) {
cp->backend[i] = calloc(sizeof *cp->backend[i], 1);
assert(cp->backend[i] != NULL);
}
}
......@@ -5,79 +5,7 @@
* XXX: *MUST* be rerun.
*/
/* XXX: This include is bad. The VCL compiler shouldn't know about it. */
#include <sys/queue.h>
struct sess;
typedef void sesscb_f(struct sess *sp);
#define VCA_ADDRBUFSIZE 32
struct object {
unsigned char hash[16];
unsigned refcnt;
unsigned valid;
unsigned cacheable;
unsigned busy;
unsigned len;
char *header;
TAILQ_HEAD(, storage) store;
};
enum handling {
HND_Error = (1 << 0),
HND_Pipe = (1 << 1),
HND_Pass = (1 << 2),
HND_Lookup = (1 << 3),
HND_Fetch = (1 << 4),
HND_Insert = (1 << 5),
HND_Deliver = (1 << 6),
};
struct sess {
int fd;
/* formatted ascii client address */
char addr[VCA_ADDRBUFSIZE];
/* HTTP request */
struct http *http;
enum handling handling;
TAILQ_ENTRY(sess) list;
sesscb_f *sesscb;
struct backend *backend;
struct object *obj;
struct VCL_conf *vcl;
/* Various internal stuff */
struct event *rd_e;
struct sessmem *mem;
};
struct backend {
const char *hostname;
const char *portname;
struct addrinfo *addr;
unsigned ip;
double responsetime;
double timeout;
double bandwidth;
int down;
/* internal stuff */
struct vbe *vbe;
};
#if 0
int ip_match(unsigned, struct vcl_acl *);
int string_match(const char *, const char *);
#endif
typedef void vcl_init_f(void);
typedef int vcl_func_f(struct sess *sp);
......@@ -90,7 +18,8 @@ struct VCL_conf {
vcl_func_f *hit_func;
vcl_func_f *miss_func;
vcl_func_f *fetch_func;
struct backend *default_backend;
struct backend **backend;
unsigned nbackend;
struct vrt_ref *ref;
unsigned nref;
unsigned busy;
......
......@@ -6,6 +6,18 @@
* XXX: *MUST* be rerun.
*/
#define VRT_H_error (1 << 0)
#define VRT_H_pipe (1 << 1)
#define VRT_H_pass (1 << 2)
#define VRT_H_lookup (1 << 3)
#define VRT_H_fetch (1 << 4)
#define VRT_H_insert (1 << 5)
#define VRT_H_deliver (1 << 6)
struct sess;
struct backend;
struct VCL_conf;
struct vrt_ref {
unsigned line;
unsigned pos;
......@@ -31,7 +43,14 @@ int VRT_switch_config(const char *);
char *VRT_GetHdr(struct sess *, const char *);
char *VRT_GetReq(struct sess *);
void VRT_handling(struct sess *sp, enum handling hand);
void VRT_handling(struct sess *sp, unsigned hand);
int VRT_obj_valid(struct sess *);
int VRT_obj_cachable(struct sess *);
void VRT_set_backend_hostname(struct backend *, const char *);
void VRT_set_backend_portname(struct backend *, const char *);
void VRT_alloc_backends(struct VCL_conf *cp);
#define VRT_done(sp, hand) \
do { \
......
......@@ -76,6 +76,7 @@ struct tokenlist {
TAILQ_HEAD(, ref) refs;
struct sbuf *sb;
int err;
int nbackend;
};
enum var_type {
......@@ -93,12 +94,6 @@ enum var_type {
HEADER
};
struct var {
const char *name;
enum var_type fmt;
int len;
const char *cname;
};
enum ref_type {
R_FUNC,
......@@ -114,17 +109,26 @@ struct ref {
TAILQ_ENTRY(ref) list;
};
struct var {
const char *name;
enum var_type fmt;
int len;
const char *rname;
const char *lname;
};
static struct var be_vars[] = {
{ "backend.host", HOSTNAME, 0, "backend->hostname" },
{ "backend.port", PORTNAME, 0, "backend->portname" },
{ "backend.host",
HOSTNAME, 0, NULL, "VRT_set_backend_hostname(backend, %s)" },
{ "backend.port",
PORTNAME, 0, NULL, "VRT_set_backend_portname(backend, %s)" },
};
static struct var vars[] = {
{ "req.request", STRING, 0, "VRT_GetReq(sp)" },
{ "obj.valid", BOOL, 0, "sp->obj->valid" },
{ "obj.cacheable", BOOL, 0, "sp->obj->cacheable" },
{ "obj.valid", BOOL, 0, "VRT_obj_valid(sp)" },
{ "obj.cacheable", BOOL, 0, "VRT_obj_cacheable(sp)" },
{ "req.http.", HEADER, 0, NULL },
#if 0
{ "req.ttlfactor", FLOAT, 0, "req->ttlfactor" },
......@@ -569,7 +573,7 @@ HeaderVar(struct tokenlist *tl, struct token *t, struct var *vh)
v->fmt = STRING;
asprintf(&p, "VRT_GetHdr(sp, \"%s\")", v->name + vh->len);
assert(p != NULL);
v->cname = p;
v->rname = p;
return (v);
}
......@@ -648,7 +652,7 @@ Cond_Ip(struct var *vp, struct tokenlist *tl)
I(tl);
AddRef(tl, tl->t, R_ACL);
sbuf_printf(tl->fc, "ip_match(%s, acl_%*.*s)\n",
vp->cname,
vp->rname,
tl->t->e - tl->t->b,
tl->t->e - tl->t->b, tl->t->b);
NextToken(tl);
......@@ -657,7 +661,7 @@ Cond_Ip(struct var *vp, struct tokenlist *tl)
case T_NEQ:
I(tl);
sbuf_printf(tl->fc, "%s %*.*s ",
vp->cname,
vp->rname,
tl->t->e - tl->t->b,
tl->t->e - tl->t->b, tl->t->b);
NextToken(tl);
......@@ -682,7 +686,7 @@ Cond_String(struct var *vp, struct tokenlist *tl)
switch (tl->t->tok) {
case '~':
I(tl); sbuf_printf(tl->fc, "string_match(%s, ", vp->cname);
I(tl); sbuf_printf(tl->fc, "string_match(%s, ", vp->rname);
NextToken(tl);
ExpectErr(tl, CSTR);
sbuf_printf(tl->fc, "%*.*s)\n",
......@@ -694,7 +698,7 @@ Cond_String(struct var *vp, struct tokenlist *tl)
case T_NEQ:
I(tl);
sbuf_printf(tl->fc, "%sstrcmp(%s, ",
tl->t->tok == T_EQ ? "!" : "", vp->cname);
tl->t->tok == T_EQ ? "!" : "", vp->rname);
NextToken(tl);
ExpectErr(tl, CSTR);
sbuf_printf(tl->fc, "%*.*s)\n",
......@@ -703,7 +707,7 @@ Cond_String(struct var *vp, struct tokenlist *tl)
NextToken(tl);
break;
default:
I(tl); sbuf_printf(tl->fc, "%s != (void*)0", vp->cname);
I(tl); sbuf_printf(tl->fc, "%s != (void*)0", vp->rname);
break;
}
}
......@@ -713,7 +717,7 @@ Cond_Int(struct var *vp, struct tokenlist *tl)
{
I(tl);
sbuf_printf(tl->fc, "%s ", vp->cname);
sbuf_printf(tl->fc, "%s ", vp->rname);
switch (tl->t->tok) {
case T_EQ:
case T_NEQ:
......@@ -764,7 +768,7 @@ Cond_Bool(struct var *vp, struct tokenlist *tl)
{
I(tl);
sbuf_printf(tl->fc, "%s\n", vp->cname);
sbuf_printf(tl->fc, "%s\n", vp->rname);
}
static void
......@@ -921,19 +925,13 @@ Action(struct tokenlist *tl)
sbuf_printf(tl->fc, "VCL_no_cache(sp);\n");
return;
case T_DELIVER:
I(tl); sbuf_printf(tl->fc, "VRT_done(sp, HND_Deliver);\n");
return;
case T_LOOKUP:
I(tl); sbuf_printf(tl->fc, "VRT_done(sp, HND_Lookup);\n");
return;
case T_PASS:
I(tl); sbuf_printf(tl->fc, "VRT_done(sp, HND_Pass);\n");
return;
case T_FETCH:
I(tl); sbuf_printf(tl->fc, "VRT_done(sp, HND_Fetch);\n");
return;
case T_INSERT:
I(tl); sbuf_printf(tl->fc, "VRT_done(sp, HND_Insert);\n");
I(tl); sbuf_printf(tl->fc, "VRT_done(sp, VRT_H_%*.*s);\n",
at->e - at->b,
at->e - at->b, at->b);
return;
case T_ERROR:
if (tl->t->tok == CNUM)
......@@ -949,7 +947,7 @@ Action(struct tokenlist *tl)
NextToken(tl);
} else
sbuf_printf(tl->fc, "(const char *)0);\n");
I(tl); sbuf_printf(tl->fc, "VRT_done(sp, HND_Error);\n");
I(tl); sbuf_printf(tl->fc, "VRT_done(sp, VRT_H_error);\n");
return;
case T_SWITCH_CONFIG:
ExpectErr(tl, ID);
......@@ -988,7 +986,7 @@ Action(struct tokenlist *tl)
ERRCHK(tl);
assert(vp != NULL);
I(tl);
sbuf_printf(tl->fc, "%s ", vp->cname);
sbuf_printf(tl->fc, "%s ", vp->rname);
NextToken(tl);
switch (vp->fmt) {
case INT:
......@@ -1186,20 +1184,22 @@ Backend(struct tokenlist *tl)
t_be = tl->t;
AddDef(tl, tl->t, R_BACKEND);
I(tl);
sbuf_printf(tl->fh, "static struct backend VGC_backend_%*.*s;\n",
tl->t->e - tl->t->b,
tl->t->e - tl->t->b, tl->t->b);
sbuf_printf(tl->fc, "static struct backend VGC_backend_%*.*s;\n",
sbuf_printf(tl->fh,
"#define VGC_backend_%*.*s (VCL_conf.backend[%d])\n",
tl->t->e - tl->t->b,
tl->t->e - tl->t->b, tl->t->b);
tl->t->e - tl->t->b, tl->t->b, tl->nbackend);
sbuf_printf(tl->fc, "static void\n");
I(tl);
sbuf_printf(tl->fc,
"VGC_init_backend_%*.*s (struct backend *backend)\n",
I(tl); sbuf_printf(tl->fc,
"VGC_init_backend_%*.*s (void)\n",
tl->t->e - tl->t->b,
tl->t->e - tl->t->b, tl->t->b);
I(tl);
sbuf_printf(tl->fc, "{\n");
I(tl); sbuf_printf(tl->fc,
"\tstruct backend *backend = VGC_backend_%*.*s;\n",
tl->t->e - tl->t->b,
tl->t->e - tl->t->b, tl->t->b);
I(tl); sbuf_printf(tl->fc, "\tconst char *p;\n");
NextToken(tl);
ExpectErr(tl, '{');
NextToken(tl);
......@@ -1220,21 +1220,24 @@ Backend(struct tokenlist *tl)
ExpectErr(tl, CSTR);
t_host = tl->t;
host = EncString(tl->t);
I(tl);
sbuf_printf(tl->fc, "\t%s = %*.*s;\n",
vp->cname,
I(tl); sbuf_printf(tl->fc, "\tp = %*.*s;\n",
tl->t->e - tl->t->b,
tl->t->e - tl->t->b, tl->t->b);
I(tl); sbuf_printf(tl->fc, "\t");
sbuf_printf(tl->fc, vp->lname, "p");
sbuf_printf(tl->fc, ";\n");
NextToken(tl);
break;
case PORTNAME:
ExpectErr(tl, CSTR);
t_port = tl->t;
port = EncString(tl->t);
sbuf_printf(tl->fc, "\t%s = %*.*s;\n",
vp->cname,
I(tl); sbuf_printf(tl->fc, "\tp = %*.*s;\n",
tl->t->e - tl->t->b,
tl->t->e - tl->t->b, tl->t->b);
I(tl); sbuf_printf(tl->fc, "\t");
sbuf_printf(tl->fc, vp->lname, "p");
sbuf_printf(tl->fc, ";\n");
NextToken(tl);
break;
default:
......@@ -1279,6 +1282,7 @@ Backend(struct tokenlist *tl)
I(tl);
sbuf_printf(tl->fc, "}\n");
sbuf_printf(tl->fc, "\n");
tl->nbackend++;
}
/*--------------------------------------------------------------------*/
......@@ -1549,6 +1553,9 @@ EmitInitFunc(struct tokenlist *tl)
"\nstatic void\n"
"VGC_Init(void)\n"
"{\n\n");
sbuf_printf(tl->fc,
"\tVRT_alloc_backends(&VCL_conf);\n");
TAILQ_FOREACH(r, &tl->refs, list) {
switch(r->type) {
......@@ -1558,9 +1565,7 @@ EmitInitFunc(struct tokenlist *tl)
break;
case R_BACKEND:
sbuf_printf(tl->fc,
"\tVGC_init_backend_%*.*s(&VGC_backend_%*.*s);\n",
r->name->e - r->name->b,
r->name->e - r->name->b, r->name->b,
"\tVGC_init_backend_%*.*s();\n",
r->name->e - r->name->b,
r->name->e - r->name->b, r->name->b);
break;
......@@ -1585,7 +1590,7 @@ EmitStruct(struct tokenlist *tl)
sbuf_printf(tl->fc, "\t.miss_func = VGC_function_vcl_miss,\n");
sbuf_printf(tl->fc, "\t.fetch_func = VGC_function_vcl_fetch,\n");
sbuf_printf(tl->fc,
"\t.default_backend = &VGC_backend_default,\n");
"\t.nbackend = %d,\n", tl->nbackend);
sbuf_printf(tl->fc,
"\t.ref = VGC_ref,\n");
sbuf_printf(tl->fc,
......@@ -1616,6 +1621,8 @@ VCC_Compile(struct sbuf *sb, const char *b, const char *e)
tokens.fh = sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND);
assert(tokens.fh != NULL);
sbuf_printf(tokens.fc, "extern struct VCL_conf VCL_conf;\n");
tokens.b = b;
if (e == NULL)
e = strchr(b, '\0');
......
......@@ -404,79 +404,7 @@ vcl_output_lang_h(FILE *f)
fputs(" * XXX: *MUST* be rerun.\n", f);
fputs(" */\n", f);
fputs("\n", f);
fputs("/* XXX: This include is bad. The VCL compiler shouldn't know about it. */\n", f);
fputs("#include <sys/queue.h>\n", f);
fputs("\n", f);
fputs("struct sess;\n", f);
fputs("typedef void sesscb_f(struct sess *sp);\n", f);
fputs("\n", f);
fputs("#define VCA_ADDRBUFSIZE 32\n", f);
fputs("\n", f);
fputs("struct object { \n", f);
fputs(" unsigned char hash[16];\n", f);
fputs(" unsigned refcnt;\n", f);
fputs(" unsigned valid;\n", f);
fputs(" unsigned cacheable;\n", f);
fputs("\n", f);
fputs(" unsigned busy;\n", f);
fputs(" unsigned len;\n", f);
fputs("\n", f);
fputs(" char *header;\n", f);
fputs("\n", f);
fputs(" TAILQ_HEAD(, storage) store;\n", f);
fputs("};\n", f);
fputs("enum handling {\n", f);
fputs(" HND_Error = (1 << 0),\n", f);
fputs(" HND_Pipe = (1 << 1),\n", f);
fputs(" HND_Pass = (1 << 2),\n", f);
fputs(" HND_Lookup = (1 << 3),\n", f);
fputs(" HND_Fetch = (1 << 4),\n", f);
fputs(" HND_Insert = (1 << 5),\n", f);
fputs(" HND_Deliver = (1 << 6),\n", f);
fputs("};\n", f);
fputs("\n", f);
fputs("struct sess {\n", f);
fputs(" int fd;\n", f);
fputs("\n", f);
fputs(" /* formatted ascii client address */\n", f);
fputs(" char addr[VCA_ADDRBUFSIZE];\n", f);
fputs("\n", f);
fputs(" /* HTTP request */\n", f);
fputs(" struct http *http;\n", f);
fputs("\n", f);
fputs(" enum handling handling;\n", f);
fputs("\n", f);
fputs(" TAILQ_ENTRY(sess) list;\n", f);
fputs("\n", f);
fputs(" sesscb_f *sesscb;\n", f);
fputs("\n", f);
fputs(" struct backend *backend;\n", f);
fputs(" struct object *obj;\n", f);
fputs(" struct VCL_conf *vcl;\n", f);
fputs("\n", f);
fputs(" /* Various internal stuff */\n", f);
fputs(" struct event *rd_e;\n", f);
fputs(" struct sessmem *mem;\n", f);
fputs("};\n", f);
fputs("\n", f);
fputs("struct backend {\n", f);
fputs(" const char *hostname;\n", f);
fputs(" const char *portname;\n", f);
fputs(" struct addrinfo *addr;\n", f);
fputs(" unsigned ip;\n", f);
fputs(" double responsetime;\n", f);
fputs(" double timeout;\n", f);
fputs(" double bandwidth;\n", f);
fputs(" int down;\n", f);
fputs("\n", f);
fputs(" /* internal stuff */\n", f);
fputs(" struct vbe *vbe;\n", f);
fputs("};\n", f);
fputs("\n", f);
fputs("#if 0\n", f);
fputs("int ip_match(unsigned, struct vcl_acl *);\n", f);
fputs("int string_match(const char *, const char *);\n", f);
fputs("#endif\n", f);
fputs("\n", f);
fputs("typedef void vcl_init_f(void);\n", f);
fputs("typedef int vcl_func_f(struct sess *sp);\n", f);
......@@ -489,7 +417,8 @@ vcl_output_lang_h(FILE *f)
fputs(" vcl_func_f *hit_func;\n", f);
fputs(" vcl_func_f *miss_func;\n", f);
fputs(" vcl_func_f *fetch_func;\n", f);
fputs(" struct backend *default_backend;\n", f);
fputs(" struct backend **backend;\n", f);
fputs(" unsigned nbackend;\n", f);
fputs(" struct vrt_ref *ref;\n", f);
fputs(" unsigned nref;\n", f);
fputs(" unsigned busy;\n", f);
......@@ -502,6 +431,17 @@ vcl_output_lang_h(FILE *f)
fputs(" * XXX: *MUST* be rerun.\n", f);
fputs(" */\n", f);
fputs("\n", f);
fputs("#define VRT_H_error (1 << 0)\n", f);
fputs("#define VRT_H_pipe (1 << 1)\n", f);
fputs("#define VRT_H_pass (1 << 2)\n", f);
fputs("#define VRT_H_lookup (1 << 3)\n", f);
fputs("#define VRT_H_fetch (1 << 4)\n", f);
fputs("#define VRT_H_insert (1 << 5)\n", f);
fputs("#define VRT_H_deliver (1 << 6)\n", f);
fputs("\n", f);
fputs("struct sess;\n", f);
fputs("struct backend;\n", f);
fputs("\n", f);
fputs("struct vrt_ref {\n", f);
fputs(" unsigned line;\n", f);
fputs(" unsigned pos;\n", f);
......@@ -527,7 +467,14 @@ vcl_output_lang_h(FILE *f)
fputs("\n", f);
fputs("char *VRT_GetHdr(struct sess *, const char *);\n", f);
fputs("char *VRT_GetReq(struct sess *);\n", f);
fputs("void VRT_handling(struct sess *sp, enum handling hand);\n", f);
fputs("void VRT_handling(struct sess *sp, unsigned hand);\n", f);
fputs("int VRT_obj_valid(struct sess *);\n", f);
fputs("int VRT_obj_cachable(struct sess *);\n", f);
fputs("\n", f);
fputs("void VRT_set_backend_hostname(struct backend *, const char *);\n", f);
fputs("void VRT_set_backend_portname(struct backend *, const char *);\n", f);
fputs("\n", f);
fputs("void VRT_alloc_backends(struct VCL_conf *cp);\n", f);
fputs("\n", f);
fputs("#define VRT_done(sp, hand) \\\n", f);
fputs(" do { \\\n", f);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment