[5.2] b72f1c6 Rototill the last bit of the VSC-api and simplify varnishstat_curses accordingly.

PÃ¥l Hermunn Johansen hermunn at varnish-software.com
Fri Sep 15 11:17:13 UTC 2017


commit b72f1c645c40d7fdaf005170fe9b41854f0fcdcd
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Fri Sep 8 08:50:44 2017 +0000

    Rototill the last bit of the VSC-api and simplify varnishstat_curses
    accordingly.
    
    If somebody has time to push varnishstat in curses mode though the
    paces and check that everything works I'd appreciate it.

diff --git a/bin/varnishstat/varnishstat.c b/bin/varnishstat/varnishstat.c
index c622cc7..d114281 100644
--- a/bin/varnishstat/varnishstat.c
+++ b/bin/varnishstat/varnishstat.c
@@ -81,7 +81,7 @@ do_xml(struct vsm *vsm, struct vsc *vsc)
 	now = time(NULL);
 	(void)strftime(time_stamp, 20, "%Y-%m-%dT%H:%M:%S", localtime(&now));
 	printf("<varnishstat timestamp=\"%s\">\n", time_stamp);
-	(void)VSC_Iter(vsc, vsm, NULL, do_xml_cb, NULL, NULL);
+	(void)VSC_Iter(vsc, vsm, do_xml_cb, NULL);
 	printf("</varnishstat>\n");
 }
 
@@ -135,7 +135,7 @@ do_json(struct vsm *vsm, struct vsc *vsc)
 
 	(void)strftime(time_stamp, 20, "%Y-%m-%dT%H:%M:%S", localtime(&now));
 	printf("  \"timestamp\": \"%s\",\n", time_stamp);
-	(void)VSC_Iter(vsc, vsm, NULL, do_json_cb, NULL, &jp);
+	(void)VSC_Iter(vsc, vsm, do_json_cb, &jp);
 	printf("\n}\n");
 }
 
@@ -199,8 +199,8 @@ do_once(struct vsm *vsm, struct vsc *vsc)
 	memset(&op, 0, sizeof op);
 	op.pad = 18;
 
-	(void)VSC_Iter(vsc, vsm, NULL, do_once_cb_first, NULL, &op);
-	(void)VSC_Iter(vsc, vsm, NULL, do_once_cb, NULL, &op);
+	(void)VSC_Iter(vsc, vsm, do_once_cb_first, &op);
+	(void)VSC_Iter(vsc, vsm, do_once_cb, &op);
 }
 
 /*--------------------------------------------------------------------*/
@@ -230,7 +230,7 @@ list_fields(struct vsm *vsm, struct vsc *vsc)
 	printf("Field name                     Description\n");
 	printf("----------                     -----------\n");
 
-	(void)VSC_Iter(vsc, vsm, NULL, do_list_cb, NULL, NULL);
+	(void)VSC_Iter(vsc, vsm, do_list_cb, NULL);
 }
 
 /*--------------------------------------------------------------------*/
diff --git a/bin/varnishstat/varnishstat_curses.c b/bin/varnishstat/varnishstat_curses.c
index fcc96ef..dec9c47 100644
--- a/bin/varnishstat/varnishstat_curses.c
+++ b/bin/varnishstat/varnishstat_curses.c
@@ -72,7 +72,7 @@ struct pt {
 #define PT_MAGIC		0x41698E4F
 	VTAILQ_ENTRY(pt)	list;
 
-	struct VSC_point	*vpt;
+	const struct VSC_point	*vpt;
 
 	char			seen;
 
@@ -119,6 +119,7 @@ static int sample = 0;
 static int scale = 1;
 static double t_sample = 0.;
 static double interval = 1.;
+static int vsm_status = 0;
 
 static void
 init_hitrate(void)
@@ -226,130 +227,6 @@ build_pt_array(void)
 }
 
 static void
