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
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);
......
......@@ -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++;
}
......
......@@ -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);
......
......@@ -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);
......
......@@ -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) {
......
......@@ -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);
}
......
......@@ -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));
}
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