[master] 59e3bef Add a "inifin" facility to make Init/Fini activities happen in the right order: Init is done first to last "inifin", Fini is done in opposite order, last to first.

Poul-Henning Kamp phk at FreeBSD.org
Fri Dec 13 16:24:40 CET 2013


commit 59e3bef7519c9e60c222a4ce8e7bbe338983eee5
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Fri Dec 13 15:23:13 2013 +0000

    Add a "inifin" facility to make Init/Fini activities happen in the
    right order:  Init is done first to last "inifin", Fini is done
    in opposite order, last to first.
    
    This replaces the several ad-hoc facilities we had.

diff --git a/lib/libvcc/vcc_action.c b/lib/libvcc/vcc_action.c
index 79786ef..99f97eb 100644
--- a/lib/libvcc/vcc_action.c
+++ b/lib/libvcc/vcc_action.c
@@ -165,6 +165,7 @@ static void
 parse_new(struct vcc *tl)
 {
 	struct symbol *sy1, *sy2, *sy3;
+	struct inifin *ifp;
 	const char *p, *s_obj, *s_init, *s_struct, *s_fini;
 	char buf1[128];
 	char buf2[128];
@@ -213,7 +214,8 @@ parse_new(struct vcc *tl)
 
 	bprintf(buf1, ", &%s, \"%s\"", sy1->name, sy1->name);
 	vcc_Eval_Func(tl, s_init, buf1, "ASDF", s_init + strlen(s_init) + 1);
-	Fd(tl, 0, "\t%s(&%s);\n", s_fini, sy1->name);
+	ifp = New_IniFin(tl);
+	VSB_printf(ifp->fin, "\t%s(&%s);", s_fini, sy1->name);
 	ExpectErr(tl, ';');
 
 	bprintf(buf1, ", %s", sy1->name);
diff --git a/lib/libvcc/vcc_backend.c b/lib/libvcc/vcc_backend.c
index 6982fb2..ab0d8b2 100644
--- a/lib/libvcc/vcc_backend.c
+++ b/lib/libvcc/vcc_backend.c
@@ -275,6 +275,7 @@ vcc_ParseHostDef(struct vcc *tl, const struct token *t_be)
 	struct token *t_port = NULL;
 	struct token *t_hosthdr = NULL;
 	struct fld_spec *fs;
+	struct inifin *ifp;
 	struct vsb *vsb;
 	unsigned u;
 	double t;
@@ -420,9 +421,11 @@ vcc_ParseHostDef(struct vcc *tl, const struct token *t_be)
 	Fh(tl, 0, "%s", VSB_data(vsb));
 	VSB_delete(vsb);
 
-	Fi(tl, 0, "\tVRT_init_dir(cli, VCL_conf.director,\n"
-	    "\t    VGC_backend_%s, &vgc_dir_priv_%s);\n", vgcname, vgcname);
-	Ff(tl, 0, "\tVRT_fini_dir(cli, VGCDIR(%s));\n", vgcname);
+	ifp = New_IniFin(tl);
+	VSB_printf(ifp->ini,
+	    "\tVRT_init_dir(cli, VCL_conf.director,\n"
+	    "\t    VGC_backend_%s, &vgc_dir_priv_%s);", vgcname, vgcname);
+	VSB_printf(ifp->fin, "\tVRT_fini_dir(cli, VGCDIR(%s));", vgcname);
 	tl->ndirector++;
 }
 
diff --git a/lib/libvcc/vcc_compile.c b/lib/libvcc/vcc_compile.c
index a1d3b9b..7fa31aa 100644
--- a/lib/libvcc/vcc_compile.c
+++ b/lib/libvcc/vcc_compile.c
@@ -123,6 +123,23 @@ TlDupTok(struct vcc *tl, const struct token *tok)
 
 /*--------------------------------------------------------------------*/
 
+struct inifin *
+New_IniFin(struct vcc *tl)
+{
+	struct inifin *p;
+
+	p = TlAlloc(tl, sizeof *p);
+	AN(p);
+	p->magic = INIFIN_MAGIC;
+	p->ini = VSB_new_auto();
+	p->fin = VSB_new_auto();
+	p->n = ++tl->ninifin;
+	VTAILQ_INSERT_TAIL(&tl->inifin, p, list);
+	return (p);
+}
+
+/*--------------------------------------------------------------------*/
+
 int
 IsMethod(const struct token *t)
 {
@@ -181,43 +198,6 @@ Fc(const struct vcc *tl, int indent, const char *fmt, ...)
 	va_end(ap);
 }
 
-void
-Fi(const struct vcc *tl, int indent, const char *fmt, ...)
-{
-	va_list ap;
-
-	if (indent)
-		VSB_printf(tl->fi, "%*.*s", tl->iindent, tl->iindent, "");
-	va_start(ap, fmt);
-	VSB_vprintf(tl->fi, fmt, ap);
-	va_end(ap);
-}
-
-void
-Fd(const struct vcc *tl, int indent, const char *fmt, ...)
-{
-	va_list ap;
-
-	if (indent)
-		VSB_printf(tl->fd, "%*.*s", tl->findent, tl->findent, "");
-	va_start(ap, fmt);
-	VSB_vprintf(tl->fd, fmt, ap);
-	va_end(ap);
-}
-
-
-void
-Ff(const struct vcc *tl, int indent, const char *fmt, ...)
-{
-	va_list ap;
-
-	if (indent)
-		VSB_printf(tl->ff, "%*.*s", tl->findent, tl->findent, "");
-	va_start(ap, fmt);
-	VSB_vprintf(tl->ff, fmt, ap);
-	va_end(ap);
-}
-
 /*--------------------------------------------------------------------*/
 
 void
@@ -318,10 +298,16 @@ LocTable(const struct vcc *tl)
 static void
 EmitInitFunc(const struct vcc *tl)
 {
+	struct inifin *p;
 
 	Fc(tl, 0, "\nstatic int\nVGC_Init(struct cli *cli)\n{\n\n");
-	AZ(VSB_finish(tl->fi));
-	VSB_cat(tl->fc, VSB_data(tl->fi));
+	VTAILQ_FOREACH(p, &tl->inifin, list) {
+		AZ(VSB_finish(p->ini));
+		if (VSB_len(p->ini))
+			Fc(tl, 0, "\t/* %u */\n%s\n", p->n, VSB_data(p->ini));
+		VSB_delete(p->ini);
+	}
+
 	Fc(tl, 0, "\treturn(0);\n");
 	Fc(tl, 0, "}\n");
 }
@@ -329,22 +315,17 @@ EmitInitFunc(const struct vcc *tl)
 static void
 EmitFiniFunc(const struct vcc *tl)
 {
-	unsigned u;
+	struct inifin *p;
 
 	Fc(tl, 0, "\nstatic void\nVGC_Fini(struct cli *cli)\n{\n\n");
 
-	AZ(VSB_finish(tl->fd));
-	VSB_cat(tl->fc, VSB_data(tl->fd));
-
-	/*
-	 * 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);
+	VTAILQ_FOREACH_REVERSE(p, &tl->inifin, inifinhead, list) {
+		AZ(VSB_finish(p->fin));
+		if (VSB_len(p->fin))
+			Fc(tl, 0, "\t/* %u */\n%s\n", p->n, VSB_data(p->fin));
+		VSB_delete(p->fin);
+	}
 
-	AZ(VSB_finish(tl->ff));
-	VSB_cat(tl->fc, VSB_data(tl->ff));
 	Fc(tl, 0, "}\n");
 }
 
@@ -519,6 +500,7 @@ vcc_NewVcc(const struct vcc *tl0)
 		tl->err_unref = 1;
 	}
 	VTAILQ_INIT(&tl->symbols);
+	VTAILQ_INIT(&tl->inifin);
 	VTAILQ_INIT(&tl->membits);
 	VTAILQ_INIT(&tl->tokens);
 	VTAILQ_INIT(&tl->sources);
@@ -534,18 +516,6 @@ vcc_NewVcc(const struct vcc *tl0)
 	tl->fh = VSB_new_auto();
 	assert(tl->fh != NULL);
 
-	/* Init C code */
-	tl->fi = VSB_new_auto();
-	assert(tl->fi != NULL);
-
-	/* Destroy Objects */
-	tl->fd = VSB_new_auto();
-	assert(tl->fd != NULL);
-
-	/* Finish C code */
-	tl->ff = VSB_new_auto();
-	assert(tl->ff != NULL);
-
 	/* body code of methods */
 	for (i = 0; i < VCL_MET_MAX; i++) {
 		tl->fm[i] = VSB_new_auto();
@@ -584,8 +554,6 @@ vcc_DestroyTokenList(struct vcc *tl, char *ret)
 
 	VSB_delete(tl->fh);
 	VSB_delete(tl->fc);
-	VSB_delete(tl->fi);
-	VSB_delete(tl->ff);
 	for (i = 0; i < VCL_MET_MAX; i++)
 		VSB_delete(tl->fm[i]);
 
@@ -603,6 +571,7 @@ vcc_CompileSource(const struct vcc *tl0, struct vsb *sb, struct source *sp)
 	struct vcc *tl;
 	struct symbol *sym;
 	const struct var *v;
+	struct inifin *ifp;
 	char *of;
 	int i;
 
@@ -678,7 +647,9 @@ vcc_CompileSource(const struct vcc *tl0, struct vsb *sb, struct source *sp)
 	}
 
 	/* Configure the default director */
