[master] 1f3fbd8 Make VSC/varnishstat sorta-work again.

Poul-Henning Kamp phk at varnish-cache.org
Wed Nov 23 22:11:13 CET 2011


commit 1f3fbd8eb67062fe211e731cccaf7251b74d2840
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Wed Nov 23 08:57:48 2011 +0000

    Make VSC/varnishstat sorta-work again.

diff --git a/bin/varnishstat/varnishstat.c b/bin/varnishstat/varnishstat.c
index 2fe7ffb..5d9226f 100644
--- a/bin/varnishstat/varnishstat.c
+++ b/bin/varnishstat/varnishstat.c
@@ -52,7 +52,9 @@ do_xml_cb(void *priv, const struct VSC_point * const pt)
 	uint64_t val;
 
 	(void)priv;
-	assert(!strcmp(pt->fmt, "uint64_t"));
+	if (pt == NULL)
+		return (0);
+	assert(!strcmp(pt->desc->fmt, "uint64_t"));
 	val = *(const volatile uint64_t*)pt->ptr;
 
 	printf("\t<stat>\n");
@@ -60,10 +62,10 @@ do_xml_cb(void *priv, const struct VSC_point * const pt)
 		printf("\t\t<type>%s</type>\n", pt->class);
 	if (strcmp(pt->ident, ""))
 		printf("\t\t<ident>%s</ident>\n", pt->ident);
-	printf("\t\t<name>%s</name>\n", pt->name);
+	printf("\t\t<name>%s</name>\n", pt->desc->name);
 	printf("\t\t<value>%ju</value>\n", val);
-	printf("\t\t<flag>%c</flag>\n", pt->flag);
-	printf("\t\t<description>%s</description>\n", pt->desc);
+	printf("\t\t<flag>%c</flag>\n", pt->desc->flag);
+	printf("\t\t<description>%s</description>\n", pt->desc->sdesc);
 	printf("\t</stat>\n");
 	return (0);
 }
@@ -91,9 +93,11 @@ do_json_cb(void *priv, const struct VSC_point * const pt)
 	uint64_t val;
 	int *jp;
 
-	jp = priv;
+	if (pt == NULL)
+		return (0);
 
-	assert(!strcmp(pt->fmt, "uint64_t"));
+	jp = priv;
+	assert(!strcmp(pt->desc->fmt, "uint64_t"));
 	val = *(const volatile uint64_t*)pt->ptr;
 
 	if (*jp) *jp = 0; else printf(",\n");
@@ -104,15 +108,15 @@ do_json_cb(void *priv, const struct VSC_point * const pt)
 		printf("%s.", pt->class);
 	if (pt->ident[0])
 		printf("%s.", pt->ident);
-	printf("%s\": {", pt->name);
+	printf("%s\": {", pt->desc->name);
 
 	if (strcmp(pt->class, "")) printf("\"type\": \"%s\", ",  pt->class);
 	if (strcmp(pt->ident, "")) printf("\"ident\": \"%s\", ", pt->ident);
 
 	printf("\"value\": %ju, ", val);
 
-	printf("\"flag\": \"%c\", ", pt->flag);
-	printf("\"description\": \"%s\"", pt->desc);
+	printf("\"flag\": \"%c\", ", pt->desc->flag);
+	printf("\"description\": \"%s\"", pt->desc->sdesc);
 	printf("}");
 
 	if (*jp) printf("\n");
@@ -153,22 +157,24 @@ do_once_cb(void *priv, const struct VSC_point * const pt)
 	uint64_t val;
 	int i;
 
+	if (pt == NULL)
+		return (0);
 	op = priv;
-	assert(!strcmp(pt->fmt, "uint64_t"));
+	assert(!strcmp(pt->desc->fmt, "uint64_t"));
 	val = *(const volatile uint64_t*)pt->ptr;
 	i = 0;
 	if (strcmp(pt->class, ""))
 		i += printf("%s.", pt->class);
 	if (strcmp(pt->ident, ""))
 		i += printf("%s.", pt->ident);
-	i += printf("%s", pt->name);
+	i += printf("%s", pt->desc->name);
 	if (i > op->pad)
 		op->pad = i + 1;
 	printf("%*.*s", op->pad - i, op->pad - i, "");
-	if (pt->flag == 'a' || pt->flag == 'c')
-		printf("%12ju %12.2f %s\n", val, val / op->up, pt->desc);
+	if (pt->desc->flag == 'a' || pt->desc->flag == 'c')
+		printf("%12ju %12.2f %s\n", val, val / op->up, pt->desc->sdesc);
 	else
-		printf("%12ju %12s %s\n", val, ".  ", pt->desc);
+		printf("%12ju %12s %s\n", val, ".  ", pt->desc->sdesc);
 	return (0);
 }
 
@@ -197,10 +203,10 @@ do_list_cb(void *priv, const struct VSC_point * const pt)
 		i += fprintf(stderr, "%s.", pt->class);
 	if (strcmp(pt->ident, ""))
 		i += fprintf(stderr, "%s.", pt->ident);
-	i += fprintf(stderr, "%s", pt->name);
+	i += fprintf(stderr, "%s", pt->desc->name);
 	if (i < 30)
 		fprintf(stderr, "%*s", i - 30, "");
-	fprintf(stderr, " %s\n", pt->desc);
+	fprintf(stderr, " %s\n", pt->desc->sdesc);
 	return (0);
 }
 
@@ -253,7 +259,6 @@ main(int argc, char * const *argv)
 	int delay = 1, once = 0, xml = 0, json = 0, do_repeat = 0;
 
 	vd = VSM_New();
-	VSC_Setup(vd);
 
 	while ((c = getopt(argc, argv, VSC_ARGS "1f:lVw:xjt:")) != -1) {
 		switch (c) {
@@ -261,8 +266,6 @@ main(int argc, char * const *argv)
 			once = 1;
 			break;
 		case 'l':
-			if (VSC_Open(vd, 1))
-				exit(1);
 			list_fields(vd);
 			exit(0);
 		case 'V':
@@ -285,9 +288,6 @@ main(int argc, char * const *argv)
 		}
 	}
 
-	if (VSC_Open(vd, 1))
-		exit(1);
-
 	VSC_C_main = VSC_Main(vd);
 	AN(VSC_C_main);
 
diff --git a/bin/varnishstat/varnishstat_curses.c b/bin/varnishstat/varnishstat_curses.c
index 9fa6b82..d4e714c 100644
--- a/bin/varnishstat/varnishstat_curses.c
+++ b/bin/varnishstat/varnishstat_curses.c
@@ -81,7 +81,9 @@ do_curses_cb(void *priv, const struct VSC_point * const sp)
 	char buf[128];
 
 	(void)priv;
-	assert(!strcmp(sp->fmt, "uint64_t"));
+	if (sp == NULL)
+		return (0);
+	assert(!strcmp(sp->desc->fmt, "uint64_t"));
 
 	pt = calloc(sizeof *pt, 1);
 	AN(pt);
@@ -89,7 +91,7 @@ do_curses_cb(void *priv, const struct VSC_point * const sp)
 
 	pt->ptr = sp->ptr;
 	pt->ref = *pt->ptr;
-	pt->flag = sp->flag;
+	pt->flag = sp->desc->flag;
 
 	*buf = '\0';
 	if (strcmp(sp->class, "")) {
@@ -100,9 +102,9 @@ do_curses_cb(void *priv, const struct VSC_point * const sp)
 		strcat(buf, sp->ident);
 		strcat(buf, ".");
 	}
-	strcat(buf, sp->name);
+	strcat(buf, sp->desc->name);
 	strcat(buf, " - ");
-	strcat(buf, sp->desc);
+	strcat(buf, sp->desc->sdesc);
 	pt->name = strdup(buf);
 	AN(pt->name);
 	return (0);
@@ -144,7 +146,6 @@ do_curses(struct VSM_data *vd, const struct VSC_C_main *VSC_C_main,
 	int ch, line;
 	struct pt *pt;
 	double act, lact;
-	unsigned seq;
 
 	(void)initscr();
 	AC(raw());
@@ -157,7 +158,6 @@ do_curses(struct VSM_data *vd, const struct VSC_C_main *VSC_C_main,
 		/*
 		 * Initialization goes in outher loop
 		 */
-		seq = VSM_Seq(vd);
 		prep_pts(vd);
 		AC(erase());
 		AC(refresh());
@@ -170,15 +170,11 @@ do_curses(struct VSM_data *vd, const struct VSC_C_main *VSC_C_main,
 		lact = 0;
 
 		while (1) {
-			if (seq != VSM_Seq(vd))
-				break;
 			/*
 			 * Break to outher loop if we need to re-read file.
 			 * Only check if it looks like nothing is happening.
 			 */
 			act = VSC_C_main->cache_hit + VSC_C_main->cache_miss + 1;
-			if (act == lact && VSM_ReOpen(vd, 1))
-				break;
 			lact = act;
 
 			AZ(gettimeofday(&tv, NULL));
diff --git a/include/vapi/vsc.h b/include/vapi/vsc.h
index 3cf16c6..6ebab31 100644
--- a/include/vapi/vsc.h
+++ b/include/vapi/vsc.h
@@ -26,6 +26,10 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
+ * This is the public API for the VSC access.
+ *
+ * VSC is a "subclass" of VSM.
+ *
  */
 
 #ifndef VAPI_VSC_H_INCLUDED
@@ -34,17 +38,12 @@
 #include "vapi/vsc_int.h"
 
 struct VSM_data;
+struct VSM_fantom;
 
 /*---------------------------------------------------------------------
  * VSC level access functions
  */
 
-void VSC_Setup(struct VSM_data *vd);
-	/*
-	 * Setup vd for use with VSC functions.
-	 * Must be called once before any other VSC function is called
-	 */
-
 #define VSC_ARGS	"f:n:"
 #define VSC_n_USAGE	VSM_n_USAGE
 #define VSC_f_USAGE	"[-f field_name,...]"
@@ -55,39 +54,58 @@ int VSC_Arg(struct VSM_data *vd, int arg, const char *opt);
 	/*
 	 * Handle standard stat-presenter arguments
 	 * Return:
-	 *	-1 error
+	 *	-1 error, VSM_Error() returns diagnostic string
 	 *	 0 not handled
 	 *	 1 Handled.
 	 */
 
-int VSC_Open(struct VSM_data *vd, int diag);
-	/*
-	 * Open shared memory for VSC processing.
-	 * args and returns as VSM_Open()
-	 */
-
-struct VSC_C_main *VSC_Main(const struct VSM_data *vd);
+struct VSC_C_main *VSC_Main(struct VSM_data *vd);
 	/*
 	 * return Main stats structure
 	 * returns NULL until child has been started.
 	 */
 
+struct VSC_desc {
+	const char *name;		/* field name			*/
+	const char *fmt;		/* field format ("uint64_t")	*/
+	int flag;			/* 'c' = counter, 'g' = gauge	*/
+	const char *sdesc;		/* short description		*/
+	const char *ldesc;		/* long description		*/
+};
+
 struct VSC_point {
 	const char *class;		/* stat struct type		*/
 	const char *ident;		/* stat struct ident		*/
-	const char *name;		/* field name			*/
-	const char *fmt;		/* field format ("uint64_t")	*/
-	int flag;			/* 'a' = counter, 'i' = gauge	*/
-	const char *desc;		/* description			*/
+	const struct VSC_desc *desc;	/* point description		*/
 	const volatile void *ptr;	/* field value			*/
+	struct VSM_fantom *vf;
 };
 
 typedef int VSC_iter_f(void *priv, const struct VSC_point *const pt);
 
-int VSC_Iter(const struct VSM_data *vd, VSC_iter_f *func, void *priv);
+int VSC_Iter(struct VSM_data *vd, VSC_iter_f *func, void *priv);
 	/*
 	 * Iterate over all statistics counters, calling "func" for
 	 * each counter not suppressed by any "-f" arguments.
+	 *
+ 	 * Func is called with pt == NULL, whenever VSM allocations
+	 * change (child restart, allocations/deallocations)
+	 *
+	 * Returns:
+	 * 	!=0:	func returned non-zero
+	 *	-1:	No VSC's available
+	 *	0: 	Done
 	 */
 
+/**********************************************************************
+ * Precompiled VSC_desc's for all know VSCs.
+ */
+#define VSC_F(n,t,l,f,d,e)
+#define VSC_DO(U,l,t) extern const struct VSC_desc VSC_desc_##l[];
+#define VSC_DONE(U,l,t)
+#include "tbl/vsc_all.h"
+#undef VSC_F
+#undef VSC_DO
+#undef VSC_DONE
+
 #endif /* VAPI_VSC_H_INCLUDED */
diff --git a/lib/libvarnishapi/vsc.c b/lib/libvarnishapi/vsc.c
index c9facfd..54bf20f 100644
--- a/lib/libvarnishapi/vsc.c
+++ b/lib/libvarnishapi/vsc.c
@@ -47,15 +47,22 @@
 #include "vqueue.h"
 #include "vsm_api.h"
 
+struct vsc_pt {
+	unsigned		magic;
+#define VSC_PT_MAGIC		0xa4ff159a
+	struct VSC_point	point;
+	VTAILQ_ENTRY(vsc_pt)	list;
+};
+
 struct vsc_sf {
 	unsigned		magic;
-#define VSL_SF_MAGIC		0x558478dd
-	VTAILQ_ENTRY(vsc_sf)	next;
+#define VSC_SF_MAGIC		0x558478dd
+	VTAILQ_ENTRY(vsc_sf)	list;
 	int			flags;
-#define VSL_SF_EXCL		(1 << 0)
-#define VSL_SF_CL_WC		(1 << 1)
-#define VSL_SF_ID_WC		(1 << 2)
-#define VSL_SF_NM_WC		(1 << 3)
+#define VSC_SF_EXCL		(1 << 0)
+#define VSC_SF_CL_WC		(1 << 1)
+#define VSC_SF_ID_WC		(1 << 2)
+#define VSC_SF_NM_WC		(1 << 3)
 	char			*class;
 	char			*ident;
 	char			*name;
@@ -65,40 +72,56 @@ struct vsc {
 	unsigned		magic;
 #define VSC_MAGIC		0x3373554a
 
-	int			sf_init;
+	VTAILQ_HEAD(, vsc_pt)	pt_list;
 	VTAILQ_HEAD(, vsc_sf)	sf_list;
-
+	struct VSM_fantom	main_fantom;
+	struct VSM_fantom	iter_fantom;
 };
 
 
 /*--------------------------------------------------------------------*/
 
-void
-VSC_Setup(struct VSM_data *vd)
+static struct vsc *
+vsc_setup(struct VSM_data *vd)
 {
 
 	CHECK_OBJ_NOTNULL(vd, VSM_MAGIC);
-	AZ(vd->vsc);
-	ALLOC_OBJ(vd->vsc, VSC_MAGIC);
-	AN(vd->vsc);
-	VTAILQ_INIT(&vd->vsc->sf_list);
+	if (vd->vsc == NULL) {
+		ALLOC_OBJ(vd->vsc, VSC_MAGIC);
+		VTAILQ_INIT(&vd->vsc->sf_list);
+		VTAILQ_INIT(&vd->vsc->pt_list);
+	}
+	CHECK_OBJ_NOTNULL(vd->vsc, VSC_MAGIC);
+	return (vd->vsc);
 }
 
 /*--------------------------------------------------------------------*/
 
-void
-VSC_Delete(struct VSM_data *vd)
+static void
+vsc_delete_pts(struct vsc *vsc)
+{
+	struct vsc_pt *pt;
+	struct VSM_fantom *vf = NULL;
+
+	while(!VTAILQ_EMPTY(&vsc->pt_list)) {
+		pt = VTAILQ_FIRST(&vsc->pt_list);
+		VTAILQ_REMOVE(&vsc->pt_list, pt, list);
+		if (pt->point.vf != vf) {
+			vf = pt->point.vf;
+			free(vf);
+		}
+		FREE_OBJ(pt);
+	}
+}
+
+static void
+vsc_delete_sfs(struct vsc *vsc)
 {
 	struct vsc_sf *sf;
-	struct vsc *vsc;
 
-	CHECK_OBJ_NOTNULL(vd, VSM_MAGIC);
-	vsc = vd->vsc;
-	vd->vsc = NULL;
-	CHECK_OBJ_NOTNULL(vsc, VSC_MAGIC);
 	while(!VTAILQ_EMPTY(&vsc->sf_list)) {
 		sf = VTAILQ_FIRST(&vsc->sf_list);
-		VTAILQ_REMOVE(&vsc->sf_list, sf, next);
+		VTAILQ_REMOVE(&vsc->sf_list, sf, list);
 		free(sf->class);
 		free(sf->ident);
 		free(sf->name);
@@ -106,39 +129,42 @@ VSC_Delete(struct VSM_data *vd)
 	}
 }
 
-/*--------------------------------------------------------------------*/
-
-static int
-vsc_sf_arg(const struct VSM_data *vd, const char *opt)
+void
+VSC_Delete(struct VSM_data *vd)
 {
 	struct vsc *vsc;
-	struct vsc_sf *sf;
-	char **av, *q, *p;
-	int i;
 
 	CHECK_OBJ_NOTNULL(vd, VSM_MAGIC);
 	vsc = vd->vsc;
+	vd->vsc = NULL;
 	CHECK_OBJ_NOTNULL(vsc, VSC_MAGIC);
+	vsc_delete_sfs(vsc);
+	vsc_delete_pts(vsc);
+	FREE_OBJ(vsc);
+}
 
-	if (VTAILQ_EMPTY(&vsc->sf_list)) {
-		if (*opt == '^')
-			vsc->sf_init = 1;
-	}
+/*--------------------------------------------------------------------*/
+
+static int
+vsc_f_arg(struct VSM_data *vd, const char *opt)
+{
+	struct vsc *vsc = vsc_setup(vd);
+	struct vsc_sf *sf;
+	char **av, *q, *p;
+	int i;
 
 	av = VAV_Parse(opt, NULL, ARGV_COMMA);
 	AN(av);
-	if (av[0] != NULL) {
-		vd->diag(vd->priv, "Parse error: %s", av[0]);
-		return (-1);
-	}
+	if (av[0] != NULL)
+		return (vsm_diag(vd, "Parse error: %s", av[0]));
 	for (i = 1; av[i] != NULL; i++) {
-		ALLOC_OBJ(sf, VSL_SF_MAGIC);
+		ALLOC_OBJ(sf, VSC_SF_MAGIC);
 		AN(sf);
-		VTAILQ_INSERT_TAIL(&vsc->sf_list, sf, next);
+		VTAILQ_INSERT_TAIL(&vsc->sf_list, sf, list);
 
 		p = av[i];
 		if (*p == '^') {
-			sf->flags |= VSL_SF_EXCL;
+			sf->flags |= VSC_SF_EXCL;
 			p++;
 		}
 
@@ -167,21 +193,21 @@ vsc_sf_arg(const struct VSM_data *vd, const char *opt)
 			q = strchr(sf->class, '*');
 			if (q != NULL && q[1] == '\0') {
 				*q = '\0';
-				sf->flags |= VSL_SF_CL_WC;
+				sf->flags |= VSC_SF_CL_WC;
 			}
 		}
 		if (sf->ident != NULL) {
 			q = strchr(sf->ident, '*');
 			if (q != NULL && q[1] == '\0') {
 				*q = '\0';
-				sf->flags |= VSL_SF_ID_WC;
+				sf->flags |= VSC_SF_ID_WC;
 			}
 		}
 		if (sf->name != NULL) {
 			q = strchr(sf->name, '*');
 			if (q != NULL && q[1] == '\0') {
 				*q = '\0';
-				sf->flags |= VSL_SF_NM_WC;
+				sf->flags |= VSC_SF_NM_WC;
 			}
 		}
 	}
@@ -195,10 +221,8 @@ int
 VSC_Arg(struct VSM_data *vd, int arg, const char *opt)
 {
 
-	CHECK_OBJ_NOTNULL(vd, VSM_MAGIC);
-	AN(vd->vsc);
 	switch (arg) {
-	case 'f': return (vsc_sf_arg(vd, opt));
+	case 'f': return (vsc_f_arg(vd, opt));
 	case 'n': return (VSM_n_Arg(vd, opt));
 	default:
 		return (0);
@@ -207,33 +231,19 @@ VSC_Arg(struct VSM_data *vd, int arg, const char *opt)
 
 /*--------------------------------------------------------------------*/
 
-int
-VSC_Open(struct VSM_data *vd, int diag)
-{
-	int i;
-
-	CHECK_OBJ_NOTNULL(vd, VSM_MAGIC);
-	AN(vd->vsc);
-
-	i = VSM_Open(vd, diag);
-	return (i);
-}
-
-/*--------------------------------------------------------------------*/
-
 struct VSC_C_main *
-VSC_Main(const struct VSM_data *vd)
+VSC_Main(struct VSM_data *vd)
 {
-	struct VSM_fantom vf;
+	struct vsc *vsc = vsc_setup(vd);
 
-	CHECK_OBJ_NOTNULL(vd, VSM_MAGIC);
-	CHECK_OBJ_NOTNULL(vd->vsc, VSC_MAGIC);
-
-	if (!VSM_Get(vd, &vf, VSC_CLASS, "", ""))
+	if (!vd->head && VSM_Open(vd))
 		return (NULL);
-	return ((void*)vf.b);
+	if (!VSM_Get(vd, &vsc->main_fantom, VSC_CLASS, "", ""))
+		return (NULL);
+	return ((void*)vsc->main_fantom.b);
 }
 
+#if 0
 /*--------------------------------------------------------------------
  * -1 -> unknown stats encountered.
  */
@@ -256,23 +266,28 @@ iter_call(const struct vsc *vsc, VSC_iter_f *func, void *priv,
     const struct VSC_point *const sp)
 {
 	struct vsc_sf *sf;
+	struct vsc_pt *pt;
 	int good;
 
 	CHECK_OBJ_NOTNULL(vsc, VSC_MAGIC);
 
-	if (VTAILQ_EMPTY(&vsc->sf_list))
-		return (func(priv, sp));
+	ALLOC_OBJ(pt, VSC_PT_MAGIC);
+	AN(pt);
 
-	good = vsc->sf_init;
+	if (VTAILQ_EMPTY(&vsc->sf_list)) {
+		VTAILQ_INSERT_TAIL(&vsc->pt_list, pt, list);
+		return (func(priv, sp));
+	}
 
-	VTAILQ_FOREACH(sf, &vsc->sf_list, next) {
-		if (iter_test(sf->class, sp->class, sf->flags & VSL_SF_CL_WC))
+	good = 0;
+	VTAILQ_FOREACH(sf, &vsc->sf_list, list) {
+		if (iter_test(sf->class, sp->class, sf->flags & VSC_SF_CL_WC))
 			continue;
-		if (iter_test(sf->ident, sp->ident, sf->flags & VSL_SF_ID_WC))
+		if (iter_test(sf->ident, sp->ident, sf->flags & VSC_SF_ID_WC))
 			continue;
-		if (iter_test(sf->name, sp->name, sf->flags & VSL_SF_NM_WC))
+		if (iter_test(sf->name, sp->desc->name, sf->flags & VSC_SF_NM_WC))
 			continue;
-		if (sf->flags & VSL_SF_EXCL)
+		if (sf->flags & VSC_SF_EXCL)
 			good = 0;
 		else
 			good = 1;
@@ -283,26 +298,27 @@ iter_call(const struct vsc *vsc, VSC_iter_f *func, void *priv,
 }
 
 #define VSC_DO(U,l,t)							\
-	static int							\
+	static void							\
 	iter_##l(const struct vsc *vsc, struct VSM_fantom *vf,		\
-	    VSC_iter_f *func, void *priv)				\
+	    const struct VSC_desc *descs)				\
 	{								\
 		struct VSC_C_##l *st;					\
-		struct VSC_point sp;					\
+		struct VSM_fantom *vf2;					\
 		int i;							\
 									\
 		CHECK_OBJ_NOTNULL(vsc, VSC_MAGIC);			\
 		st = vf->b;						\
 		sp.class = t;						\
-		sp.ident = vf->chunk->ident;
+		sp.ident = vf->chunk->ident;				\
+		sp.desc = descs++;					\
+		vf2 = malloc(sizeof *vf2);				\
+		AN(vf2);						\
+		memcpy(vf2, vf, sizeof *vf2);
 
 #define VSC_F(nn,tt,ll,ff,dd,ee)					\
-		sp.name = #nn;						\
-		sp.fmt = #tt;						\
-		sp.flag = ff;						\
-		sp.desc = dd;						\
 		sp.ptr = &st->nn;					\
-		i = iter_call(vsc, func, priv, &sp);			\
+		sp.vf = vf2;						\
+		i = iter_call(vsc, &sp);				\
 		if (i)							\
 			return(i);
 
@@ -315,19 +331,14 @@ iter_call(const struct vsc *vsc, VSC_iter_f *func, void *priv,
 #undef VSC_F
 #undef VSC_DONE
 
-int
-VSC_Iter(const struct VSM_data *vd, VSC_iter_f *func, void *priv)
+static void
+vsc_build_pt_list(struct VSM_data *vd)
 {
-	struct vsc *vsc;
+	struct vsc *vsc = vsc_setup(vd);
 	struct VSM_fantom vf;
-	int i;
 
-	CHECK_OBJ_NOTNULL(vd, VSM_MAGIC);
-	vsc = vd->vsc;
-	CHECK_OBJ_NOTNULL(vsc, VSC_MAGIC);
-	i = 0;
-	if (!VSM_StillValid(vd, NULL))
-		return (-1);
+	vsc_delete_pts(vsc *vsc);
+
 	VSM_FOREACH_SAFE(&vf, vd) {
 		if (strcmp(vf.chunk->class, VSC_CLASS))
 			continue;
@@ -335,11 +346,8 @@ VSC_Iter(const struct VSM_data *vd, VSC_iter_f *func, void *priv)
 #define VSC_F(n,t,l,f,d,e)
 #define VSC_DONE(a,b,c)
 #define VSC_DO(U,l,t)						\
-		if (!strcmp(vf.chunk->type, t)) {		\
-			i = iter_##l(vsc, &vf, func, priv);	\
-			if (!i)					\
-				continue;			\
-		}
+		if (!strcmp(vf.chunk->type, t))			\
+			iter_##l(vsc, &vf, VSC_desc_##l);
 #include "tbl/vsc_all.h"
 #undef VSC_F
 #undef VSC_DO
@@ -349,3 +357,127 @@ VSC_Iter(const struct VSM_data *vd, VSC_iter_f *func, void *priv)
 	}
 	return (i);
 }
+#endif
+
+/*--------------------------------------------------------------------
+ */
+
+static void
+vsc_add_pt(struct vsc *vsc, const char *class, const char *ident,
+    const struct VSC_desc *desc, const volatile void *ptr,
+    struct VSM_fantom *vf)
+{
+	struct vsc_pt *pt;
+
+	ALLOC_OBJ(pt, VSC_PT_MAGIC);
+	AN(pt);
+	pt->point.class = class;
+	pt->point.ident = ident;
+	pt->point.desc = desc;
+	pt->point.ptr = ptr;
+	pt->point.vf = vf;
+	VTAILQ_INSERT_TAIL(&vsc->pt_list, pt, list);
+}
+
+#define VSC_DO(U,l,t)							\
+	static void							\
+	iter_##l(struct vsc *vsc, struct VSM_fantom *vf,		\
+	    const struct VSC_desc *descs)				\
+	{								\
+		struct VSC_C_##l *st;					\
+		struct VSM_fantom *vf2;					\
+		const char *class = t;					\
+									\
+		CHECK_OBJ_NOTNULL(vsc, VSC_MAGIC);			\
+		st = vf->b;						\
+		vf2 = malloc(sizeof *vf2);				\
+		AN(vf2);						\
+		memcpy(vf2, vf, sizeof *vf2);
+
+#define VSC_F(nn,tt,ll,ff,dd,ee)					\
+		vsc_add_pt(vsc, class, vf->chunk->ident, descs++,	\
+		    &st->nn, vf2);
+
+#define VSC_DONE(U,l,t)							\
+	}
+
+#include "tbl/vsc_all.h"
+#undef VSC_DO
+#undef VSC_F
+#undef VSC_DONE
+
+/*--------------------------------------------------------------------
+ */
+
+static void
+vsc_build_pt_list(struct VSM_data *vd)
+{
+	struct vsc *vsc = vsc_setup(vd);
+	struct VSM_fantom vf;
+
+	vsc_delete_pts(vsc);
+
+	VSM_FOREACH_SAFE(&vf, vd) {
+		if (strcmp(vf.chunk->class, VSC_CLASS))
+			continue;
+		/*lint -save -e525 -e539 */
+#define VSC_F(n,t,l,f,d,e)
+#define VSC_DONE(a,b,c)
+#define VSC_DO(U,l,t)						\
+		if (!strcmp(vf.chunk->type, t))			\
+			iter_##l(vsc, &vf, VSC_desc_##l);
+#include "tbl/vsc_all.h"
+#undef VSC_F
+#undef VSC_DO
+#undef VSC_DONE
+		/*lint -restore */
+	}
+
+	/* XXX: filter pt list */
+}
+
+/*--------------------------------------------------------------------
+ */
+
+int
+VSC_Iter(struct VSM_data *vd, VSC_iter_f *func, void *priv)
+{
+	struct vsc *vsc = vsc_setup(vd);
+	struct vsc_pt *pt;
+	int i;
+
+	if (1 != VSM_StillValid(vd, &vsc->iter_fantom)) {
+		if (!VSM_Get(vd, &vsc->iter_fantom, VSC_CLASS, "", "")) {
+			VSM_Close(vd);
+			if (!vd->head && VSM_Open(vd))
+				return (-1);
+			if (!VSM_Get(vd, &vsc->iter_fantom, VSC_CLASS, "", "")) {
+				return (-1);
+			}
+		}
+		AN(vd->head);
+		func(priv, NULL);
+		vsc_build_pt_list(vd);
+	}
+	AN(vd->head);
+	VTAILQ_FOREACH(pt, &vsc->pt_list, list) {
+		i = func(priv, &pt->point);
+		if (i)
+			return (i);
+	}
+	return (0);
+}
+
+/*--------------------------------------------------------------------
+ * Build the static point descriptions
+ */
+
+#define VSC_F(n,t,l,f,d,e)	{#n,#t,f,d,e},
+#define VSC_DO(U,l,t) const struct VSC_desc VSC_desc_##l[] = {
+#define VSC_DONE(U,l,t) };
+#include "tbl/vsc_all.h"
+#undef VSC_F
+#undef VSC_DO
+#undef VSC_DONE
+
+
diff --git a/lib/libvarnishapi/vsm.c b/lib/libvarnishapi/vsm.c
index 1d762e5..a9f176c 100644
--- a/lib/libvarnishapi/vsm.c
+++ b/lib/libvarnishapi/vsm.c
@@ -113,7 +113,7 @@ VSM_n_Arg(struct VSM_data *vd, const char *opt)
 {
 
 	CHECK_OBJ_NOTNULL(vd, VSM_MAGIC);
-	AN(vd->n_opt);
+	AN(opt);
 
 	REPLACE(vd->n_opt, opt);
 	if (VIN_N_Arg(vd->n_opt, NULL, NULL, &vd->fname))



More information about the varnish-commit mailing list