Commit 59e3bef7 authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

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.
parent 21e0139e
...@@ -165,6 +165,7 @@ static void ...@@ -165,6 +165,7 @@ static void
parse_new(struct vcc *tl) parse_new(struct vcc *tl)
{ {
struct symbol *sy1, *sy2, *sy3; struct symbol *sy1, *sy2, *sy3;
struct inifin *ifp;
const char *p, *s_obj, *s_init, *s_struct, *s_fini; const char *p, *s_obj, *s_init, *s_struct, *s_fini;
char buf1[128]; char buf1[128];
char buf2[128]; char buf2[128];
...@@ -213,7 +214,8 @@ parse_new(struct vcc *tl) ...@@ -213,7 +214,8 @@ parse_new(struct vcc *tl)
bprintf(buf1, ", &%s, \"%s\"", sy1->name, sy1->name); bprintf(buf1, ", &%s, \"%s\"", sy1->name, sy1->name);
vcc_Eval_Func(tl, s_init, buf1, "ASDF", s_init + strlen(s_init) + 1); 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, ';'); ExpectErr(tl, ';');
bprintf(buf1, ", %s", sy1->name); bprintf(buf1, ", %s", sy1->name);
......
...@@ -275,6 +275,7 @@ vcc_ParseHostDef(struct vcc *tl, const struct token *t_be) ...@@ -275,6 +275,7 @@ vcc_ParseHostDef(struct vcc *tl, const struct token *t_be)
struct token *t_port = NULL; struct token *t_port = NULL;
struct token *t_hosthdr = NULL; struct token *t_hosthdr = NULL;
struct fld_spec *fs; struct fld_spec *fs;
struct inifin *ifp;
struct vsb *vsb; struct vsb *vsb;
unsigned u; unsigned u;
double t; double t;
...@@ -420,9 +421,11 @@ vcc_ParseHostDef(struct vcc *tl, const struct token *t_be) ...@@ -420,9 +421,11 @@ vcc_ParseHostDef(struct vcc *tl, const struct token *t_be)
Fh(tl, 0, "%s", VSB_data(vsb)); Fh(tl, 0, "%s", VSB_data(vsb));
VSB_delete(vsb); VSB_delete(vsb);
Fi(tl, 0, "\tVRT_init_dir(cli, VCL_conf.director,\n" ifp = New_IniFin(tl);
"\t VGC_backend_%s, &vgc_dir_priv_%s);\n", vgcname, vgcname); VSB_printf(ifp->ini,
Ff(tl, 0, "\tVRT_fini_dir(cli, VGCDIR(%s));\n", vgcname); "\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++; tl->ndirector++;
} }
......
...@@ -123,6 +123,23 @@ TlDupTok(struct vcc *tl, const struct token *tok) ...@@ -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 int
IsMethod(const struct token *t) IsMethod(const struct token *t)
{ {
...@@ -181,43 +198,6 @@ Fc(const struct vcc *tl, int indent, const char *fmt, ...) ...@@ -181,43 +198,6 @@ Fc(const struct vcc *tl, int indent, const char *fmt, ...)
va_end(ap); 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 void
...@@ -318,10 +298,16 @@ LocTable(const struct vcc *tl) ...@@ -318,10 +298,16 @@ LocTable(const struct vcc *tl)
static void static void
EmitInitFunc(const struct vcc *tl) EmitInitFunc(const struct vcc *tl)
{ {
struct inifin *p;
Fc(tl, 0, "\nstatic int\nVGC_Init(struct cli *cli)\n{\n\n"); Fc(tl, 0, "\nstatic int\nVGC_Init(struct cli *cli)\n{\n\n");
AZ(VSB_finish(tl->fi)); VTAILQ_FOREACH(p, &tl->inifin, list) {
VSB_cat(tl->fc, VSB_data(tl->fi)); 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, "\treturn(0);\n");
Fc(tl, 0, "}\n"); Fc(tl, 0, "}\n");
} }
...@@ -329,22 +315,17 @@ EmitInitFunc(const struct vcc *tl) ...@@ -329,22 +315,17 @@ EmitInitFunc(const struct vcc *tl)
static void static void
EmitFiniFunc(const struct vcc *tl) EmitFiniFunc(const struct vcc *tl)
{ {
unsigned u; struct inifin *p;
Fc(tl, 0, "\nstatic void\nVGC_Fini(struct cli *cli)\n{\n\n"); Fc(tl, 0, "\nstatic void\nVGC_Fini(struct cli *cli)\n{\n\n");
AZ(VSB_finish(tl->fd)); VTAILQ_FOREACH_REVERSE(p, &tl->inifin, inifinhead, list) {
VSB_cat(tl->fc, VSB_data(tl->fd)); AZ(VSB_finish(p->fin));
if (VSB_len(p->fin))
/* Fc(tl, 0, "\t/* %u */\n%s\n", p->n, VSB_data(p->fin));
* We do this here, so we are sure they happen before any VSB_delete(p->fin);
* per-vcl vmod_privs get cleaned. }
*/
for (u = 0; u < tl->nvmodpriv; u++)
Fc(tl, 0, "\tvmod_priv_fini(&vmod_priv_%u);\n", u);
AZ(VSB_finish(tl->ff));
VSB_cat(tl->fc, VSB_data(tl->ff));
Fc(tl, 0, "}\n"); Fc(tl, 0, "}\n");
} }
...@@ -519,6 +500,7 @@ vcc_NewVcc(const struct vcc *tl0) ...@@ -519,6 +500,7 @@ vcc_NewVcc(const struct vcc *tl0)
tl->err_unref = 1; tl->err_unref = 1;
} }
VTAILQ_INIT(&tl->symbols); VTAILQ_INIT(&tl->symbols);
VTAILQ_INIT(&tl->inifin);
VTAILQ_INIT(&tl->membits); VTAILQ_INIT(&tl->membits);
VTAILQ_INIT(&tl->tokens); VTAILQ_INIT(&tl->tokens);
VTAILQ_INIT(&tl->sources); VTAILQ_INIT(&tl->sources);
...@@ -534,18 +516,6 @@ vcc_NewVcc(const struct vcc *tl0) ...@@ -534,18 +516,6 @@ vcc_NewVcc(const struct vcc *tl0)
tl->fh = VSB_new_auto(); tl->fh = VSB_new_auto();
assert(tl->fh != NULL); 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 */ /* body code of methods */
for (i = 0; i < VCL_MET_MAX; i++) { for (i = 0; i < VCL_MET_MAX; i++) {
tl->fm[i] = VSB_new_auto(); tl->fm[i] = VSB_new_auto();
...@@ -584,8 +554,6 @@ vcc_DestroyTokenList(struct vcc *tl, char *ret) ...@@ -584,8 +554,6 @@ vcc_DestroyTokenList(struct vcc *tl, char *ret)
VSB_delete(tl->fh); VSB_delete(tl->fh);
VSB_delete(tl->fc); VSB_delete(tl->fc);
VSB_delete(tl->fi);
VSB_delete(tl->ff);
for (i = 0; i < VCL_MET_MAX; i++) for (i = 0; i < VCL_MET_MAX; i++)
VSB_delete(tl->fm[i]); VSB_delete(tl->fm[i]);
...@@ -603,6 +571,7 @@ vcc_CompileSource(const struct vcc *tl0, struct vsb *sb, struct source *sp) ...@@ -603,6 +571,7 @@ vcc_CompileSource(const struct vcc *tl0, struct vsb *sb, struct source *sp)
struct vcc *tl; struct vcc *tl;
struct symbol *sym; struct symbol *sym;
const struct var *v; const struct var *v;
struct inifin *ifp;
char *of; char *of;
int i; int i;
...@@ -678,7 +647,9 @@ vcc_CompileSource(const struct vcc *tl0, struct vsb *sb, struct source *sp) ...@@ -678,7 +647,9 @@ vcc_CompileSource(const struct vcc *tl0, struct vsb *sb, struct source *sp)
} }
/* Configure the default director */ /* 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); tl->defaultdir);
vcc_AddRef(tl, tl->t_defaultdir, SYM_BACKEND); vcc_AddRef(tl, tl->t_defaultdir, SYM_BACKEND);
......
...@@ -144,6 +144,17 @@ struct symbol { ...@@ -144,6 +144,17 @@ struct symbol {
VTAILQ_HEAD(tokenhead, token); 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 { struct vcc {
unsigned magic; unsigned magic;
#define VCC_MAGIC 0x24ad719d #define VCC_MAGIC 0x24ad719d
...@@ -156,6 +167,9 @@ struct vcc { ...@@ -156,6 +167,9 @@ struct vcc {
const struct var *vars; const struct var *vars;
VTAILQ_HEAD(, symbol) symbols; VTAILQ_HEAD(, symbol) symbols;
struct inifinhead inifin;
unsigned ninifin;
/* Instance section */ /* Instance section */
struct tokenhead tokens; struct tokenhead tokens;
VTAILQ_HEAD(, source) sources; VTAILQ_HEAD(, source) sources;
...@@ -165,15 +179,10 @@ struct vcc { ...@@ -165,15 +179,10 @@ struct vcc {
struct token *t; struct token *t;
int indent; int indent;
int hindent; int hindent;
int iindent;
int findent;
unsigned cnt; unsigned cnt;
struct vsb *fc; /* C-code */ struct vsb *fc; /* C-code */
struct vsb *fh; /* H-code (before 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 struct vsb *fb; /* Body of current sub
* NULL otherwise * NULL otherwise
*/ */
...@@ -192,7 +201,6 @@ struct vcc { ...@@ -192,7 +201,6 @@ struct vcc {
struct token *t_defaultdir; struct token *t_defaultdir;
unsigned unique; unsigned unique;
unsigned nvmodpriv;
unsigned err_unref; unsigned err_unref;
unsigned allow_inline_c; unsigned allow_inline_c;
...@@ -237,6 +245,8 @@ void vcc_FieldsOk(struct vcc *tl, const struct fld_spec *fs); ...@@ -237,6 +245,8 @@ void vcc_FieldsOk(struct vcc *tl, const struct fld_spec *fs);
/* vcc_compile.c */ /* vcc_compile.c */
extern struct method method_tab[]; extern struct method method_tab[];
struct inifin *New_IniFin(struct vcc *tl);
/* /*
* H -> Header, before the C code * H -> Header, before the C code
* C -> C-code * C -> C-code
...@@ -250,12 +260,6 @@ void Fc(const struct vcc *tl, int indent, const char *fmt, ...) ...@@ -250,12 +260,6 @@ void Fc(const struct vcc *tl, int indent, const char *fmt, ...)
__printflike(3, 4); __printflike(3, 4);
void Fb(const struct vcc *tl, int indent, const char *fmt, ...) void Fb(const struct vcc *tl, int indent, const char *fmt, ...)
__printflike(3, 4); __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); void EncToken(struct vsb *sb, const struct token *t);
int IsMethod(const struct token *t); int IsMethod(const struct token *t);
void *TlAlloc(struct vcc *tl, unsigned len); void *TlAlloc(struct vcc *tl, unsigned len);
......
...@@ -536,6 +536,7 @@ vcc_func(struct vcc *tl, struct expr **e, const char *cfunc, ...@@ -536,6 +536,7 @@ vcc_func(struct vcc *tl, struct expr **e, const char *cfunc,
{ {
const char *p, *r; const char *p, *r;
struct expr *e1, *e2; struct expr *e1, *e2;
struct inifin *ifp;
enum var_type fmt; enum var_type fmt;
char buf[32]; char buf[32];
...@@ -557,8 +558,10 @@ vcc_func(struct vcc *tl, struct expr **e, const char *cfunc, ...@@ -557,8 +558,10 @@ vcc_func(struct vcc *tl, struct expr **e, const char *cfunc,
(int) (r - name), name); (int) (r - name), name);
p += strlen(p) + 1; p += strlen(p) + 1;
} else if (fmt == VOID && !strcmp(p, "PRIV_CALL")) { } 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); 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); e2 = vcc_mk_expr(VOID, "&%s", buf);
p += strlen(p) + 1; p += strlen(p) + 1;
} else if (fmt == ENUM) { } else if (fmt == ENUM) {
......
...@@ -51,6 +51,7 @@ vcc_regexp(struct vcc *tl) ...@@ -51,6 +51,7 @@ vcc_regexp(struct vcc *tl)
vre_t *t; vre_t *t;
const char *error; const char *error;
int erroroffset; int erroroffset;
struct inifin *ifp;
Expect(tl, CSTR); Expect(tl, CSTR);
if (tl->err) if (tl->err)
...@@ -69,10 +70,11 @@ vcc_regexp(struct vcc *tl) ...@@ -69,10 +70,11 @@ vcc_regexp(struct vcc *tl)
strcpy(p, buf); strcpy(p, buf);
Fh(tl, 0, "static void *%s;\n", buf); Fh(tl, 0, "static void *%s;\n", buf);
Fi(tl, 0, "\tVRT_re_init(&%s, ",buf); ifp = New_IniFin(tl);
EncToken(tl->fi, tl->t); VSB_printf(ifp->ini, "\tVRT_re_init(&%s, ",buf);
Fi(tl, 0, ");\n"); EncToken(ifp->ini, tl->t);
Ff(tl, 0, "\tVRT_re_fini(%s);\n", buf); VSB_printf(ifp->ini, ");");
VSB_printf(ifp->fin, "\tVRT_re_fini(%s);", buf);
return (p); return (p);
} }
......
...@@ -43,6 +43,7 @@ vcc_ParseImport(struct vcc *tl) ...@@ -43,6 +43,7 @@ vcc_ParseImport(struct vcc *tl)
char fn[1024]; char fn[1024];
char buf[256]; char buf[256];
struct token *mod, *t1; struct token *mod, *t1;
struct inifin *ifp;
const char *modname; const char *modname;
const char *proto; const char *proto;
const char *abi; const char *abi;
...@@ -105,15 +106,23 @@ vcc_ParseImport(struct vcc *tl) ...@@ -105,15 +106,23 @@ vcc_ParseImport(struct vcc *tl)
Fh(tl, 0, "static void *VGC_vmod_%.*s;\n", PF(mod)); Fh(tl, 0, "static void *VGC_vmod_%.*s;\n", PF(mod));
Fi(tl, 0, "\tif (VRT_Vmod_Init(&VGC_vmod_%.*s,\n", PF(mod)); ifp = New_IniFin(tl);
Fi(tl, 0, "\t &Vmod_%.*s_Func,\n", PF(mod));
Fi(tl, 0, "\t sizeof(Vmod_%.*s_Func),\n", PF(mod)); VSB_printf(ifp->ini, "\tif (VRT_Vmod_Init(&VGC_vmod_%.*s,\n", PF(mod));
Fi(tl, 0, "\t \"%.*s\",\n", PF(mod)); VSB_printf(ifp->ini, "\t &Vmod_%.*s_Func,\n", PF(mod));
Fi(tl, 0, "\t "); VSB_printf(ifp->ini, "\t sizeof(Vmod_%.*s_Func),\n", PF(mod));
EncString(tl->fi, fn, NULL, 0); VSB_printf(ifp->ini, "\t \"%.*s\",\n", PF(mod));
Fi(tl, 0, ",\n\t "); VSB_printf(ifp->ini, "\t ");
Fi(tl, 0, "cli))\n"); EncString(ifp->ini, fn, NULL, 0);
Fi(tl, 0, "\t\treturn(1);\n"); 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, ';'); SkipToken(tl, ';');
...@@ -178,7 +187,10 @@ vcc_ParseImport(struct vcc *tl) ...@@ -178,7 +187,10 @@ vcc_ParseImport(struct vcc *tl)
sym->args = p; sym->args = p;
} else if (!strcmp(p, "INIT")) { } else if (!strcmp(p, "INIT")) {
p += strlen(p) + 1; 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)); p, PF(mod));
} else { } else {
sym = VCC_AddSymbolStr(tl, p, SYM_FUNC); sym = VCC_AddSymbolStr(tl, p, SYM_FUNC);
...@@ -196,8 +208,4 @@ vcc_ParseImport(struct vcc *tl) ...@@ -196,8 +208,4 @@ vcc_ParseImport(struct vcc *tl)
} }
} }
Fh(tl, 0, "\n%s\n", proto); 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));
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment