[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