-delete_pt_list(void)
-{
-	struct pt *pt;
-	unsigned i = 0;
-
-	delete_pt_array();
-
-	while (!VTAILQ_EMPTY(&ptlist)) {
-		pt = VTAILQ_FIRST(&ptlist);
-		CHECK_OBJ_NOTNULL(pt, PT_MAGIC);
-		VTAILQ_REMOVE(&ptlist, pt, list);
-		VSC_Destroy_Point(&pt->vpt);
-		FREE_OBJ(pt);
-		i++;
-	}
-	assert(i == n_ptlist);
-	n_ptlist = 0;
-
-	update_position();
-}
-
-struct pt_priv {
-	unsigned		magic;
-#define PT_PRIV_MAGIC		0x34ACBAD6
-	VTAILQ_HEAD(, pt)	ptlist;
-	unsigned		n_ptlist;
-};
-
-static int __match_proto__(VSC_iter_f)
-build_pt_list_cb(void *priv, const struct VSC_point *vpt)
-{
-	struct pt_priv *pt_priv;
-	struct pt *pt;
-
-	if (vpt == NULL)
-		return (0);
-
-	CAST_OBJ_NOTNULL(pt_priv, priv, PT_PRIV_MAGIC);
-
-	AZ(strcmp(vpt->ctype, "uint64_t"));
-
-	if (!strcmp(vpt->name, "MGT.uptime"))
-		mgt_uptime = vpt->ptr;
-	if (!strcmp(vpt->name, "MAIN.uptime"))
-		main_uptime = vpt->ptr;
-	if (!strcmp(vpt->name, "MAIN.cache_hit"))
-		main_cache_hit = vpt->ptr;
-	if (!strcmp(vpt->name, "MAIN.cache_miss"))
-		main_cache_miss = vpt->ptr;
-
-	VTAILQ_FOREACH(pt, &ptlist, list) {
-		CHECK_OBJ_NOTNULL(pt, PT_MAGIC);
-		AN(pt->vpt->name);
-		if (strcmp(vpt->name, pt->vpt->name))
-			continue;
-		VTAILQ_REMOVE(&ptlist, pt, list);
-		AN(n_ptlist);
-		n_ptlist--;
-		VSC_Destroy_Point(&pt->vpt);
-		pt->vpt = VSC_Clone_Point(vpt);
-		AN(pt->vpt);
-		VTAILQ_INSERT_TAIL(&pt_priv->ptlist, pt, list);
-		pt_priv->n_ptlist++;
-		return (0);
-	}
-	AZ(pt);
-
-	ALLOC_OBJ(pt, PT_MAGIC);
-	AN(pt);
-
-	pt->vpt = VSC_Clone_Point(vpt);
-	AN(pt->vpt);
-
-	pt->last = *pt->vpt->ptr;
-
-	pt->ma_10.nmax = 10;
-	pt->ma_100.nmax = 100;
-	pt->ma_1000.nmax = 1000;
-
-	VTAILQ_INSERT_TAIL(&pt_priv->ptlist, pt, list);
-	pt_priv->n_ptlist++;
-
-	return (0);
-}
-
-static void
-build_pt_list(struct vsc *vsc, struct vsm *vsm)
-{
-	struct pt_priv pt_priv;
-	int i;
-	struct pt *pt_current = NULL;
-	int current_line = 0;
-
-	if (current < n_ptarray) {
-		pt_current = ptarray[current];
-		current_line = current - page_start;
-	}
-
-	pt_priv.magic = PT_PRIV_MAGIC;
-	VTAILQ_INIT(&pt_priv.ptlist);
-	pt_priv.n_ptlist = 0;
-
-	mgt_uptime = NULL;
-	main_uptime = NULL;
-	main_cache_hit = NULL;
-	main_cache_miss = NULL;
-
-	(void)VSC_Iter(vsc, vsm, NULL, build_pt_list_cb, NULL, &pt_priv);
-	delete_pt_list();
-	AN(VTAILQ_EMPTY(&ptlist));
-	AZ(n_ptlist);
-	VTAILQ_CONCAT(&ptlist, &pt_priv.ptlist, list);
-	n_ptlist = pt_priv.n_ptlist;
-	build_pt_array();
-
-	for (i = 0; pt_current != NULL && i < n_ptarray; i++)
-		if (ptarray[i] == pt_current)
-			break;
-	current = i;
-	page_start = current - current_line;
-	update_position();
-}
-
-static void
 sample_points(void)
 {
 	struct pt *pt;
@@ -528,11 +405,22 @@ print_duration(WINDOW *w, time_t t)
 }
 
 static void
+running(WINDOW *w, time_t up, int flg)
+{
+	if (vsm_status & flg) {
+		print_duration(w_status, up);
+	} else {
+		wattron(w, A_STANDOUT);
+		wprintw(w, "  Not Running");
+		wattroff(w, A_STANDOUT);
+	}
+}
+
+static void
 draw_status(void)
 {
 	time_t up_mgt = 0;
 	time_t up_chld = 0;
-	static const char discon[] = "*** DISCONNECTED ***";
 
 	AN(w_status);
 
@@ -543,14 +431,12 @@ draw_status(void)
 	if (main_uptime != NULL)
 		up_chld = *main_uptime;
 
-	mvwprintw(w_status, 0, 0, "Uptime mgt:  ");
-	print_duration(w_status, up_mgt);
-	mvwprintw(w_status, 1, 0, "Uptime child:");
-	print_duration(w_status, up_chld);
+	mvwprintw(w_status, 0, 0, "Uptime mgt:   ");
+	running(w_status, up_mgt, VSM_MGT_RUNNING);
+	mvwprintw(w_status, 1, 0, "Uptime child: ");
+	running(w_status, up_chld, VSM_WRK_RUNNING);
 
-	if (mgt_uptime == NULL)
-		mvwprintw(w_status, 0, COLS - strlen(discon), discon);
-	else if (COLS > 70) {
+	if (COLS > 70) {
 		mvwprintw(w_status, 0, getmaxx(w_status) - 37,
 		    "Hitrate n: %8u %8u %8u", hitrate.hr_10.n, hitrate.hr_100.n,
 		    hitrate.hr_1000.n);
@@ -1042,12 +928,62 @@ handle_keypress(int ch)
 	redraw = 1;
 }
 
+static void * __match_proto__(VSC_new_f)
+newpt(void *priv, const struct VSC_point *const vpt)
+{
+	struct pt *pt;
+
+	ALLOC_OBJ(pt, PT_MAGIC);
+	AN(pt);
+	AZ(priv);
+	pt->vpt = vpt;
+	pt->last = *pt->vpt->ptr;
+	pt->ma_10.nmax = 10;
+	pt->ma_100.nmax = 100;
+	pt->ma_1000.nmax = 1000;
+
+	VTAILQ_INSERT_TAIL(&ptlist, pt, list);
+	n_ptlist++;
+
+	AZ(strcmp(vpt->ctype, "uint64_t"));
+
+	if (!strcmp(vpt->name, "MGT.uptime"))
+		mgt_uptime = vpt->ptr;
+	if (!strcmp(vpt->name, "MAIN.uptime"))
+		main_uptime = vpt->ptr;
+	if (!strcmp(vpt->name, "MAIN.cache_hit"))
+		main_cache_hit = vpt->ptr;
+	if (!strcmp(vpt->name, "MAIN.cache_miss"))
+		main_cache_miss = vpt->ptr;
+	return (pt);
+}
+
+static void __match_proto__(VSC_destroy_f)
+delpt(void *priv, const struct VSC_point *const vpt)
+{
+	struct pt *pt;
+
+	AZ(priv);
+	CAST_OBJ_NOTNULL(pt, vpt->priv, PT_MAGIC);
+	VTAILQ_REMOVE(&ptlist, pt, list);
+	n_ptlist--;
+	FREE_OBJ(pt);
+	if (vpt->ptr == mgt_uptime)
+		mgt_uptime = NULL;
+	if (vpt->ptr == main_uptime)
+		main_uptime = NULL;
+	if (vpt->ptr == main_cache_hit)
+		main_cache_hit = NULL;
+	if (vpt->ptr == main_cache_miss)
+		main_cache_miss = NULL;
+}
+
 void
-do_curses(struct vsm *vd, struct vsc *vsc, double delay)
+do_curses(struct vsm *vsm, struct vsc *vsc, double delay)
 {
 	struct pollfd pollfd;
 	long t;
-	int ch, initial = 1;
+	int ch;
 	double now;
 
 	interval = delay;
@@ -1066,13 +1002,17 @@ do_curses(struct vsm *vd, struct vsc *vsc, double delay)
 	make_windows();
 	doupdate();
 
+	VSC_State(vsc, newpt, delpt, NULL);
+
+	rebuild = 1;
 	while (keep_running) {
-		if (initial ||
-		    (VSM_Status(vd) & (VSM_MGT_CHANGED|VSM_WRK_CHANGED))) {
+		vsm_status = VSM_Status(vsm);
+		rebuild |= vsm_status & ~(VSM_MGT_RUNNING|VSM_WRK_RUNNING);
+		if (rebuild) {
+			(void)VSC_Iter(vsc, vsm, NULL, NULL);
 			init_hitrate();
-			delete_pt_list();
-			build_pt_list(vsc, vd);
-			initial = 0;
+			build_pt_array();
+			redraw = 1;
 		}
 
 		now = VTIM_mono();
@@ -1080,8 +1020,6 @@ do_curses(struct vsm *vd, struct vsc *vsc, double delay)
 			sample = 1;
 		if (sample)
 			sample_data();
-		if (rebuild)
-			build_pt_array();
 		if (redraw)
 			draw_screen();
 
@@ -1103,6 +1041,8 @@ do_curses(struct vsm *vd, struct vsc *vsc, double delay)
 			break;
 		}
 	}
-	VSM_Destroy(&vd);
+	VSC_Destroy(&vsc);
+	AN(VTAILQ_EMPTY(&ptlist));
+	VSM_Destroy(&vsm);
 	AZ(endwin());
 }
diff --git a/bin/varnishtest/vtc_varnish.c b/bin/varnishtest/vtc_varnish.c
index d63b37e..965931c 100644
--- a/bin/varnishtest/vtc_varnish.c
+++ b/bin/varnishtest/vtc_varnish.c
@@ -849,7 +849,7 @@ varnish_vsc(const struct varnish *v, const char *arg)
 	dp.v = v;
 	dp.arg = arg;
 	(void)VSM_Status(v->vsm_vsc);
-	(void)VSC_Iter(v->vsc, v->vsm_vsc, NULL, do_stat_dump_cb, NULL, &dp);
+	(void)VSC_Iter(v->vsc, v->vsm_vsc, do_stat_dump_cb, &dp);
 }
 
 /**********************************************************************
@@ -914,8 +914,7 @@ varnish_expect(const struct varnish *v, char * const *av)
 	good = 0;
 	for (i = 0; i < 50; i++, (void)usleep(100000)) {
 		(void)VSM_Status(v->vsm_vsc);
-		good = VSC_Iter(v->vsc, v->vsm_vsc,
-		    NULL, do_expect_cb, NULL, &sp);
+		good = VSC_Iter(v->vsc, v->vsm_vsc, do_expect_cb, &sp);
 		if (!good) {
 			good = -2;
 			continue;
diff --git a/include/vapi/vsc.h b/include/vapi/vsc.h
index 6f747f7..969c243 100644
--- a/include/vapi/vsc.h
+++ b/include/vapi/vsc.h
@@ -41,25 +41,6 @@ struct vsm;
 struct vsc;
 struct vsm_fantom;
 
-/*---------------------------------------------------------------------
- * VSC level access functions
- */
-
-struct vsc *VSC_New(void);
-void VSC_Destroy(struct vsc **);
-
-int VSC_Arg(struct vsc *, char arg, const char *opt);
-	/*
-	 * Handle standard stat-presenter arguments
-	 * Return:
-	 *	-1 error, VSM_Error() returns diagnostic string
-	 *	 0 not handled
-	 *	 1 Handled.
-	 */
-
-struct VSC_level_desc;
-struct VSC_point;
-
 struct VSC_level_desc {
 	const char *name;		/* name */
 	const char *label;		/* label */
@@ -71,50 +52,104 @@ struct VSC_point {
 	const volatile uint64_t *ptr;	/* field value			*/
 	const char *name;		/* field name			*/
 	const char *ctype;		/* C-type			*/
-	int semantics;			/* semantics			*/
-	int format;			/* display format		*/
+	int semantics;			/* semantics
+					 * 'c' = Counter
+					 * 'g' = Gauge
+					 * 'b' = bitmap
+					 * '?' = unknown
+					 */
+	int format;			/* display format
+					 * 'i' = integer
+					 * 'B' = bytes
+					 * 'b' = bitmap
+					 * 'd' = duration
+					 * '?' = unknown
+					 */
 	const struct VSC_level_desc *level; /* verbosity level		*/
 	const char *sdesc;		/* short description		*/
 	const char *ldesc;		/* long description		*/
+	void *priv;			/* return val from VSC_new_f	*/
 };
 
-struct VSC_point *VSC_Clone_Point(const struct VSC_point * const);
-
-void VSC_Destroy_Point(struct VSC_point **);
+/*---------------------------------------------------------------------
+ * Function pointers
+ */
 
 typedef void *VSC_new_f(void *priv, const struct VSC_point *const pt);
+	/*
+	 * priv is from VSC_State().
+	 *
+	 * The return value is installed in pt->priv
+	 */
+
+typedef void VSC_destroy_f(void *priv, const struct VSC_point *const pt);
+	/*
+	 * priv is from VSC_State().
+	 */
+
 typedef int VSC_iter_f(void *priv, const struct VSC_point *const pt);
-typedef int VSC_destroy_f(void *priv, const struct VSC_point *const pt);
+	/*
+	 * priv is the argument to VSC_Iter() and not from VSC_State().
+	 *
+	 * A non-zero return terminates the iteration
+	 */
 
-int VSC_Iter(struct vsc *, struct vsm *, VSC_new_f *, VSC_iter_f *, VSC_destroy_f *, void *priv);
+/*---------------------------------------------------------------------
+ * VSC level access functions
+ */
+
+struct vsc *VSC_New(void);
 	/*
-	 * Iterate over all statistics counters, calling "func" for
-	 * each counter not suppressed by any "-f" arguments.
+	 * Create a new VSC instance
+	 */
+
+void VSC_Destroy(struct vsc **);
+	/*
+	 * Destroy a VSC instance
 	 *
-	 * fantom points to a struct vsm_fantom. If non-NULL, it can be
-	 * used with VSM_StillValid to check the validity of the points
-	 * returned.
+	 * If a destroy function was installed with VSC_State()
+	 * it will be called for all remaining points
+	 */
+
+int VSC_Arg(struct vsc *, char arg, const char *opt);
+	/*
+	 * Handle standard stat-presenter arguments
+	 *	'f' - filter
 	 *
-	 * The returned points are valid for at most 60 seconds after
-	 * VSM_StillValid(,fantom) starts returning anything but
-	 * VSM_valid, or until the next call to VSC_Iter. Using the point
-	 * values after any of these events gives undefined behavior.
+	 * Return:
+	 *	-1 error, VSM_Error() returns diagnostic string
+	 *	 0 not handled
+	 *	 1 Handled.
+	 */
+
+void VSC_State(struct vsc *, VSC_new_f *, VSC_destroy_f *, void *);
+	/*
+	 * Install function pointers for create/destroy and their
+	 * priv pointer.  All arguments can be NULL.
+	 */
+
+int VSC_Iter(struct vsc *, struct vsm *, VSC_iter_f *, void *priv);
+	/*
+	 * Iterate over all statistics counters, calling a function for
+	 * each counter not suppressed by any "-f" arguments.
 	 *
-	 * Func is called with pt == NULL, whenever VSM allocations
-	 * change (child restart, allocations/deallocations)
+	 * To discover new/deleted points, call VSM_Status() first.
+	 *
+	 * The returned points are valid until the next call to VSC_Iter()
 	 *
 	 * Arguments:
 	 *	    vd: The vsm context
-	 *	fantom: Pointer to a fantom. Can be NULL.
 	 *	  func: The callback function
 	 *	  priv: Passed as argument to func
 	 *
 	 * Returns:
 	 *	!=0:	func returned non-zero
-	 *	-1:	No VSC's available
 	 *	0:	Done
 	 */
 
 const struct VSC_level_desc *VSC_ChangeLevel(const struct VSC_level_desc*, int);
+	/*
+	 * Change a level up or down.
+	 */
 
 #endif /* VAPI_VSC_H_INCLUDED */
diff --git a/lib/libvarnishapi/libvarnishapi.map b/lib/libvarnishapi/libvarnishapi.map
index b89c90c..aee341b 100644
--- a/lib/libvarnishapi/libvarnishapi.map
+++ b/lib/libvarnishapi/libvarnishapi.map
@@ -195,5 +195,5 @@ LIBVARNISHAPI_1.7 {
 	VSM_Dup;
 	VSC_New;
 	VSC_Destroy;
-	VSC_Iter2;
+	VSC_State;
 } LIBVARNISHAPI_1.0;
diff --git a/lib/libvarnishapi/vsc.c b/lib/libvarnishapi/vsc.c
index 6ccbc9d..417c834 100644
--- a/lib/libvarnishapi/vsc.c
+++ b/lib/libvarnishapi/vsc.c
@@ -69,7 +69,7 @@ struct vsc_seg {
 #define VSC_SEG_MAGIC		0x801177d4
 	VTAILQ_ENTRY(vsc_seg)	list;
 	struct vsm_fantom	fantom[1];
-	struct vjsn 		*vj;
+	struct vjsn		*vj;
 	unsigned		npoints;
 	struct vsc_pt		*points;
 };
@@ -81,6 +81,10 @@ struct vsc {
 	struct vsc_sf_head	sf_list_include;
 	struct vsc_sf_head	sf_list_exclude;
 	VTAILQ_HEAD(,vsc_seg)	segs;
+
+	VSC_new_f		*fnew;
+	VSC_destroy_f		*fdestroy;
+	void			*priv;
 };
 
 /*--------------------------------------------------------------------
@@ -101,34 +105,6 @@ static const size_t nlevels = sizeof(levels)/sizeof(*levels);
 
 /*--------------------------------------------------------------------*/
 
-struct VSC_point *
-VSC_Clone_Point(const struct VSC_point * const vp)
-{
-	struct VSC_point *pt;
-	char *p;
-
-	pt = calloc(sizeof *pt, 1);
-	AN(pt);
-	*pt = *vp;
-	p = strdup(pt->name); AN(p); pt->name = p;
-	p = strdup(pt->sdesc); AN(p); pt->sdesc = p;
-	p = strdup(pt->ldesc); AN(p); pt->ldesc = p;
-	return (pt);
-}
-
-void
-VSC_Destroy_Point(struct VSC_point **p)
-{
-	AN(p);
-	free(TRUST_ME((*p)->ldesc));
-	free(TRUST_ME((*p)->sdesc));
-	free(TRUST_ME((*p)->name));
-	free(*p);
-	*p = NULL;
-}
-
-/*--------------------------------------------------------------------*/
-
 struct vsc *
 VSC_New(void)
 {
@@ -215,6 +191,18 @@ VSC_Arg(struct vsc *vsc, char arg, const char *opt)
 
 /*--------------------------------------------------------------------
  */
+void
+VSC_State(struct vsc *vsc, VSC_new_f *fn, VSC_destroy_f *fd, void *priv)
+{
+
+	CHECK_OBJ_NOTNULL(vsc, VSC_MAGIC);
+	vsc->fnew = fn;
+	vsc->fdestroy = fd;
+	vsc->priv = priv;
+}
+
+/*--------------------------------------------------------------------
+ */
 
 static int
 vsc_filter(const struct vsc *vsc, const char *nm)
@@ -329,16 +317,22 @@ vsc_fill_point(const struct vsc *vsc, const struct vsm_fantom *fantom,
 }
 
 static void
-vsc_del_seg(struct vsm *vsm, struct vsc_seg *sp)
+vsc_del_seg(const struct vsc *vsc, struct vsm *vsm, struct vsc_seg *sp)
 {
 	unsigned u;
+	struct vsc_pt *pp;
 
+	CHECK_OBJ_NOTNULL(vsc, VSC_MAGIC);
 	AN(vsm);
 	CHECK_OBJ_NOTNULL(sp, VSC_SEG_MAGIC);
 	AZ(VSM_Unmap(vsm, sp->fantom));
 	vjsn_delete(&sp->vj);
-	for(u = 0; u < sp->npoints; u++)
-		vsc_clean_point(&sp->points[u]);
+	pp = sp->points;
+	for(u = 0; u < sp->npoints; u++, pp++) {
+		if (vsc->fdestroy != NULL)
+			vsc->fdestroy(vsc->priv, &pp->point);
+		vsc_clean_point(pp);
+	}
 	free(sp->points);
 	FREE_OBJ(sp);
 }
@@ -348,11 +342,11 @@ vsc_add_seg(const struct vsc *vsc, struct vsm *vsm, const struct vsm_fantom *fp)
 {
 	struct vsc_seg *sp;
 	uint64_t u;
-	unsigned j;
 	const char *p;
 	const char *e;
 	struct vjsn_val *vv, *vve;
 	struct vsb *vsb;
+	struct vsc_pt *pp;
 
 	CHECK_OBJ_NOTNULL(vsc, VSC_MAGIC);
 	AN(vsm);
@@ -380,37 +374,41 @@ vsc_add_seg(const struct vsc *vsc, struct vsm *vsm, const struct vsm_fantom *fp)
 	AN(sp->points);
 	vsb = VSB_new_auto();
 	AN(vsb);
-	j = 0;
 	vve = vjsn_child(sp->vj->value, "elem");
 	AN(vve);
-	VTAILQ_FOREACH(vv, &vve->children, list)
-		(void)vsc_fill_point(vsc, sp->fantom, vv, vsb, sp->points + j++);
+	pp = sp->points;
+	VTAILQ_FOREACH(vv, &vve->children, list) {
+		if (vsc_fill_point(vsc, sp->fantom, vv, vsb, pp) &&
+			vsc->fnew != NULL)
+			pp->point.priv = vsc->fnew(vsc->priv, &pp->point);
+		pp++;
+	}
 	VSB_destroy(&vsb);
 	AN(sp->vj);
 	return (sp);
 }
 
 static int
-vsc_iter_seg(const struct vsc_seg *sp, VSC_iter_f *fiter, void *priv)
+vsc_iter_seg(const struct vsc *vsc, const struct vsc_seg *sp,
+    VSC_iter_f *fiter, void *priv)
 {
 	unsigned u;
 	int i = 0;
+	struct vsc_pt *pp;
 
+	CHECK_OBJ_NOTNULL(vsc, VSC_MAGIC);
 	CHECK_OBJ_NOTNULL(sp, VSC_SEG_MAGIC);
 	AN(fiter);
-	for(u = 0; u < sp->npoints; u++) {
-		if (sp->points[u].name != NULL) {
-			i = fiter(priv, &sp->points[u].point);
-			if (i)
-				break;
-		}
+	pp = sp->points;
+	for(u = 0; u < sp->npoints && i == 0; u++, pp++) {
+		if (pp->name != NULL)
+			i = fiter(priv, &pp->point);
 	}
 	return (i);
 }
 
 int
-VSC_Iter(struct vsc *vsc, struct vsm *vsm,
-    VSC_new_f *fnew, VSC_iter_f *fiter, VSC_destroy_f *fdestroy, void *priv)
+VSC_Iter(struct vsc *vsc, struct vsm *vsm, VSC_iter_f *fiter, void *priv)
 {
 	struct vsm_fantom ifantom;
 	struct vsc_seg *sp, *sp2;
@@ -418,8 +416,6 @@ VSC_Iter(struct vsc *vsc, struct vsm *vsm,
 
 	CHECK_OBJ_NOTNULL(vsc, VSC_MAGIC);
 	AN(vsm);
-	(void)fnew;
-	(void)fdestroy;
 	sp = VTAILQ_FIRST(&vsc->segs);
 	VSM_FOREACH(&ifantom, vsm) {
 		if (strcmp(ifantom.class, VSC_CLASS))
@@ -430,20 +426,28 @@ VSC_Iter(struct vsc *vsc, struct vsm *vsm,
 			sp2 = sp;
 			sp = VTAILQ_NEXT(sp, list);
 			VTAILQ_REMOVE(&vsc->segs, sp2, list);
-			vsc_del_seg(vsm, sp2);
+			vsc_del_seg(vsc, vsm, sp2);
 		}
 		if (sp != NULL) {
-			i = vsc_iter_seg(sp, fiter, priv);
+			if (fiter != NULL)
+				i = vsc_iter_seg(vsc, sp, fiter, priv);
 			sp = VTAILQ_NEXT(sp, list);
 		} else {
 			sp = vsc_add_seg(vsc, vsm, &ifantom);
 			VTAILQ_INSERT_TAIL(&vsc->segs, sp, list);
-			i = vsc_iter_seg(sp, fiter, priv);
+			if (fiter != NULL)
+				i = vsc_iter_seg(vsc, sp, fiter, priv);
 			sp = NULL;
 		}
 		if (i)
 			break;
 	}
+	while (sp != NULL) {
+		sp2 = sp;
+		sp = VTAILQ_NEXT(sp, list);
+		VTAILQ_REMOVE(&vsc->segs, sp2, list);
+		vsc_del_seg(vsc, vsm, sp2);
+	}
 	return (i);
 }
 
diff --git a/lib/libvarnishapi/vsm.c b/lib/libvarnishapi/vsm.c
index 96c171b..50e1805 100644
--- a/lib/libvarnishapi/vsm.c
+++ b/lib/libvarnishapi/vsm.c
@@ -37,6 +37,7 @@
 #include <fcntl.h>
 #include <float.h>
 #include <math.h>
+#include <signal.h>
 #include <stdarg.h>
 #include <stdint.h>
 #include <stdio.h>
@@ -353,7 +354,7 @@ vsm_refresh_set2(struct vsm *vd, struct vsm_set *vs, struct vsb *vsb)
 	retval |= VSM_MGT_CHANGED;
 	vs->fd = openat(vs->dfd, "_.index", O_RDONLY);
 	if (vs->fd < 0)
-		return (retval|VSM_NUKE_ALL);
+		return (retval|VSM_MGT_RESTARTED);
 
 	AZ(fstat(vs->fd, &vs->fst));
 
@@ -376,17 +377,17 @@ vsm_refresh_set2(struct vsm *vd, struct vsm_set *vs, struct vsb *vsb)
 	 * XXX: be kill(pid,0)'ed for more rapid abandonment detection.
 	 */
 	i = sscanf(VSB_data(vsb), "# %ju %ju\n%n", &id1, &id2, &ac);
-	if (i != 2) {
-		retval |= VSM_MGT_RESTARTED;
-		return (retval|VSM_NUKE_ALL);
+	if (i != 2 || kill(id1, 0)) {
+		retval |= VSM_MGT_RESTARTED | VSM_MGT_CHANGED;
+		return (retval);
 	}
+	retval |= VSM_MGT_RUNNING;
 	if (id1 != vs->id1 || id2 != vs->id2) {
-		retval |= VSM_MGT_RESTARTED;
+		retval |= VSM_MGT_RESTARTED | VSM_MGT_CHANGED;
 		vs->id1 = id1;
 		vs->id2 = id2;
 	}
 	p = VSB_data(vsb) + ac;
-	retval |= VSM_MGT_RUNNING;
 
 	VTAILQ_FOREACH(vg, &vs->segs, list)
 		vg->markscan = 0;


More information about the varnish-commit mailing list