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