-	Fi(tl, 0, "\tVCL_conf.director[0] = VCL_conf.director[%d];\n",
+	ifp = New_IniFin(tl);
+	VSB_printf(ifp->ini,
+	    "\tVCL_conf.director[0] = VCL_conf.director[%d];",
 	    tl->defaultdir);
 	vcc_AddRef(tl, tl->t_defaultdir, SYM_BACKEND);
 
diff --git a/lib/libvcc/vcc_compile.h b/lib/libvcc/vcc_compile.h
index cd72db9..07dbbf3 100644
--- a/lib/libvcc/vcc_compile.h
+++ b/lib/libvcc/vcc_compile.h
@@ -144,6 +144,17 @@ struct symbol {
 
 VTAILQ_HEAD(tokenhead, token);
 
+struct inifin {
+	unsigned		magic;
+#define INIFIN_MAGIC		0x583c274c
+	unsigned		n;
+	struct vsb		*ini;
+	struct vsb		*fin;
+	VTAILQ_ENTRY(inifin)	list;
+};
+
+VTAILQ_HEAD(inifinhead, inifin);
+
 struct vcc {
 	unsigned		magic;
 #define VCC_MAGIC		0x24ad719d
@@ -156,6 +167,9 @@ struct vcc {
 	const struct var	*vars;
 	VTAILQ_HEAD(, symbol)	symbols;
 
+	struct inifinhead	inifin;
+	unsigned		ninifin;
+
 	/* Instance section */
 	struct tokenhead	tokens;
 	VTAILQ_HEAD(, source)	sources;
@@ -165,15 +179,10 @@ struct vcc {
 	struct token		*t;
 	int			indent;
 	int			hindent;
-	int			iindent;
-	int			findent;
 	unsigned		cnt;
 
 	struct vsb		*fc;		/* C-code */
 	struct vsb		*fh;		/* H-code (before C-code) */
-	struct vsb		*fi;		/* Init func code */
-	struct vsb		*fd;		/* Object destructors */
-	struct vsb		*ff;		/* Finish func code */
 	struct vsb		*fb;		/* Body of current sub
 						 * NULL otherwise
 						 */
@@ -192,7 +201,6 @@ struct vcc {
 	struct token		*t_defaultdir;
 
 	unsigned		unique;
-	unsigned		nvmodpriv;
 
 	unsigned		err_unref;
 	unsigned		allow_inline_c;
@@ -237,6 +245,8 @@ void vcc_FieldsOk(struct vcc *tl, const struct fld_spec *fs);
 
 /* vcc_compile.c */
 extern struct method method_tab[];
+struct inifin *New_IniFin(struct vcc *tl);
+
 /*
  * H -> Header, before the C code
  * C -> C-code
@@ -250,12 +260,6 @@ void Fc(const struct vcc *tl, int indent, const char *fmt, ...)
     __printflike(3, 4);
 void Fb(const struct vcc *tl, int indent, const char *fmt, ...)
     __printflike(3, 4);
-void Fi(const struct vcc *tl, int indent, const char *fmt, ...)
-    __printflike(3, 4);
-void Ff(const struct vcc *tl, int indent, const char *fmt, ...)
-    __printflike(3, 4);
-void Fd(const struct vcc *tl, int indent, const char *fmt, ...)
-    __printflike(3, 4);
 void EncToken(struct vsb *sb, const struct token *t);
 int IsMethod(const struct token *t);
 void *TlAlloc(struct vcc *tl, unsigned len);
diff --git a/lib/libvcc/vcc_expr.c b/lib/libvcc/vcc_expr.c
index f9c5a83..fab381a 100644
--- a/lib/libvcc/vcc_expr.c
+++ b/lib/libvcc/vcc_expr.c
@@ -536,6 +536,7 @@ vcc_func(struct vcc *tl, struct expr **e, const char *cfunc,
 {
 	const char *p, *r;
 	struct expr *e1, *e2;
+	struct inifin *ifp;
 	enum var_type fmt;
 	char buf[32];
 
@@ -557,8 +558,10 @@ vcc_func(struct vcc *tl, struct expr **e, const char *cfunc,
 			    (int) (r - name), name);
 			p += strlen(p) + 1;
 		} else if (fmt == VOID && !strcmp(p, "PRIV_CALL")) {
-			bprintf(buf, "vmod_priv_%u", tl->nvmodpriv++);
+			bprintf(buf, "vmod_priv_%u", tl->unique++);
+			ifp = New_IniFin(tl);
 			Fh(tl, 0, "static struct vmod_priv %s;\n", buf);
+			VSB_printf(ifp->fin, "\tvmod_priv_fini(&%s);", buf);
 			e2 = vcc_mk_expr(VOID, "&%s", buf);
 			p += strlen(p) + 1;
 		} else if (fmt == ENUM) {
diff --git a/lib/libvcc/vcc_utils.c b/lib/libvcc/vcc_utils.c
index 88edc2d..4f2b99b 100644
--- a/lib/libvcc/vcc_utils.c
+++ b/lib/libvcc/vcc_utils.c
@@ -51,6 +51,7 @@ vcc_regexp(struct vcc *tl)
 	vre_t *t;
 	const char *error;
 	int erroroffset;
+	struct inifin *ifp;
 
 	Expect(tl, CSTR);
 	if (tl->err)
@@ -69,10 +70,11 @@ vcc_regexp(struct vcc *tl)
 	strcpy(p, buf);
 
 	Fh(tl, 0, "static void *%s;\n", buf);
-	Fi(tl, 0, "\tVRT_re_init(&%s, ",buf);
-	EncToken(tl->fi, tl->t);
-	Fi(tl, 0, ");\n");
-	Ff(tl, 0, "\tVRT_re_fini(%s);\n", buf);
+	ifp = New_IniFin(tl);
+	VSB_printf(ifp->ini, "\tVRT_re_init(&%s, ",buf);
+	EncToken(ifp->ini, tl->t);
+	VSB_printf(ifp->ini, ");");
+	VSB_printf(ifp->fin, "\tVRT_re_fini(%s);", buf);
 	return (p);
 }
 
diff --git a/lib/libvcc/vcc_vmod.c b/lib/libvcc/vcc_vmod.c
index a2dc029..98ffeb2 100644
--- a/lib/libvcc/vcc_vmod.c
+++ b/lib/libvcc/vcc_vmod.c
@@ -43,6 +43,7 @@ vcc_ParseImport(struct vcc *tl)
 	char fn[1024];
 	char buf[256];
 	struct token *mod, *t1;
+	struct inifin *ifp;
 	const char *modname;
 	const char *proto;
 	const char *abi;
@@ -105,15 +106,23 @@ vcc_ParseImport(struct vcc *tl)
 
 	Fh(tl, 0, "static void *VGC_vmod_%.*s;\n", PF(mod));
 
-	Fi(tl, 0, "\tif (VRT_Vmod_Init(&VGC_vmod_%.*s,\n", PF(mod));
-	Fi(tl, 0, "\t    &Vmod_%.*s_Func,\n", PF(mod));
-	Fi(tl, 0, "\t    sizeof(Vmod_%.*s_Func),\n", PF(mod));
-	Fi(tl, 0, "\t    \"%.*s\",\n", PF(mod));
-	Fi(tl, 0, "\t    ");
-	EncString(tl->fi, fn, NULL, 0);
-	Fi(tl, 0, ",\n\t    ");
-	Fi(tl, 0, "cli))\n");
-	Fi(tl, 0, "\t\treturn(1);\n");
+	ifp = New_IniFin(tl);
+
+	VSB_printf(ifp->ini, "\tif (VRT_Vmod_Init(&VGC_vmod_%.*s,\n", PF(mod));
+	VSB_printf(ifp->ini, "\t    &Vmod_%.*s_Func,\n", PF(mod));
+	VSB_printf(ifp->ini, "\t    sizeof(Vmod_%.*s_Func),\n", PF(mod));
+	VSB_printf(ifp->ini, "\t    \"%.*s\",\n", PF(mod));
+	VSB_printf(ifp->ini, "\t    ");
+	EncString(ifp->ini, fn, NULL, 0);
+	VSB_printf(ifp->ini, ",\n\t    ");
+	VSB_printf(ifp->ini, "cli))\n");
+	VSB_printf(ifp->ini, "\t\treturn(1);");
+
+	/* XXX: zero the function pointer structure ?*/
+	VSB_printf(ifp->fin, "\tvmod_priv_fini(&vmod_priv_%.*s);", PF(mod));
+	VSB_printf(ifp->fin, "\n\tVRT_Vmod_Fini(&VGC_vmod_%.*s);", PF(mod));
+
+	ifp = NULL;
 
 	SkipToken(tl, ';');
 
@@ -178,7 +187,10 @@ vcc_ParseImport(struct vcc *tl)
 			sym->args = p;
 		} else if (!strcmp(p, "INIT")) {
 			p += strlen(p) + 1;
-			Fi(tl, 0, "\t%s(&vmod_priv_%.*s, &VCL_conf);\n",
+			if (ifp == NULL)
+				ifp = New_IniFin(tl);
+			VSB_printf(ifp->ini,
+			    "\t%s(&vmod_priv_%.*s, &VCL_conf);",
 			    p, PF(mod));
 		} else {
 			sym = VCC_AddSymbolStr(tl, p, SYM_FUNC);
@@ -196,8 +208,4 @@ vcc_ParseImport(struct vcc *tl)
 		}
 	}
 	Fh(tl, 0, "\n%s\n", proto);
-
-	/* 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));
 }



More information about the varnish-commit mailing list