r5221 - in trunk/varnish-cache: include lib/libvcl lib/libvmod_std
phk at varnish-cache.org
phk at varnish-cache.org
Fri Sep 17 12:20:20 CEST 2010
Author: phk
Date: 2010-09-17 12:20:19 +0200 (Fri, 17 Sep 2010)
New Revision: 5221
Modified:
trunk/varnish-cache/include/vrt.h
trunk/varnish-cache/lib/libvcl/vcc_compile.c
trunk/varnish-cache/lib/libvcl/vcc_compile.h
trunk/varnish-cache/lib/libvcl/vcc_expr.c
trunk/varnish-cache/lib/libvcl/vcc_vmod.c
trunk/varnish-cache/lib/libvmod_std/vmod.py
trunk/varnish-cache/lib/libvmod_std/vmod.vcc
trunk/varnish-cache/lib/libvmod_std/vmod_std.c
Log:
Add an utterly evil feature to VMODs: Per-call private pointers.
Will describe evil details in sphinx docs in a moment.
Modified: trunk/varnish-cache/include/vrt.h
===================================================================
--- trunk/varnish-cache/include/vrt.h 2010-09-16 04:46:06 UTC (rev 5220)
+++ trunk/varnish-cache/include/vrt.h 2010-09-17 10:20:19 UTC (rev 5221)
@@ -185,12 +185,28 @@
int idx, const void *priv);
void VRT_fini_dir(struct cli *, struct director *);
-/* Modules related */
+/* VMOD/Modules related */
void VRT_Vmod_Init(void **hdl, void *ptr, int len, const char *nm,
const char *path);
void VRT_Vmod_Fini(void **hdl);
-typedef int vmod_meta_f(void **, const struct VCL_conf *);
+struct vmod_priv;
+typedef void vmod_priv_free_f(void *);
+struct vmod_priv {
+ void *priv;
+ vmod_priv_free_f *free;
+};
+
+typedef int vmod_init_f(struct vmod_priv *, const struct VCL_conf *);
+
+static inline void
+vmod_priv_fini(struct vmod_priv *p)
+{
+
+ if (p->priv != (void*)0 && p->free != (void*)0)
+ p->free(p->priv);
+}
+
/* Convert things to string */
char *VRT_IP_string(const struct sess *sp, const struct sockaddr *sa);
Modified: trunk/varnish-cache/lib/libvcl/vcc_compile.c
===================================================================
--- trunk/varnish-cache/lib/libvcl/vcc_compile.c 2010-09-16 04:46:06 UTC (rev 5220)
+++ trunk/varnish-cache/lib/libvcl/vcc_compile.c 2010-09-17 10:20:19 UTC (rev 5221)
@@ -298,8 +298,17 @@
static void
EmitFiniFunc(const struct vcc *tl)
{
+ unsigned u;
Fc(tl, 0, "\nstatic void\nVGC_Fini(struct cli *cli)\n{\n\n");
+
+ /*
+ * We do this here, so we are sure they happen before any
+ * per-vcl vmod_privs get cleaned.
+ */
+ for (u = 0; u < tl->nvmodpriv; u++)
+ Fc(tl, 0, "\tvmod_priv_fini(&vmod_priv_%u);\n", u);
+
vsb_finish(tl->ff);
AZ(vsb_overflowed(tl->ff));
vsb_cat(tl->fc, vsb_data(tl->ff));
Modified: trunk/varnish-cache/lib/libvcl/vcc_compile.h
===================================================================
--- trunk/varnish-cache/lib/libvcl/vcc_compile.h 2010-09-16 04:46:06 UTC (rev 5220)
+++ trunk/varnish-cache/lib/libvcl/vcc_compile.h 2010-09-17 10:20:19 UTC (rev 5221)
@@ -151,6 +151,7 @@
unsigned recnt;
unsigned nsockaddr;
+ unsigned nvmodpriv;
};
enum ref_type {
Modified: trunk/varnish-cache/lib/libvcl/vcc_expr.c
===================================================================
--- trunk/varnish-cache/lib/libvcl/vcc_expr.c 2010-09-16 04:46:06 UTC (rev 5220)
+++ trunk/varnish-cache/lib/libvcl/vcc_expr.c 2010-09-17 10:20:19 UTC (rev 5221)
@@ -425,6 +425,7 @@
const char *p, *q, *r;
struct expr *e1;
enum var_type fmt;
+ char buf[32];
(void)tl;
(void)e;
@@ -450,6 +451,14 @@
vsb_finish(e1->vsb);
AZ(vsb_overflowed(e1->vsb));
p += strlen(p) + 1;
+ } else if (fmt == VOID && !strcmp(p, "PRIV_CALL")) {
+ bprintf(buf, "vmod_priv_%u", tl->nvmodpriv++);
+ e1 = vcc_new_expr();
+ Fh(tl, 0, "struct vmod_priv %s;\n", buf);
+ vsb_printf(e1->vsb, "&%s", buf);
+ vsb_finish(e1->vsb);
+ AZ(vsb_overflowed(e1->vsb));
+ p += strlen(p) + 1;
} else {
vcc_expr0(tl, &e1, fmt);
ERRCHK(tl);
Modified: trunk/varnish-cache/lib/libvcl/vcc_vmod.c
===================================================================
--- trunk/varnish-cache/lib/libvcl/vcc_vmod.c 2010-09-16 04:46:06 UTC (rev 5220)
+++ trunk/varnish-cache/lib/libvcl/vcc_vmod.c 2010-09-17 10:20:19 UTC (rev 5221)
@@ -143,13 +143,12 @@
vcc_ErrWhere(tl, mod);
return;
}
+ Fh(tl, 0, "static struct vmod_priv vmod_priv_%.*s;\n", PF(mod));
for (; *spec != NULL; spec++) {
p = *spec;
- if (!strcmp(p, "META")) {
+ if (!strcmp(p, "INIT")) {
p += strlen(p) + 1;
- Fh(tl, 0, "static void *vmod_priv_%.*s;\n", PF(mod));
Fi(tl, 0, "\t%s(&vmod_priv_%.*s, &VCL_conf);\n", p, PF(mod));
- Ff(tl, 0, "\t%s(&vmod_priv_%.*s, 0);\n", p, PF(mod));
} else {
sym = VCC_AddSymbol(tl, p, SYM_FUNC);
p += strlen(p) + 1;
@@ -164,6 +163,7 @@
}
Fh(tl, 0, "\n%s\n", proto);
- /* XXX: zero the function pointer structure */
+ /* XXX: zero the function pointer structure ?*/
+ Ff(tl, 0, "\tvmod_priv_fini(&vmod_priv_%.*s);\n", PF(mod));
Ff(tl, 0, "\tVRT_Vmod_Fini(&VGC_vmod_%.*s);\n", PF(mod));
}
Modified: trunk/varnish-cache/lib/libvmod_std/vmod.py
===================================================================
--- trunk/varnish-cache/lib/libvmod_std/vmod.py 2010-09-16 04:46:06 UTC (rev 5220)
+++ trunk/varnish-cache/lib/libvmod_std/vmod.py 2010-09-17 10:20:19 UTC (rev 5221)
@@ -59,13 +59,14 @@
'DURATION': "double",
'INT': "int",
'HEADER': "const char *",
- 'PRIV_VCL': "void **",
+ 'PRIV_VCL': "struct vmod_priv *",
+ 'PRIV_CALL': "struct vmod_priv *",
'VOID': "void",
}
#######################################################################
-metaname = ""
+initname = ""
modname = "???"
pstruct = ""
pinit = ""
@@ -131,8 +132,8 @@
modname = l[2].strip();
continue
- if l[0] == "Meta":
- metaname = l[2].strip();
+ if l[0] == "Init":
+ initname = l[2].strip();
continue
if l[0] != "Function":
@@ -166,11 +167,11 @@
#######################################################################
-if metaname != "":
- plist += "int " + metaname + "(void **, const struct VCL_conf *);\n"
- pstruct += "\tvmod_meta_f\t*_meta;\n"
- pinit += "\t" + metaname + ",\n"
- slist += '\t"META\\0Vmod_Func_' + modname + '._meta",\n'
+if initname != "":
+ plist += "int " + initname + "(struct vmod_priv *, const struct VCL_conf *);\n"
+ pstruct += "\tvmod_init_f\t*_init;\n"
+ pinit += "\t" + initname + ",\n"
+ slist += '\t"INIT\\0Vmod_Func_' + modname + '._init",\n'
#######################################################################
@@ -179,6 +180,7 @@
fh.write('struct sess;\n')
fh.write('struct VCL_conf;\n')
+fh.write('struct vmod_priv;\n')
fh.write("\n");
fh.write(plist)
Modified: trunk/varnish-cache/lib/libvmod_std/vmod.vcc
===================================================================
--- trunk/varnish-cache/lib/libvmod_std/vmod.vcc 2010-09-16 04:46:06 UTC (rev 5220)
+++ trunk/varnish-cache/lib/libvmod_std/vmod.vcc 2010-09-17 10:20:19 UTC (rev 5221)
@@ -1,5 +1,5 @@
Module std
-Meta meta_function
-Function STRING toupper(STRING_LIST)
+Init init_function
+Function STRING toupper(PRIV_CALL, STRING_LIST)
Function STRING tolower(PRIV_VCL, STRING_LIST)
Function VOID set_ip_tos(INT)
Modified: trunk/varnish-cache/lib/libvmod_std/vmod_std.c
===================================================================
--- trunk/varnish-cache/lib/libvmod_std/vmod_std.c 2010-09-16 04:46:06 UTC (rev 5220)
+++ trunk/varnish-cache/lib/libvmod_std/vmod_std.c 2010-09-17 10:20:19 UTC (rev 5221)
@@ -1,5 +1,6 @@
#include <ctype.h>
#include <stdarg.h>
+#include <stdlib.h>
#include <netinet/in.h>
#include "vrt.h"
#include "../../bin/varnishd/cache.h"
@@ -48,12 +49,18 @@
}
const char *
-vmod_toupper(struct sess *sp, const char *s, ...)
+vmod_toupper(struct sess *sp, struct vmod_priv *priv, const char *s, ...)
{
const char *p;
va_list ap;
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
+ if (priv->priv == NULL) {
+ priv->priv = strdup("BAR");
+ priv->free = free;
+ } else {
+ assert(!strcmp(priv->priv, "BAR"));
+ }
va_start(ap, s);
p = vmod_updown(sp, 1, s, ap);
va_end(ap);
@@ -61,13 +68,13 @@
}
const char *
-vmod_tolower(struct sess *sp, void **vcl_priv, const char *s, ...)
+vmod_tolower(struct sess *sp, struct vmod_priv *priv, const char *s, ...)
{
const char *p;
va_list ap;
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
- assert(*vcl_priv == (void *)8);
+ assert(!strcmp(priv->priv, "FOO"));
va_start(ap, s);
p = vmod_updown(sp, 0, s, ap);
va_end(ap);
@@ -75,17 +82,11 @@
}
int
-meta_function(void **priv, const struct VCL_conf *cfg)
+init_function(struct vmod_priv *priv, const struct VCL_conf *cfg)
{
- if (cfg != NULL) {
- // Initialization in new VCL program
- // Hang any private data/state off *priv
- *priv = (void *)8;
- } else {
- // Cleaup in new VCL program
- // Cleanup/Free any private data/state hanging of *priv
- assert(*priv == (void *)8);
- *priv = NULL;
- }
+ (void)cfg;
+
+ priv->priv = strdup("FOO");
+ priv->free = free;
return (0);
}
More information about the varnish-commit
mailing list