void RelVCL(struct VCL_conf *vc);
struct VCL_conf *GetVCL(void);
int CVCL_Load(const char *fn, const char *name);
+void VCL_recv_method(struct sess *);
+void VCL_hit_method(struct sess *);
+void VCL_miss_method(struct sess *);
+void VCL_fetch_method(struct sess *);
#ifdef CLI_PRIV_H
cli_func_t cli_func_config_list;
cli_func_t cli_func_config_load;
break;
}
- sp->handling = HND_Insert;
- sp->vcl->fetch_func(sp);
-
- assert(sp->handling == HND_Insert);
+ VCL_fetch_method(sp);
if (http_GetHdr(hp, "Content-Length", &b))
cls = fetch_straight(w, sp, fd, hp, b);
static pthread_cond_t shdcnd;
+/*--------------------------------------------------------------------*/
+
static int
LookupSession(struct worker *w, struct sess *sp)
{
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);
MD5Update(&ctx, b, strlen(b));
MD5Final(key, &ctx);
o = hash->lookup(key, w->nobj);
+ sp->obj = o;
if (o == w->nobj) {
VSL(SLT_Debug, 0, "Lookup new %p %s", o, b);
w->nobj = NULL;
+ VCL_miss_method(sp);
} else {
+ /* XXX: wait while obj->busy */
VSL(SLT_Debug, 0, "Lookup found %p %s", o, b);
- }
- /*
- * 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;
+ VCL_hit_method(sp);
}
return (0);
}
sp->backend = sp->vcl->default_backend;
- /*
- * Call the VCL recv function.
- * Default action is to lookup
- */
- sp->handling = HND_Lookup;
-
- sp->vcl->recv_func(sp);
+ VCL_recv_method(sp);
for (done = 0; !done; ) {
switch(sp->handling) {
done = 1;
break;
default:
- VSL(SLT_Handling, sp->fd, "Unclass");
- assert(sp->handling == HND_Unclass);
- assert(sp->handling != HND_Unclass);
+ INCOMPL();
}
}
if (http_GetHdr(sp->http, "Connection", &b) &&
/*--------------------------------------------------------------------*/
-void
-VCL_pass(VCL_FARGS)
-{
-
- sess->handling = HND_Pass;
- sess->done++;
-}
-
-void VCL_insert(VCL_FARGS) { }
-void VCL_deliver(VCL_FARGS) { }
-
-void VCL_fetch(VCL_FARGS) {
- sess->handling = HND_Fetch;
- sess->done++;
-}
-
void
VCL_error(VCL_FARGS, unsigned err, const char *str)
{
VSL(SLT_VCL, 0, "%u", u);
}
+/*--------------------------------------------------------------------*/
+
+static const char *
+HandlingName(unsigned u)
+{
+
+ switch (u) {
+ case HND_Error: return ("Error");
+ case HND_Pass: return ("Pass");
+ case HND_Pipe: return ("Pipe");
+ case HND_Lookup: return ("Lookup");
+ case HND_Fetch: return ("Fetch");
+ case HND_Insert: return ("Insert");
+ case HND_Deliver: return ("Deliver");
+ default: return (NULL);
+ }
+}
+
+static void
+CheckHandling(struct sess *sp, const char *func, unsigned bitmap)
+{
+ unsigned u;
+ const char *n;
+
+ u = sp->handling;
+ n = HandlingName(u);
+ if (n != NULL)
+ VSL(SLT_Handling, sp->fd, "%s(): %s", func, n);
+ else
+ VSL(SLT_Handling, sp->fd, "%s(): Illegal: 0x%x", func, u);
+ if (u & (u - 1))
+ VSL(SLT_Debug, sp->fd,
+ "Illegal handling after %s function: 0x%x", func, u);
+ else if (!(u & bitmap))
+ VSL(SLT_Debug, sp->fd,
+ "Wrong handling after %s function: 0x%x", func, u);
+ else
+ return;
+ sp->handling = HND_Error;
+}
+
+#define VCL_method(func, bitmap) \
+void \
+VCL_##func##_method(struct sess *sp) \
+{ \
+ \
+ sp->handling = 0; \
+ sp->vcl->func##_func(sp); \
+ CheckHandling(sp, #func, (bitmap)); \
+}
+
+VCL_method(recv, HND_Error|HND_Pass|HND_Pipe|HND_Lookup)
+VCL_method(miss, HND_Error|HND_Pass|HND_Pipe|HND_Fetch)
+VCL_method(hit, HND_Error|HND_Pass|HND_Pipe|HND_Deliver)
+VCL_method(fetch, HND_Error|HND_Pass|HND_Pipe|HND_Insert)