summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2020-11-11 21:29:54 -0800
committerGarrett D'Amore <garrett@damore.org>2020-11-11 23:51:13 -0800
commit66ff33813a8cd9d4cba96280bb613762fb0c2ce2 (patch)
tree4d9230b87715ebb1ff876894cd805ee4da42eccb /src
parent53f20bbc4a2bd0d333e0307640883a778de31e2b (diff)
downloadnng-66ff33813a8cd9d4cba96280bb613762fb0c2ce2.tar.gz
nng-66ff33813a8cd9d4cba96280bb613762fb0c2ce2.tar.bz2
nng-66ff33813a8cd9d4cba96280bb613762fb0c2ce2.zip
fixes #1323 stats framework is *way* to heavy
This should reduce the amount of copying, and the overall size used by pipes and other objects quite a bit. (On my system, the sizeof nni_pipe shrank by 400 bytes, for example.)
Diffstat (limited to 'src')
-rw-r--r--src/core/dialer.c224
-rw-r--r--src/core/listener.c214
-rw-r--r--src/core/pipe.c156
-rw-r--r--src/core/socket.c301
-rw-r--r--src/core/sockimpl.h107
-rw-r--r--src/core/stats.c363
-rw-r--r--src/core/stats.h73
-rw-r--r--src/protocol/pair1/pair.c141
-rw-r--r--src/protocol/pair1/pair1_poly.c121
-rw-r--r--src/transport/ipc/ipc.c26
-rw-r--r--src/transport/tcp/tcp.c33
-rw-r--r--src/transport/tls/tls.c29
12 files changed, 1107 insertions, 681 deletions
diff --git a/src/core/dialer.c b/src/core/dialer.c
index 80b93dc0..3efbcabd 100644
--- a/src/core/dialer.c
+++ b/src/core/dialer.c
@@ -23,8 +23,6 @@ static void dialer_timer_cb(void *);
static nni_id_map dialers;
static nni_mtx dialers_lk;
-#define BUMP_STAT(x) nni_stat_inc_atomic(x, 1)
-
int
nni_dialer_sys_init(void)
{
@@ -65,59 +63,129 @@ nni_dialer_destroy(nni_dialer *d)
NNI_FREE_STRUCT(d);
}
+#if NNG_ENABLE_STATS
static void
-dialer_stats_init(nni_dialer *d)
+dialer_stat_init(nni_dialer *d, nni_stat_item *item, const nni_stat_info *info)
{
- nni_dialer_stats *st = &d->d_stats;
- nni_stat_item * root = &st->s_root;
-
- nni_stat_init_scope(root, st->s_scope, "dialer statistics");
-
- nni_stat_init_id(&st->s_id, "id", "dialer id", d->d_id);
- nni_stat_add(root, &st->s_id);
-
- nni_stat_init_id(&st->s_sock, "socket", "socket for dialer",
- nni_sock_id(d->d_sock));
- nni_stat_add(root, &st->s_sock);
-
- nni_stat_init_string(
- &st->s_url, "url", "dialer url", d->d_url->u_rawurl);
- nni_stat_add(root, &st->s_url);
-
- nni_stat_init_atomic(&st->s_npipes, "npipes", "open pipes");
- nni_stat_add(root, &st->s_npipes);
-
- nni_stat_init_atomic(
- &st->s_connok, "connect", "connections established");
- nni_stat_add(root, &st->s_connok);
-
- nni_stat_init_atomic(&st->s_refused, "refused", "connections refused");
- nni_stat_add(root, &st->s_refused);
-
- nni_stat_init_atomic(&st->s_discon, "discon", "remote disconnects");
- nni_stat_add(root, &st->s_discon);
-
- nni_stat_init_atomic(&st->s_canceled, "canceled", "canceled");
- nni_stat_add(root, &st->s_canceled);
-
- nni_stat_init_atomic(&st->s_othererr, "othererr", "other errors");
- nni_stat_add(root, &st->s_othererr);
-
- nni_stat_init_atomic(&st->s_etimedout, "timedout", "timed out");
- nni_stat_add(root, &st->s_etimedout);
-
- nni_stat_init_atomic(&st->s_eproto, "protoerr", "protocol errors");
- nni_stat_add(root, &st->s_eproto);
-
- nni_stat_init_atomic(&st->s_eauth, "autherr", "auth errors");
- nni_stat_add(root, &st->s_eauth);
-
- nni_stat_init_atomic(&st->s_enomem, "nomem", "out of memory");
- nni_stat_add(root, &st->s_enomem);
+ nni_stat_init(item, info);
+ nni_stat_add(&d->st_root, item);
+}
- nni_stat_init_atomic(&st->s_reject, "reject", "pipes rejected");
- nni_stat_add(root, &st->s_reject);
+static void
+dialer_stats_init(nni_dialer *d)
+{
+ static const nni_stat_info root_info = {
+ .si_name = "dialer",
+ .si_desc = "dialer statistics",
+ .si_type = NNG_STAT_SCOPE,
+ };
+ static const nni_stat_info id_info = {
+ .si_name = "id",
+ .si_desc = "dialer id",
+ .si_type = NNG_STAT_ID,
+ };
+ static const nni_stat_info socket_info = {
+ .si_name = "socket",
+ .si_desc = "socket for dialer",
+ .si_type = NNG_STAT_ID,
+ };
+ static const nni_stat_info url_info = {
+ .si_name = "url",
+ .si_desc = "dialer url",
+ .si_type = NNG_STAT_STRING,
+ .si_alloc = true,
+ };
+ static const nni_stat_info pipes_info = {
+ .si_name = "pipes",
+ .si_desc = "open pipes",
+ .si_type = NNG_STAT_LEVEL,
+ .si_atomic = true,
+ };
+ static const nni_stat_info connect_info = {
+ .si_name = "connect",
+ .si_desc = "connections established",
+ .si_type = NNG_STAT_COUNTER,
+ .si_atomic = true,
+ };
+ static const nni_stat_info refused_info = {
+ .si_name = "refused",
+ .si_desc = "connections refused",
+ .si_type = NNG_STAT_COUNTER,
+ .si_atomic = true,
+ };
+ static const nni_stat_info disconnect_info = {
+ .si_name = "disconnect",
+ .si_desc = "remote disconnects",
+ .si_type = NNG_STAT_COUNTER,
+ .si_atomic = true,
+ };
+ static const nni_stat_info canceled_info = {
+ .si_name = "canceled",
+ .si_desc = "canceled connections",
+ .si_type = NNG_STAT_COUNTER,
+ .si_atomic = true,
+ };
+ static const nni_stat_info other_info = {
+ .si_name = "other",
+ .si_desc = "other errors",
+ .si_type = NNG_STAT_COUNTER,
+ .si_atomic = true,
+ };
+ static const nni_stat_info timeout_info = {
+ .si_name = "timeout",
+ .si_desc = "timeout errors",
+ .si_type = NNG_STAT_COUNTER,
+ .si_atomic = true,
+ };
+ static const nni_stat_info proto_info = {
+ .si_name = "proto",
+ .si_desc = "protocol errors",
+ .si_type = NNG_STAT_COUNTER,
+ .si_atomic = true,
+ };
+ static const nni_stat_info auth_info = {
+ .si_name = "auth",
+ .si_desc = "auth errors",
+ .si_type = NNG_STAT_COUNTER,
+ .si_atomic = true,
+ };
+ static const nni_stat_info oom_info = {
+ .si_name = "oom",
+ .si_desc = "allocation failures",
+ .si_type = NNG_STAT_COUNTER,
+ .si_atomic = true,
+ };
+ static const nni_stat_info reject_info = {
+ .si_name = "reject",
+ .si_desc = "rejected pipes",
+ .si_type = NNG_STAT_COUNTER,
+ .si_atomic = true,
+ };
+
+ nni_stat_init(&d->st_root, &root_info);
+
+ dialer_stat_init(d, &d->st_id, &id_info);
+ dialer_stat_init(d, &d->st_sock, &socket_info);
+ dialer_stat_init(d, &d->st_url, &url_info);
+ dialer_stat_init(d, &d->st_pipes, &pipes_info);
+ dialer_stat_init(d, &d->st_connect, &connect_info);
+ dialer_stat_init(d, &d->st_refused, &refused_info);
+ dialer_stat_init(d, &d->st_disconnect, &disconnect_info);
+ dialer_stat_init(d, &d->st_canceled, &canceled_info);
+ dialer_stat_init(d, &d->st_other, &other_info);
+ dialer_stat_init(d, &d->st_timeout, &timeout_info);
+ dialer_stat_init(d, &d->st_proto, &proto_info);
+ dialer_stat_init(d, &d->st_auth, &auth_info);
+ dialer_stat_init(d, &d->st_oom, &oom_info);
+ dialer_stat_init(d, &d->st_reject, &reject_info);
+
+ nni_stat_set_id(&d->st_root, d->d_id);
+ nni_stat_set_id(&d->st_id, d->d_id);
+ nni_stat_set_id(&d->st_sock, nni_sock_id(d->d_sock));
+ nni_stat_set_string(&d->st_url, d->d_url->u_rawurl);
+ nni_stat_register(&d->st_root);
}
+#endif // NNG_ENABLE_STATS
void
nni_dialer_bump_error(nni_dialer *d, int err)
@@ -126,34 +194,31 @@ nni_dialer_bump_error(nni_dialer *d, int err)
switch (err) {
case NNG_ECONNABORTED:
case NNG_ECONNRESET:
- BUMP_STAT(&d->d_stats.s_discon);
+ nni_stat_inc(&d->st_disconnect, 1);
break;
case NNG_ECONNREFUSED:
- BUMP_STAT(&d->d_stats.s_refused);
+ nni_stat_inc(&d->st_refused, 1);
break;
case NNG_ECANCELED:
- BUMP_STAT(&d->d_stats.s_canceled);
+ nni_stat_inc(&d->st_canceled, 1);
break;
case NNG_ETIMEDOUT:
- BUMP_STAT(&d->d_stats.s_etimedout);
+ nni_stat_inc(&d->st_timeout, 1);
break;
case NNG_EPROTO:
- BUMP_STAT(&d->d_stats.s_eproto);
+ nni_stat_inc(&d->st_proto, 1);
break;
case NNG_EPEERAUTH:
case NNG_ECRYPTO:
- BUMP_STAT(&d->d_stats.s_eauth);
+ nni_stat_inc(&d->st_auth, 1);
break;
case NNG_ENOMEM:
- BUMP_STAT(&d->d_stats.s_enomem);
+ nni_stat_inc(&d->st_oom, 1);
break;
default:
- BUMP_STAT(&d->d_stats.s_othererr);
+ nni_stat_inc(&d->st_other, 1);
break;
}
-#else
- NNI_ARG_UNUSED(d);
- NNI_ARG_UNUSED(err);
#endif
}
@@ -182,7 +247,7 @@ nni_dialer_create(nni_dialer **dp, nni_sock *s, const char *urlstr)
d->d_closed = false;
d->d_closing = false;
d->d_data = NULL;
- d->d_refcnt = 1;
+ d->d_ref = 1;
d->d_sock = s;
d->d_tran = tran;
nni_atomic_flag_reset(&d->d_started);
@@ -197,7 +262,6 @@ nni_dialer_create(nni_dialer **dp, nni_sock *s, const char *urlstr)
nni_mtx_init(&d->d_mtx);
- dialer_stats_init(d);
nni_aio_init(&d->d_con_aio, dialer_connect_cb, d);
nni_aio_init(&d->d_tmo_aio, dialer_timer_cb, d);
@@ -205,19 +269,22 @@ nni_dialer_create(nni_dialer **dp, nni_sock *s, const char *urlstr)
rv = nni_id_alloc(&dialers, &d->d_id, d);
nni_mtx_unlock(&dialers_lk);
+#ifdef NNG_ENABLE_STATS
+ dialer_stats_init(d);
+#endif
+
if ((rv != 0) || ((rv = d->d_ops.d_init(&d->d_data, url, d)) != 0) ||
((rv = nni_sock_add_dialer(s, d)) != 0)) {
nni_mtx_lock(&dialers_lk);
nni_id_remove(&dialers, d->d_id);
nni_mtx_unlock(&dialers_lk);
+#ifdef NNG_ENABLE_STATS
+ nni_stat_unregister(&d->st_root);
+#endif
nni_dialer_destroy(d);
return (rv);
}
- snprintf(d->d_stats.s_scope, sizeof(d->d_stats.s_scope), "dialer%u",
- d->d_id);
- nni_stat_set_value(&d->d_stats.s_id, d->d_id);
- nni_stat_register(&d->d_stats.s_root);
*dp = d;
return (0);
}
@@ -234,7 +301,7 @@ nni_dialer_find(nni_dialer **dp, uint32_t id)
nni_mtx_lock(&dialers_lk);
if ((d = nni_id_get(&dialers, id)) != NULL) {
- d->d_refcnt++;
+ d->d_ref++;
*dp = d;
}
nni_mtx_unlock(&dialers_lk);
@@ -249,7 +316,7 @@ nni_dialer_hold(nni_dialer *d)
if (d->d_closed) {
rv = NNG_ECLOSED;
} else {
- d->d_refcnt++;
+ d->d_ref++;
rv = 0;
}
nni_mtx_unlock(&dialers_lk);
@@ -260,8 +327,8 @@ void
nni_dialer_rele(nni_dialer *d)
{
nni_mtx_lock(&dialers_lk);
- d->d_refcnt--;
- if ((d->d_refcnt == 0) && (d->d_closed)) {
+ d->d_ref--;
+ if ((d->d_ref == 0) && (d->d_closed)) {
nni_reap(&d->d_reap, (nni_cb) nni_dialer_reap, d);
}
nni_mtx_unlock(&dialers_lk);
@@ -326,7 +393,9 @@ dialer_connect_cb(void *arg)
switch ((rv = nni_aio_result(aio))) {
case 0:
- BUMP_STAT(&d->d_stats.s_connok);
+#ifdef NNG_ENABLE_STATS
+ nni_stat_inc(&d->st_connect, 1);
+#endif
nni_dialer_add_pipe(d, nni_aio_get_output(aio, 0));
break;
case NNG_ECLOSED: // No further action.
@@ -491,7 +560,12 @@ nni_dialer_getopt(
}
void
-nni_dialer_add_stat(nni_dialer *d, nni_stat_item *stat)
+nni_dialer_add_stat(nni_dialer *d, nni_stat_item *item)
{
- nni_stat_add(&d->d_stats.s_root, stat);
+#ifdef NNG_ENABLE_STATS
+ nni_stat_add(&d->st_root, item);
+#else
+ NNI_ARG_UNUSED(d);
+ NNI_ARG_UNUSED(item);
+#endif
}
diff --git a/src/core/listener.c b/src/core/listener.c
index 56850649..83882389 100644
--- a/src/core/listener.c
+++ b/src/core/listener.c
@@ -24,8 +24,6 @@ static void listener_timer_cb(void *);
static nni_id_map listeners;
static nni_mtx listeners_lk;
-#define BUMP_STAT(x) nni_stat_inc_atomic(x, 1)
-
int
nni_listener_sys_init(void)
{
@@ -65,56 +63,122 @@ nni_listener_destroy(nni_listener *l)
NNI_FREE_STRUCT(l);
}
+#ifdef NNG_ENABLE_STATS
static void
-listener_stats_init(nni_listener *l)
+listener_stat_init(
+ nni_listener *l, nni_stat_item *item, const nni_stat_info *info)
{
- nni_listener_stats *st = &l->l_stats;
- nni_stat_item * root = &st->s_root;
-
- nni_stat_init_scope(root, st->s_scope, "listener statistics");
-
- // NB: This will be updated later.
- nni_stat_init_id(&st->s_id, "id", "listener id", l->l_id);
- nni_stat_add(root, &st->s_id);
-
- nni_stat_init_id(&st->s_sock, "socket", "socket for listener",
- nni_sock_id(l->l_sock));
- nni_stat_add(root, &st->s_sock);
-
- nni_stat_init_string(
- &st->s_url, "url", "listener url", l->l_url->u_rawurl);
- nni_stat_add(root, &st->s_url);
-
- nni_stat_init_atomic(&st->s_npipes, "npipes", "open pipes");
- nni_stat_add(root, &st->s_npipes);
-
- nni_stat_init_atomic(&st->s_accept, "accept", "connections accepted");
- nni_stat_add(root, &st->s_accept);
-
- nni_stat_init_atomic(&st->s_discon, "discon", "remote disconnects");
- nni_stat_add(root, &st->s_discon);
-
- nni_stat_init_atomic(&st->s_canceled, "canceled", "canceled");
- nni_stat_add(root, &st->s_canceled);
-
- nni_stat_init_atomic(&st->s_othererr, "othererr", "other errors");
- nni_stat_add(root, &st->s_othererr);
-
- nni_stat_init_atomic(&st->s_etimedout, "timedout", "timed out");
- nni_stat_add(root, &st->s_etimedout);
-
- nni_stat_init_atomic(&st->s_eproto, "protoerr", "protocol errors");
- nni_stat_add(root, &st->s_eproto);
-
- nni_stat_init_atomic(&st->s_eauth, "autherr", "auth errors");
- nni_stat_add(root, &st->s_eauth);
-
- nni_stat_init_atomic(&st->s_enomem, "nomem", "out of memory");
- nni_stat_add(root, &st->s_enomem);
+ nni_stat_init(item, info);
+ nni_stat_add(&l->st_root, item);
+}
- nni_stat_init_atomic(&st->s_reject, "reject", "pipes rejected");
- nni_stat_add(root, &st->s_reject);
+static void
+listener_stats_init(nni_listener *l)
+{
+ static const nni_stat_info root_info = {
+ .si_name = "listener",
+ .si_desc = "listener statistics",
+ .si_type = NNG_STAT_SCOPE,
+ };
+ static const nni_stat_info id_info = {
+ .si_name = "id",
+ .si_desc = "listener id",
+ .si_type = NNG_STAT_ID,
+ };
+ static const nni_stat_info sock_info = {
+ .si_name = "socket",
+ .si_desc = "socket id",
+ .si_type = NNG_STAT_ID,
+ };
+ static const nni_stat_info url_info = {
+ .si_name = "url",
+ .si_desc = "listener url",
+ .si_type = NNG_STAT_STRING,
+ .si_alloc = true,
+ };
+ static const nni_stat_info pipes_info = {
+ .si_name = "pipes",
+ .si_desc = "open pipes",
+ .si_type = NNG_STAT_COUNTER,
+ .si_atomic = true,
+ };
+ static const nni_stat_info accept_info = {
+ .si_name = "accept",
+ .si_desc = "connections accepted",
+ .si_type = NNG_STAT_COUNTER,
+ .si_atomic = true,
+ };
+ static const nni_stat_info disconnect_info = {
+ .si_name = "disconnect",
+ .si_desc = "remote disconnects",
+ .si_type = NNG_STAT_COUNTER,
+ .si_atomic = true,
+ };
+ static const nni_stat_info canceled_info = {
+ .si_name = "canceled",
+ .si_desc = "canceled connections",
+ .si_type = NNG_STAT_COUNTER,
+ .si_atomic = true,
+ };
+ static const nni_stat_info other_info = {
+ .si_name = "other",
+ .si_desc = "other errors",
+ .si_type = NNG_STAT_COUNTER,
+ .si_atomic = true,
+ };
+ static const nni_stat_info timeout_info = {
+ .si_name = "timeout",
+ .si_desc = "timeout errors",
+ .si_type = NNG_STAT_COUNTER,
+ .si_atomic = true,
+ };
+ static const nni_stat_info proto_info = {
+ .si_name = "proto",
+ .si_desc = "protocol errors",
+ .si_type = NNG_STAT_COUNTER,
+ .si_atomic = true,
+ };
+ static const nni_stat_info auth_info = {
+ .si_name = "auth",
+ .si_desc = "auth errors",
+ .si_type = NNG_STAT_COUNTER,
+ .si_atomic = true,
+ };
+ static const nni_stat_info oom_info = {
+ .si_name = "oom",
+ .si_desc = "allocation failures",
+ .si_type = NNG_STAT_COUNTER,
+ .si_atomic = true,
+ };
+ static const nni_stat_info reject_info = {
+ .si_name = "reject",
+ .si_desc = "rejected pipes",
+ .si_type = NNG_STAT_COUNTER,
+ .si_atomic = true,
+ };
+
+ nni_stat_init(&l->st_root, &root_info);
+
+ listener_stat_init(l, &l->st_id, &id_info);
+ listener_stat_init(l, &l->st_sock, &sock_info);
+ listener_stat_init(l, &l->st_url, &url_info);
+ listener_stat_init(l, &l->st_pipes, &pipes_info);
+ listener_stat_init(l, &l->st_accept, &accept_info);
+ listener_stat_init(l, &l->st_disconnect, &disconnect_info);
+ listener_stat_init(l, &l->st_canceled, &canceled_info);
+ listener_stat_init(l, &l->st_other, &other_info);
+ listener_stat_init(l, &l->st_timeout, &timeout_info);
+ listener_stat_init(l, &l->st_proto, &proto_info);
+ listener_stat_init(l, &l->st_auth, &auth_info);
+ listener_stat_init(l, &l->st_oom, &oom_info);
+ listener_stat_init(l, &l->st_reject, &reject_info);
+
+ nni_stat_set_id(&l->st_root, l->l_id);
+ nni_stat_set_id(&l->st_id, l->l_id);
+ nni_stat_set_string(&l->st_url, l->l_url->u_rawurl);
+ nni_stat_register(&l->st_root);
}
+#endif // NNG_ENABLE_STATS
void
nni_listener_bump_error(nni_listener *l, int err)
@@ -123,31 +187,28 @@ nni_listener_bump_error(nni_listener *l, int err)
switch (err) {
case NNG_ECONNABORTED:
case NNG_ECONNRESET:
- BUMP_STAT(&l->l_stats.s_discon);
+ nni_stat_inc(&l->st_disconnect, 1);
break;
case NNG_ECANCELED:
- BUMP_STAT(&l->l_stats.s_canceled);
+ nni_stat_inc(&l->st_canceled, 1);
break;
case NNG_ETIMEDOUT:
- BUMP_STAT(&l->l_stats.s_etimedout);
+ nni_stat_inc(&l->st_timeout, 1);
break;
case NNG_EPROTO:
- BUMP_STAT(&l->l_stats.s_eproto);
+ nni_stat_inc(&l->st_proto, 1);
break;
case NNG_EPEERAUTH:
case NNG_ECRYPTO:
- BUMP_STAT(&l->l_stats.s_eauth);
+ nni_stat_inc(&l->st_auth, 1);
break;
case NNG_ENOMEM:
- BUMP_STAT(&l->l_stats.s_enomem);
+ nni_stat_inc(&l->st_oom, 1);
break;
default:
- BUMP_STAT(&l->l_stats.s_othererr);
+ nni_stat_inc(&l->st_other, 1);
break;
}
-#else
- NNI_ARG_UNUSED(l);
- NNI_ARG_UNUSED(err);
#endif
}
@@ -176,7 +237,7 @@ nni_listener_create(nni_listener **lp, nni_sock *s, const char *url_str)
l->l_closed = false;
l->l_closing = false;
l->l_data = NULL;
- l->l_refcnt = 1;
+ l->l_ref = 1;
l->l_sock = s;
l->l_tran = tran;
nni_atomic_flag_reset(&l->l_started);
@@ -188,7 +249,6 @@ nni_listener_create(nni_listener **lp, nni_sock *s, const char *url_str)
NNI_LIST_NODE_INIT(&l->l_node);
NNI_LIST_INIT(&l->l_pipes, nni_pipe, p_ep_node);
- listener_stats_init(l);
nni_aio_init(&l->l_acc_aio, listener_accept_cb, l);
nni_aio_init(&l->l_tmo_aio, listener_timer_cb, l);
@@ -197,21 +257,22 @@ nni_listener_create(nni_listener **lp, nni_sock *s, const char *url_str)
rv = nni_id_alloc(&listeners, &l->l_id, l);
nni_mtx_unlock(&listeners_lk);
+#ifdef NNG_ENABLE_STATS
+ listener_stats_init(l);
+#endif
+
if ((rv != 0) || ((rv = l->l_ops.l_init(&l->l_data, url, l)) != 0) ||
((rv = nni_sock_add_listener(s, l)) != 0)) {
nni_mtx_lock(&listeners_lk);
nni_id_remove(&listeners, l->l_id);
nni_mtx_unlock(&listeners_lk);
+#ifdef NNG_ENABLE_STATS
+ nni_stat_unregister(&l->st_root);
+#endif
nni_listener_destroy(l);
return (rv);
}
- // Update a few stat bits, and register them.
- snprintf(l->l_stats.s_scope, sizeof(l->l_stats.s_scope), "listener%u",
- l->l_id);
- nni_stat_set_value(&l->l_stats.s_id, l->l_id);
- nni_stat_register(&l->l_stats.s_root);
-
*lp = l;
return (0);
}
@@ -228,7 +289,7 @@ nni_listener_find(nni_listener **lp, uint32_t id)
nni_mtx_lock(&listeners_lk);
if ((l = nni_id_get(&listeners, id)) != NULL) {
- l->l_refcnt++;
+ l->l_ref++;
*lp = l;
}
nni_mtx_unlock(&listeners_lk);
@@ -243,7 +304,7 @@ nni_listener_hold(nni_listener *l)
if (l->l_closed) {
rv = NNG_ECLOSED;
} else {
- l->l_refcnt++;
+ l->l_ref++;
rv = 0;
}
nni_mtx_unlock(&listeners_lk);
@@ -254,8 +315,8 @@ void
nni_listener_rele(nni_listener *l)
{
nni_mtx_lock(&listeners_lk);
- l->l_refcnt--;
- if ((l->l_refcnt == 0) && (l->l_closed)) {
+ l->l_ref--;
+ if ((l->l_ref == 0) && (l->l_closed)) {
nni_reap(&l->l_reap, (nni_cb) nni_listener_reap, l);
}
nni_mtx_unlock(&listeners_lk);
@@ -315,7 +376,9 @@ listener_accept_cb(void *arg)
switch ((rv = nni_aio_result(aio))) {
case 0:
- BUMP_STAT(&l->l_stats.s_accept);
+#ifdef NNG_ENABLE_STATS
+ nni_stat_inc(&l->st_accept, 1);
+#endif
nni_listener_add_pipe(l, nni_aio_get_output(aio, 0));
listener_accept_start(l);
break;
@@ -441,7 +504,12 @@ nni_listener_getopt(
}
void
-nni_listener_add_stat(nni_listener *l, nni_stat_item *stat)
+nni_listener_add_stat(nni_listener *l, nni_stat_item *item)
{
- nni_stat_add(&l->l_stats.s_root, stat);
+#if NNG_ENABLE_STATS
+ nni_stat_add(&l->st_root, item);
+#else
+ NNI_ARG_UNUSED(l);
+ NNI_ARG_UNUSED(item);
+#endif
}
diff --git a/src/core/pipe.c b/src/core/pipe.c
index b93d9f64..8ba35b2b 100644
--- a/src/core/pipe.c
+++ b/src/core/pipe.c
@@ -58,7 +58,7 @@ pipe_destroy(nni_pipe *p)
nni_id_remove(&pipes, p->p_id);
}
// This wait guarantees that all callers are done with us.
- while (p->p_refcnt != 0) {
+ while (p->p_ref != 0) {
nni_cv_wait(&p->p_cv);
}
nni_mtx_unlock(&pipes_lk);
@@ -70,7 +70,9 @@ pipe_destroy(nni_pipe *p)
p->p_tran_ops.p_stop(p->p_tran_data);
}
- nni_stat_unregister(&p->p_stats.s_root);
+#ifdef NNG_ENABLE_STATS
+ nni_stat_unregister(&p->st_root);
+#endif
nni_pipe_remove(p);
if (p->p_proto_data != NULL) {
@@ -93,9 +95,9 @@ nni_pipe_find(nni_pipe **pp, uint32_t id)
// access to the pipe in order to obtain properties (which may
// be retried during the post-close notification callback) or to
// close the pipe.
- nni_mtx_lock(&pipes_lk);
+ nni_mtx_lock(&pipes_lk);
if ((p = nni_id_get(&pipes, id)) != NULL) {
- p->p_refcnt++;
+ p->p_ref++;
*pp = p;
}
nni_mtx_unlock(&pipes_lk);
@@ -106,8 +108,8 @@ void
nni_pipe_rele(nni_pipe *p)
{
nni_mtx_lock(&pipes_lk);
- p->p_refcnt--;
- if (p->p_refcnt == 0) {
+ p->p_ref--;
+ if (p->p_ref == 0) {
nni_cv_wake(&p->p_cv);
}
nni_mtx_unlock(&pipes_lk);
@@ -165,6 +167,75 @@ nni_pipe_peer(nni_pipe *p)
return (p->p_tran_ops.p_peer(p->p_tran_data));
}
+#ifdef NNG_ENABLE_STATS
+static void
+pipe_stat_init(nni_pipe *p, nni_stat_item *item, const nni_stat_info *info)
+{
+ nni_stat_init(item, info);
+ nni_stat_add(&p->st_root, item);
+}
+
+static void
+pipe_stats_init(nni_pipe *p)
+{
+ static const nni_stat_info root_info = {
+ .si_name = "pipe",
+ .si_desc = "pipe statistics",
+ .si_type = NNG_STAT_SCOPE,
+ };
+ static const nni_stat_info id_info = {
+ .si_name = "id",
+ .si_desc = "pipe id",
+ .si_type = NNG_STAT_ID,
+ };
+ static const nni_stat_info socket_info = {
+ .si_name = "socket",
+ .si_desc = "socket for pipe",
+ .si_type = NNG_STAT_ID,
+ };
+ static const nni_stat_info rx_msgs_info = {
+ .si_name = "rx_msgs",
+ .si_desc = "messages received",
+ .si_type = NNG_STAT_COUNTER,
+ .si_unit = NNG_UNIT_MESSAGES,
+ .si_atomic = true,
+ };
+ static const nni_stat_info tx_msgs_info = {
+ .si_name = "tx_msgs",
+ .si_desc = "messages sent",
+ .si_type = NNG_STAT_COUNTER,
+ .si_unit = NNG_UNIT_MESSAGES,
+ .si_atomic = true,
+ };
+ static const nni_stat_info rx_bytes_info = {
+ .si_name = "rx_bytes",
+ .si_desc = "bytes received",
+ .si_type = NNG_STAT_COUNTER,
+ .si_unit = NNG_UNIT_BYTES,
+ .si_atomic = true,
+ };
+ static const nni_stat_info tx_bytes_info = {
+ .si_name = "tx_bytes",
+ .si_desc = "bytes sent",
+ .si_type = NNG_STAT_COUNTER,
+ .si_unit = NNG_UNIT_BYTES,
+ .si_atomic = true,
+ };
+
+ nni_stat_init(&p->st_root, &root_info);
+ pipe_stat_init(p, &p->st_id, &id_info);
+ pipe_stat_init(p, &p->st_sock_id, &socket_info);
+ pipe_stat_init(p, &p->st_rx_msgs, &rx_msgs_info);
+ pipe_stat_init(p, &p->st_tx_msgs, &tx_msgs_info);
+ pipe_stat_init(p, &p->st_rx_bytes, &rx_bytes_info);
+ pipe_stat_init(p, &p->st_tx_bytes, &tx_bytes_info);
+
+ nni_stat_set_id(&p->st_root, p->p_id);
+ nni_stat_set_id(&p->st_id, p->p_id);
+ nni_stat_set_id(&p->st_sock_id, nni_sock_id(p->p_sock));
+}
+#endif // NNG_ENABLE_STATS
+
static int
pipe_create(nni_pipe **pp, nni_sock *sock, nni_tran *tran, void *tdata)
{
@@ -172,7 +243,6 @@ pipe_create(nni_pipe **pp, nni_sock *sock, nni_tran *tran, void *tdata)
int rv;
void * sdata = nni_sock_proto_data(sock);
nni_proto_pipe_ops *pops = nni_sock_proto_pipe_ops(sock);
- nni_pipe_stats * st;
size_t sz;
sz = NNI_ALIGN_UP(sizeof(*p)) + pops->pipe_size;
@@ -191,8 +261,7 @@ pipe_create(nni_pipe **pp, nni_sock *sock, nni_tran *tran, void *tdata)
p->p_sock = sock;
p->p_closed = false;
p->p_cbs = false;
- p->p_refcnt = 0;
- st = &p->p_stats;
+ p->p_ref = 0;
nni_atomic_flag_reset(&p->p_stop);
NNI_LIST_NODE_INIT(&p->p_sock_node);
@@ -203,32 +272,13 @@ pipe_create(nni_pipe **pp, nni_sock *sock, nni_tran *tran, void *tdata)
nni_mtx_lock(&pipes_lk);
if ((rv = nni_id_alloc(&pipes, &p->p_id, p)) == 0) {
- p->p_refcnt = 1;
+ p->p_ref = 1;
}
nni_mtx_unlock(&pipes_lk);
- snprintf(st->s_scope, sizeof(st->s_scope), "pipe%u", p->p_id);
-
- nni_stat_init_scope(&st->s_root, st->s_scope, "pipe statistics");
-
- nni_stat_init_id(&st->s_id, "id", "pipe id", p->p_id);
- nni_stat_add(&st->s_root, &st->s_id);
-
- nni_stat_init_id(&st->s_sock_id, "socket", "socket for pipe",
- nni_sock_id(p->p_sock));
- nni_stat_add(&st->s_root, &st->s_sock_id);
- nni_stat_init_atomic(&st->s_rxmsgs, "rxmsgs", "messages received");
- nni_stat_set_unit(&st->s_rxmsgs, NNG_UNIT_MESSAGES);
- nni_stat_add(&st->s_root, &st->s_rxmsgs);
- nni_stat_init_atomic(&st->s_txmsgs, "txmsgs", "messages sent");
- nni_stat_set_unit(&st->s_txmsgs, NNG_UNIT_MESSAGES);
- nni_stat_add(&st->s_root, &st->s_txmsgs);
- nni_stat_init_atomic(&st->s_rxbytes, "rxbytes", "bytes received");
- nni_stat_set_unit(&st->s_rxbytes, NNG_UNIT_BYTES);
- nni_stat_add(&st->s_root, &st->s_rxbytes);
- nni_stat_init_atomic(&st->s_txbytes, "txbytes", "bytes sent");
- nni_stat_set_unit(&st->s_txbytes, NNG_UNIT_BYTES);
- nni_stat_add(&st->s_root, &st->s_txbytes);
+#ifdef NNG_ENABLE_STATS
+ pipe_stats_init(p);
+#endif
if ((rv != 0) || ((rv = p->p_tran_ops.p_init(tdata, p)) != 0) ||
((rv = pops->pipe_init(p->p_proto_data, p, sdata)) != 0)) {
@@ -247,18 +297,20 @@ nni_pipe_create_dialer(nni_pipe **pp, nni_dialer *d, void *tdata)
int rv;
nni_tran * tran = d->d_tran;
nni_pipe * p;
- nni_stat_item *st;
-#ifdef NNG_ENABLE_STATS
- uint64_t id = nni_dialer_id(d);
-#endif
if ((rv = pipe_create(&p, d->d_sock, tran, tdata)) != 0) {
return (rv);
}
- st = &p->p_stats.s_ep_id;
p->p_dialer = d;
- nni_stat_init_id(st, "dialer", "dialer for pipe", id);
- nni_pipe_add_stat(p, st);
+#ifdef NNG_ENABLE_STATS
+ static const nni_stat_info dialer_info = {
+ .si_name = "dialer",
+ .si_desc = "dialer for pipe",
+ .si_type = NNG_STAT_ID,
+ };
+ pipe_stat_init(p, &p->st_ep_id, &dialer_info);
+ nni_stat_set_id(&p->st_ep_id, nni_dialer_id(d));
+#endif
*pp = p;
return (0);
}
@@ -269,18 +321,20 @@ nni_pipe_create_listener(nni_pipe **pp, nni_listener *l, void *tdata)
int rv;
nni_tran * tran = l->l_tran;
nni_pipe * p;
- nni_stat_item *st;
-#ifdef NNG_ENABLE_STATS
- uint64_t id = nni_listener_id(l);
-#endif
if ((rv = pipe_create(&p, l->l_sock, tran, tdata)) != 0) {
return (rv);
}
- st = &p->p_stats.s_ep_id;
p->p_listener = l;
- nni_stat_init_id(st, "listener", "listener for pipe", id);
- nni_pipe_add_stat(p, st);
+#if NNG_ENABLE_STATS
+ static const nni_stat_info listener_info = {
+ .si_name = "listener",
+ .si_desc = "listener for pipe",
+ .si_type = NNG_STAT_ID,
+ };
+ pipe_stat_init(p, &p->st_ep_id, &listener_info);
+ nni_stat_set_id(&p->st_ep_id, nni_listener_id(l));
+#endif
*pp = p;
return (0);
}
@@ -334,15 +388,15 @@ nni_pipe_dialer_id(nni_pipe *p)
void
nni_pipe_add_stat(nni_pipe *p, nni_stat_item *item)
{
- nni_stat_add(&p->p_stats.s_root, item);
+ nni_stat_add(&p->st_root, item);
}
void
nni_pipe_bump_rx(nni_pipe *p, size_t nbytes)
{
#ifdef NNG_ENABLE_STATS
- nni_stat_inc_atomic(&p->p_stats.s_rxbytes, nbytes);
- nni_stat_inc_atomic(&p->p_stats.s_rxmsgs, 1);
+ nni_stat_inc(&p->st_rx_bytes, nbytes);
+ nni_stat_inc(&p->st_rx_msgs, 1);
#else
NNI_ARG_UNUSED(p);
NNI_ARG_UNUSED(nbytes);
@@ -353,8 +407,8 @@ void
nni_pipe_bump_tx(nni_pipe *p, size_t nbytes)
{
#ifdef NNG_ENABLE_STATS
- nni_stat_inc_atomic(&p->p_stats.s_txbytes, nbytes);
- nni_stat_inc_atomic(&p->p_stats.s_txmsgs, 1);
+ nni_stat_inc(&p->st_tx_bytes, nbytes);
+ nni_stat_inc(&p->st_tx_msgs, 1);
#else
NNI_ARG_UNUSED(p);
NNI_ARG_UNUSED(nbytes);
diff --git a/src/core/socket.c b/src/core/socket.c
index 66130d4a..11b1371e 100644
--- a/src/core/socket.c
+++ b/src/core/socket.c
@@ -29,7 +29,7 @@ struct nni_ctx {
void * c_data;
size_t c_size;
bool c_closed;
- unsigned c_refcnt; // protected by global lock
+ unsigned c_ref; // protected by global lock
uint32_t c_id;
nng_duration c_sndtimeo;
nng_duration c_rcvtimeo;
@@ -48,21 +48,6 @@ typedef struct nni_sock_pipe_cb {
void * cb_arg;
} nni_sock_pipe_cb;
-typedef struct sock_stats {
- nni_stat_item s_root; // socket scope
- nni_stat_item s_id; // socket id
- nni_stat_item s_name; // socket name
- nni_stat_item s_protocol; // socket protocol
- nni_stat_item s_ndialers; // number of dialers
- nni_stat_item s_nlisteners; // number of listeners
- nni_stat_item s_npipes; // number of pipes
- nni_stat_item s_rxbytes; // number of bytes received
- nni_stat_item s_txbytes; // number of bytes received
- nni_stat_item s_rxmsgs; // number of msgs received
- nni_stat_item s_txmsgs; // number of msgs sent
- nni_stat_item s_reject; // pipes rejected
-} sock_stats;
-
struct nni_socket {
nni_list_node s_node;
nni_mtx s_mx;
@@ -71,8 +56,8 @@ struct nni_socket {
uint32_t s_id;
uint32_t s_flags;
- unsigned s_refcnt; // protected by global lock
- void * s_data; // Protocol private
+ unsigned s_ref; // protected by global lock
+ void * s_data; // Protocol private
size_t s_size;
nni_msgq *s_uwq; // Upper write queue
@@ -93,7 +78,6 @@ struct nni_socket {
size_t s_rcvmaxsz; // max receive size
nni_list s_options; // opts not handled by sock/proto
char s_name[64]; // socket name (legacy compat)
- char s_scope[24]; // socket scope ("socket%u", 32 bits max)
nni_list s_listeners; // active listeners
nni_list s_dialers; // active dialers
@@ -107,7 +91,20 @@ struct nni_socket {
nni_mtx s_pipe_cbs_mtx;
nni_sock_pipe_cb s_pipe_cbs[NNG_PIPE_EV_NUM];
- sock_stats s_stats;
+#ifdef NNG_ENABLE_STATS
+ nni_stat_item st_root; // socket scope
+ nni_stat_item st_id; // socket id
+ nni_stat_item st_name; // socket name
+ nni_stat_item st_protocol; // socket protocol
+ nni_stat_item st_dialers; // number of dialers
+ nni_stat_item st_listeners; // number of listeners
+ nni_stat_item st_pipes; // number of pipes
+ nni_stat_item st_rx_bytes; // number of bytes received
+ nni_stat_item st_tx_bytes; // number of bytes received
+ nni_stat_item st_rx_msgs; // number of msgs received
+ nni_stat_item st_tx_msgs; // number of msgs sent
+ nni_stat_item st_rejects; // pipes rejected
+#endif
};
static void nni_ctx_destroy(nni_ctx *);
@@ -379,7 +376,7 @@ nni_sock_find(nni_sock **sockp, uint32_t id)
if (s->s_closed) {
rv = NNG_ECLOSED;
} else {
- s->s_refcnt++;
+ s->s_ref++;
*sockp = s;
}
} else {
@@ -394,88 +391,129 @@ void
nni_sock_rele(nni_sock *s)
{
nni_mtx_lock(&sock_lk);
- s->s_refcnt--;
- if (s->s_closed && (s->s_refcnt < 2)) {
+ s->s_ref--;
+ if (s->s_closed && (s->s_ref < 2)) {
nni_cv_wake(&s->s_close_cv);
}
nni_mtx_unlock(&sock_lk);
}
+#ifdef NNG_ENABLE_STATS
static void
-sock_stats_fini(nni_sock *s)
+sock_stat_init(nni_sock *s, nni_stat_item *item, const nni_stat_info *info)
{
-#ifdef NNG_ENABLE_STATS
- sock_stats *st = &s->s_stats;
- nni_stat_unregister(&st->s_root);
-#else
- NNI_ARG_UNUSED(s);
-#endif
+ nni_stat_init(item, info);
+ nni_stat_add(&s->st_root, item);
}
static void
sock_stats_init(nni_sock *s)
{
-#ifdef NNG_ENABLE_STATS
- sock_stats * st = &s->s_stats;
- nni_stat_item *root = &s->s_stats.s_root;
+ static const nni_stat_info root_info = {
+ .si_name = "socket",
+ .si_desc = "socket statistics",
+ .si_type = NNG_STAT_SCOPE,
+ };
+ static const nni_stat_info id_info = {
+ .si_name = "id",
+ .si_desc = "socket identifier",
+ .si_type = NNG_STAT_ID,
+ };
+ static const nni_stat_info name_info = {
+ .si_name = "name",
+ .si_desc = "socket name",
+ .si_type = NNG_STAT_STRING,
+ .si_alloc = true,
+ };
+ static const nni_stat_info protocol_info = {
+ .si_name = "protocol",
+ .si_desc = "socket protocol",
+ .si_type = NNG_STAT_STRING,
+ };
+ static const nni_stat_info dialers_info = {
+ .si_name = "dialers",
+ .si_desc = "open dialers",
+ .si_type = NNG_STAT_LEVEL,
+ .si_atomic = true,
+ };
+ static const nni_stat_info listeners_info = {
+ .si_name = "listeners",
+ .si_desc = "open listeners",
+ .si_type = NNG_STAT_LEVEL,
+ .si_atomic = true,
+ };
+ static const nni_stat_info pipes_info = {
+ .si_name = "pipes",
+ .si_desc = "open pipes",
+ .si_type = NNG_STAT_LEVEL,
+ .si_atomic = true,
+ };
+ static const nni_stat_info reject_info = {
+ .si_name = "reject",
+ .si_desc = "rejected pipes",
+ .si_type = NNG_STAT_COUNTER,
+ .si_atomic = true,
+ };
+ static const nni_stat_info tx_msgs_info = {
+ .si_name = "tx_msgs",
+ .si_desc = "sent messages",
+ .si_type = NNG_STAT_COUNTER,
+ .si_unit = NNG_UNIT_MESSAGES,
+ .si_atomic = true,
+ };
+ static const nni_stat_info rx_msgs_info = {
+ .si_name = "rx_msgs",
+ .si_desc = "received messages",
+ .si_type = NNG_STAT_COUNTER,
+ .si_unit = NNG_UNIT_MESSAGES,
+ .si_atomic = true,
+ };
+ static const nni_stat_info tx_bytes_info = {
+ .si_name = "tx_bytes",
+ .si_desc = "sent bytes",
+ .si_type = NNG_STAT_COUNTER,
+ .si_unit = NNG_UNIT_BYTES,
+ .si_atomic = true,
+ };
+ static const nni_stat_info rx_bytes_info = {
+ .si_name = "rx_bytes",
+ .si_desc = "received messages",
+ .si_type = NNG_STAT_COUNTER,
+ .si_unit = NNG_UNIT_BYTES,
+ .si_atomic = true,
+ };
// To make collection cheap and atomic for the socket,
// we just use a single lock for the entire chain.
- nni_stat_init_scope(root, s->s_scope, "socket statistics");
-
- nni_stat_init_id(&st->s_id, "id", "socket id", s->s_id);
- nni_stat_add(root, &st->s_id);
-
- nni_stat_init_string(&st->s_name, "name", "socket name", s->s_name);
- nni_stat_set_lock(&st->s_name, &s->s_mx);
- nni_stat_add(root, &st->s_name);
-
- nni_stat_init_string(&st->s_protocol, "protocol", "socket protocol",
- nni_sock_proto_name(s));
- nni_stat_add(root, &st->s_protocol);
-
- nni_stat_init_atomic(&st->s_ndialers, "ndialers", "open dialers");
- nni_stat_set_type(&st->s_ndialers, NNG_STAT_LEVEL);
- nni_stat_add(root, &st->s_ndialers);
-
- nni_stat_init_atomic(
- &st->s_nlisteners, "nlisteners", "open listeners");
- nni_stat_set_type(&st->s_nlisteners, NNG_STAT_LEVEL);
- nni_stat_add(root, &st->s_nlisteners);
-
- nni_stat_init_atomic(&st->s_npipes, "npipes", "open pipes");
- nni_stat_set_type(&st->s_npipes, NNG_STAT_LEVEL);
- nni_stat_add(root, &st->s_npipes);
-
- nni_stat_init_atomic(&st->s_rxbytes, "rxbytes", "bytes received");
- nni_stat_set_unit(&st->s_rxbytes, NNG_UNIT_BYTES);
- nni_stat_add(root, &st->s_rxbytes);
-
- nni_stat_init_atomic(&st->s_txbytes, "txbytes", "bytes sent");
- nni_stat_set_unit(&st->s_txbytes, NNG_UNIT_BYTES);
- nni_stat_add(root, &st->s_txbytes);
-
- nni_stat_init_atomic(&st->s_rxmsgs, "rxmsgs", "messages received");
- nni_stat_set_unit(&st->s_rxmsgs, NNG_UNIT_MESSAGES);
- nni_stat_add(root, &st->s_rxmsgs);
-
- nni_stat_init_atomic(&st->s_txmsgs, "txmsgs", "messages sent");
- nni_stat_set_unit(&st->s_txmsgs, NNG_UNIT_MESSAGES);
- nni_stat_add(root, &st->s_txmsgs);
-
- nni_stat_init_atomic(&st->s_reject, "reject", "pipes rejected");
- nni_stat_add(root, &st->s_reject);
-#else
- NNI_ARG_UNUSED(s);
-#endif
+ nni_stat_init(&s->st_root, &root_info);
+ sock_stat_init(s, &s->st_id, &id_info);
+ sock_stat_init(s, &s->st_name, &name_info);
+ sock_stat_init(s, &s->st_protocol, &protocol_info);
+ sock_stat_init(s, &s->st_dialers, &dialers_info);
+ sock_stat_init(s, &s->st_listeners, &listeners_info);
+ sock_stat_init(s, &s->st_pipes, &pipes_info);
+ sock_stat_init(s, &s->st_rejects, &reject_info);
+ sock_stat_init(s, &s->st_tx_msgs, &tx_msgs_info);
+ sock_stat_init(s, &s->st_rx_msgs, &rx_msgs_info);
+ sock_stat_init(s, &s->st_tx_bytes, &tx_bytes_info);
+ sock_stat_init(s, &s->st_rx_bytes, &rx_bytes_info);
+
+ nni_stat_set_id(&s->st_id, s->s_id);
+ nni_stat_set_string(&s->st_name, s->s_name);
+ nni_stat_set_string(&s->st_protocol, nni_sock_proto_name(s));
}
+#endif
static void
sock_destroy(nni_sock *s)
{
nni_sockopt *sopt;
+#ifdef NNG_ENABLE_STATS
+ nni_stat_unregister(&s->st_root);
+#endif
+
// The protocol needs to clean up its state.
if (s->s_data != NULL) {
s->s_sock_ops.sock_fini(s->s_data);
@@ -490,7 +528,6 @@ sock_destroy(nni_sock *s)
nni_mtx_lock(&s->s_mx);
nni_mtx_unlock(&s->s_mx);
- sock_stats_fini(s);
nni_msgq_fini(s->s_urq);
nni_msgq_fini(s->s_uwq);
nni_cv_fini(&s->s_close_cv);
@@ -519,7 +556,7 @@ nni_sock_create(nni_sock **sp, const nni_proto *proto)
s->s_reconnmax = 0;
s->s_rcvmaxsz = 0; // unlimited by default
s->s_id = 0;
- s->s_refcnt = 0;
+ s->s_ref = 0;
s->s_self_id = proto->proto_self;
s->s_peer_id = proto->proto_peer;
s->s_flags = proto->proto_flags;
@@ -545,7 +582,10 @@ nni_sock_create(nni_sock **sp, const nni_proto *proto)
nni_mtx_init(&s->s_pipe_cbs_mtx);
nni_cv_init(&s->s_cv, &s->s_mx);
nni_cv_init(&s->s_close_cv, &sock_lk);
+
+#ifdef NNG_ENABLE_STATS
sock_stats_init(s);
+#endif
if (((rv = nni_msgq_init(&s->s_uwq, 0)) != 0) ||
((rv = nni_msgq_init(&s->s_urq, 1)) != 0) ||
@@ -629,11 +669,10 @@ nni_sock_open(nni_sock **sockp, const nni_proto *proto)
(void) snprintf(s->s_name, sizeof(s->s_name), "%u", s->s_id);
// Set up basic stat values.
- (void) snprintf(s->s_scope, sizeof(s->s_scope), "socket%u", s->s_id);
- nni_stat_set_value(&s->s_stats.s_id, s->s_id);
+ nni_stat_set_id(&s->st_id, s->s_id);
// Add our stats chain.
- nni_stat_register(&s->s_stats.s_root);
+ nni_stat_register(&s->st_root);
return (0);
}
@@ -677,7 +716,7 @@ nni_sock_shutdown(nni_sock *sock)
while ((ctx = nctx) != NULL) {
nctx = nni_list_next(&sock->s_ctxs, ctx);
ctx->c_closed = true;
- if (ctx->c_refcnt == 0) {
+ if (ctx->c_ref == 0) {
// No open operations. So close it.
nni_id_remove(&ctx_ids, ctx->c_id);
nni_list_remove(&sock->s_ctxs, ctx);
@@ -767,8 +806,6 @@ nni_sock_close(nni_sock *s)
// is idempotent.
nni_sock_shutdown(s);
- nni_stat_unregister(&s->s_stats.s_root);
-
nni_mtx_lock(&sock_lk);
if (s->s_closed) {
// Some other thread called close. All we need to do
@@ -787,7 +824,7 @@ nni_sock_close(nni_sock *s)
// Wait for all other references to drop. Note that we
// have a reference already (from our caller).
s->s_ctxwait = true;
- while ((s->s_refcnt > 1) || (!nni_list_empty(&s->s_ctxs))) {
+ while ((s->s_ref > 1) || (!nni_list_empty(&s->s_ctxs))) {
nni_cv_wait(&s->s_close_cv);
}
nni_mtx_unlock(&sock_lk);
@@ -819,7 +856,7 @@ nni_sock_closeall(void)
}
// Bump the reference count. The close call below
// will drop it.
- s->s_refcnt++;
+ s->s_ref++;
nni_list_node_remove(&s->s_node);
nni_mtx_unlock(&sock_lk);
nni_sock_close(s);
@@ -901,7 +938,9 @@ nni_sock_add_listener(nni_sock *s, nni_listener *l)
nni_list_append(&s->s_listeners, l);
- nni_stat_inc_atomic(&s->s_stats.s_nlisteners, 1);
+#ifdef NNG_ENABLE_STATS
+ nni_stat_inc(&s->st_listeners, 1);
+#endif
nni_mtx_unlock(&s->s_mx);
return (0);
@@ -930,7 +969,9 @@ nni_sock_add_dialer(nni_sock *s, nni_dialer *d)
nni_list_append(&s->s_dialers, d);
- nni_stat_inc_atomic(&s->s_stats.s_ndialers, 1);
+#ifdef NNG_ENABLE_STATS
+ nni_stat_inc(&s->st_dialers, 1);
+#endif
nni_mtx_unlock(&s->s_mx);
return (0);
@@ -1159,7 +1200,7 @@ nni_ctx_find(nni_ctx **cp, uint32_t id, bool closing)
if (ctx->c_closed || ((!closing) && ctx->c_sock->s_closed)) {
rv = NNG_ECLOSED;
} else {
- ctx->c_refcnt++;
+ ctx->c_ref++;
*cp = ctx;
}
} else {
@@ -1186,8 +1227,8 @@ nni_ctx_rele(nni_ctx *ctx)
{
nni_sock *sock = ctx->c_sock;
nni_mtx_lock(&sock_lk);
- ctx->c_refcnt--;
- if ((ctx->c_refcnt > 0) || (!ctx->c_closed)) {
+ ctx->c_ref--;
+ if ((ctx->c_ref > 0) || (!ctx->c_closed)) {
// Either still have an active reference, or not
// actually closing yet.
nni_mtx_unlock(&sock_lk);
@@ -1225,7 +1266,7 @@ nni_ctx_open(nni_ctx **ctxp, nni_sock *sock)
ctx->c_size = sz;
ctx->c_data = ctx + 1;
ctx->c_closed = false;
- ctx->c_refcnt = 1; // Caller implicitly gets a reference.
+ ctx->c_ref = 1; // Caller implicitly gets a reference.
ctx->c_sock = sock;
ctx->c_ops = sock->s_ctx_ops;
ctx->c_rcvtimeo = sock->s_rcvtimeo;
@@ -1413,29 +1454,37 @@ nni_dialer_add_pipe(nni_dialer *d, void *tpipe)
d->d_pipe = p;
d->d_currtime = d->d_inirtime;
nni_mtx_unlock(&s->s_mx);
- nni_stat_inc_atomic(&s->s_stats.s_npipes, 1);
- nni_stat_inc_atomic(&d->d_stats.s_npipes, 1);
+#ifdef NNG_ENABLE_STATS
+ nni_stat_inc(&s->st_pipes, 1);
+ nni_stat_inc(&d->st_pipes, 1);
+#endif
nni_pipe_run_cb(p, NNG_PIPE_EV_ADD_PRE);
nni_mtx_lock(&s->s_mx);
if (p->p_closed) {
nni_mtx_unlock(&s->s_mx);
- nni_stat_inc_atomic(&d->d_stats.s_reject, 1);
- nni_stat_inc_atomic(&s->s_stats.s_reject, 1);
+#ifdef NNG_ENABLE_STATS
+ nni_stat_inc(&d->st_reject, 1);
+ nni_stat_inc(&s->st_rejects, 1);
+#endif
nni_pipe_rele(p);
return;
}
if (p->p_proto_ops.pipe_start(p->p_proto_data) != 0) {
nni_mtx_unlock(&s->s_mx);
- nni_stat_inc_atomic(&d->d_stats.s_reject, 1);
- nni_stat_inc_atomic(&s->s_stats.s_reject, 1);
+#ifdef NNG_ENABLE_STATS
+ nni_stat_inc(&d->st_reject, 1);
+ nni_stat_inc(&s->st_rejects, 1);
+#endif
nni_pipe_close(p);
nni_pipe_rele(p);
return;
}
nni_mtx_unlock(&s->s_mx);
- nni_stat_register(&p->p_stats.s_root);
+#ifdef NNG_ENABLE_STATS
+ nni_stat_register(&p->st_root);
+#endif
nni_pipe_run_cb(p, NNG_PIPE_EV_ADD_POST);
nni_pipe_rele(p);
}
@@ -1483,7 +1532,9 @@ nni_dialer_reap(nni_dialer *d)
nni_aio_stop(&d->d_tmo_aio);
nni_aio_stop(&d->d_con_aio);
- nni_stat_unregister(&d->d_stats.s_root);
+#ifdef NNG_ENABLE_STATS
+ nni_stat_unregister(&d->st_root);
+#endif
nni_mtx_lock(&s->s_mx);
if (!nni_list_empty(&d->d_pipes)) {
@@ -1524,29 +1575,35 @@ nni_listener_add_pipe(nni_listener *l, void *tpipe)
nni_list_append(&l->l_pipes, p);
nni_list_append(&s->s_pipes, p);
nni_mtx_unlock(&s->s_mx);
- nni_stat_inc_atomic(&l->l_stats.s_npipes, 1);
- nni_stat_inc_atomic(&s->s_stats.s_npipes, 1);
+#ifdef NNG_ENABLE_STATS
+ nni_stat_inc(&l->st_pipes, 1);
+ nni_stat_inc(&s->st_pipes, 1);
+#endif
nni_pipe_run_cb(p, NNG_PIPE_EV_ADD_PRE);
nni_mtx_lock(&s->s_mx);
if (p->p_closed) {
nni_mtx_unlock(&s->s_mx);
- nni_stat_inc_atomic(&l->l_stats.s_reject, 1);
- nni_stat_inc_atomic(&s->s_stats.s_reject, 1);
+#ifdef NNG_ENABLE_STATS
+ nni_stat_inc(&l->st_reject, 1);
+ nni_stat_inc(&s->st_rejects, 1);
+#endif
nni_pipe_rele(p);
return;
}
if (p->p_proto_ops.pipe_start(p->p_proto_data) != 0) {
nni_mtx_unlock(&s->s_mx);
- nni_stat_inc_atomic(&l->l_stats.s_reject, 1);
- nni_stat_inc_atomic(&s->s_stats.s_reject, 1);
+#ifdef NNG_ENABLE_STATS
+ nni_stat_inc(&l->st_reject, 1);
+ nni_stat_inc(&s->st_rejects, 1);
+#endif
nni_pipe_close(p);
nni_pipe_rele(p);
return;
}
nni_mtx_unlock(&s->s_mx);
- nni_stat_register(&p->p_stats.s_root);
+ nni_stat_register(&p->st_root);
nni_pipe_run_cb(p, NNG_PIPE_EV_ADD_POST);
nni_pipe_rele(p);
}
@@ -1595,7 +1652,9 @@ nni_listener_reap(nni_listener *l)
nni_aio_stop(&l->l_tmo_aio);
nni_aio_stop(&l->l_acc_aio);
- nni_stat_unregister(&l->l_stats.s_root);
+#ifdef NNG_ENABLE_STATS
+ nni_stat_unregister(&l->st_root);
+#endif
nni_mtx_lock(&s->s_mx);
if (!nni_list_empty(&l->l_pipes)) {
@@ -1655,15 +1714,17 @@ nni_pipe_remove(nni_pipe *p)
nni_dialer *d = p->p_dialer;
nni_mtx_lock(&s->s_mx);
+#ifdef NNG_ENABLE_STATS
if (nni_list_node_active(&p->p_sock_node)) {
- nni_stat_dec_atomic(&s->s_stats.s_npipes, 1);
+ nni_stat_dec(&s->st_pipes, 1);
}
if (p->p_listener != NULL) {
- nni_stat_dec_atomic(&p->p_listener->l_stats.s_npipes, 1);
+ nni_stat_dec(&p->p_listener->st_pipes, 1);
}
if (p->p_dialer != NULL) {
- nni_stat_dec_atomic(&p->p_dialer->d_stats.s_npipes, 1);
+ nni_stat_dec(&p->p_dialer->st_pipes, 1);
}
+#endif
nni_list_node_remove(&p->p_sock_node);
nni_list_node_remove(&p->p_ep_node);
p->p_listener = NULL;
@@ -1682,7 +1743,7 @@ void
nni_sock_add_stat(nni_sock *s, nni_stat_item *stat)
{
#ifdef NNG_ENABLE_STATS
- nni_stat_add(&s->s_stats.s_root, stat);
+ nni_stat_add(&s->st_root, stat);
#else
NNI_ARG_UNUSED(s);
NNI_ARG_UNUSED(stat);
@@ -1693,8 +1754,8 @@ void
nni_sock_bump_tx(nni_sock *s, uint64_t sz)
{
#ifdef NNG_ENABLE_STATS
- nni_stat_inc_atomic(&s->s_stats.s_txmsgs, 1);
- nni_stat_inc_atomic(&s->s_stats.s_txbytes, sz);
+ nni_stat_inc(&s->st_tx_msgs, 1);
+ nni_stat_inc(&s->st_tx_bytes, sz);
#else
NNI_ARG_UNUSED(s);
NNI_ARG_UNUSED(sz);
@@ -1705,8 +1766,8 @@ void
nni_sock_bump_rx(nni_sock *s, uint64_t sz)
{
#ifdef NNG_ENABLE_STATS
- nni_stat_inc_atomic(&s->s_stats.s_rxmsgs, 1);
- nni_stat_inc_atomic(&s->s_stats.s_rxbytes, sz);
+ nni_stat_inc(&s->st_rx_msgs, 1);
+ nni_stat_inc(&s->st_rx_bytes, sz);
#else
NNI_ARG_UNUSED(s);
NNI_ARG_UNUSED(sz);
diff --git a/src/core/sockimpl.h b/src/core/sockimpl.h
index 732e2285..804fa00c 100644
--- a/src/core/sockimpl.h
+++ b/src/core/sockimpl.h
@@ -15,25 +15,6 @@
// and pipes. This must not be exposed to other subsystems -- these internals
// are subject to change at any time.
-typedef struct nni_dialer_stats {
- nni_stat_item s_root;
- nni_stat_item s_id;
- nni_stat_item s_sock;
- nni_stat_item s_url;
- nni_stat_item s_npipes;
- nni_stat_item s_connok;
- nni_stat_item s_refused;
- nni_stat_item s_discon;
- nni_stat_item s_canceled;
- nni_stat_item s_othererr;
- nni_stat_item s_etimedout;
- nni_stat_item s_eproto; // protocol error
- nni_stat_item s_eauth;
- nni_stat_item s_enomem;
- nni_stat_item s_reject;
- char s_scope[24]; // scope name for stats
-} nni_dialer_stats;
-
struct nni_dialer {
nni_tran_dialer_ops d_ops; // transport ops
nni_tran * d_tran; // transport pointer
@@ -42,8 +23,8 @@ struct nni_dialer {
nni_list_node d_node; // per socket list
nni_sock * d_sock;
nni_url * d_url;
- nni_pipe * d_pipe; // active pipe (for redialer)
- int d_refcnt;
+ nni_pipe * d_pipe; // active pipe (for re-dialer)
+ int d_ref;
bool d_closed; // full shutdown
bool d_closing;
nni_atomic_flag d_started;
@@ -57,26 +38,25 @@ struct nni_dialer {
nni_duration d_inirtime; // initial time for reconnect
nni_time d_conntime; // time of last good connect
nni_reap_item d_reap;
- nni_dialer_stats d_stats;
-};
-typedef struct nni_listener_stats {
- nni_stat_item s_root;
- nni_stat_item s_id;
- nni_stat_item s_sock;
- nni_stat_item s_url;
- nni_stat_item s_npipes;
- nni_stat_item s_accept;
- nni_stat_item s_discon; // aborted remotely
- nni_stat_item s_canceled;
- nni_stat_item s_othererr;
- nni_stat_item s_etimedout;
- nni_stat_item s_eproto; // protocol error
- nni_stat_item s_eauth;
- nni_stat_item s_enomem;
- nni_stat_item s_reject;
- char s_scope[24]; // scope name for stats
-} nni_listener_stats;
+#ifdef NNG_ENABLE_STATS
+ nni_stat_item st_root;
+ nni_stat_item st_id;
+ nni_stat_item st_sock;
+ nni_stat_item st_url;
+ nni_stat_item st_pipes;
+ nni_stat_item st_connect;
+ nni_stat_item st_refused;
+ nni_stat_item st_disconnect; // aborted remotely
+ nni_stat_item st_canceled;
+ nni_stat_item st_other;
+ nni_stat_item st_timeout;
+ nni_stat_item st_proto; // protocol error
+ nni_stat_item st_auth;
+ nni_stat_item st_oom;
+ nni_stat_item st_reject;
+#endif
+};
struct nni_listener {
nni_tran_listener_ops l_ops; // transport ops
@@ -86,7 +66,7 @@ struct nni_listener {
nni_list_node l_node; // per socket list
nni_sock * l_sock;
nni_url * l_url;
- int l_refcnt;
+ int l_ref;
bool l_closed; // full shutdown
bool l_closing; // close started (shutdown)
nni_atomic_flag l_started;
@@ -94,20 +74,24 @@ struct nni_listener {
nni_aio l_acc_aio;
nni_aio l_tmo_aio;
nni_reap_item l_reap;
- nni_listener_stats l_stats;
-};
-typedef struct nni_pipe_stats {
- nni_stat_item s_root;
- nni_stat_item s_id;
- nni_stat_item s_ep_id;
- nni_stat_item s_sock_id;
- nni_stat_item s_rxmsgs;
- nni_stat_item s_txmsgs;
- nni_stat_item s_rxbytes;
- nni_stat_item s_txbytes;
- char s_scope[16]; // scope name for stats ("pipe" is short)
-} nni_pipe_stats;
+#ifdef NNG_ENABLE_STATS
+ nni_stat_item st_root;
+ nni_stat_item st_id;
+ nni_stat_item st_sock;
+ nni_stat_item st_url;
+ nni_stat_item st_pipes;
+ nni_stat_item st_accept;
+ nni_stat_item st_disconnect; // aborted remotely
+ nni_stat_item st_canceled;
+ nni_stat_item st_other;
+ nni_stat_item st_timeout;
+ nni_stat_item st_proto; // protocol error
+ nni_stat_item st_auth;
+ nni_stat_item st_oom;
+ nni_stat_item st_reject;
+#endif
+};
struct nni_pipe {
uint32_t p_id;
@@ -124,11 +108,22 @@ struct nni_pipe {
bool p_closed;
nni_atomic_flag p_stop;
bool p_cbs;
- int p_refcnt;
+ int p_ref;
nni_mtx p_mtx;
nni_cv p_cv;
nni_reap_item p_reap;
- nni_pipe_stats p_stats;
+
+#ifdef NNG_ENABLE_STATS
+ nni_stat_item st_root;
+ nni_stat_item st_id;
+ nni_stat_item st_ep_id;
+ nni_stat_item st_sock_id;
+ nni_stat_item st_rx_msgs;
+ nni_stat_item st_tx_msgs;
+ nni_stat_item st_rx_bytes;
+ nni_stat_item st_tx_bytes;
+
+#endif
};
extern int nni_sock_add_dialer(nni_sock *, nni_dialer *);
diff --git a/src/core/stats.c b/src/core/stats.c
index d6f98e3e..14cf7978 100644
--- a/src/core/stats.c
+++ b/src/core/stats.c
@@ -16,23 +16,24 @@
typedef struct nng_stat nni_stat;
struct nng_stat {
- char * s_name;
- char * s_desc;
- char * s_string;
- uint64_t s_value;
- nni_time s_time;
- nni_stat_type s_type;
- nni_stat_unit s_unit;
- nni_stat_item *s_item; // Used during snapshot collection
- nni_list s_children;
- nni_stat * s_parent;
- nni_list_node s_node;
+ const nni_stat_info *s_info;
+ const nni_stat_item *s_item; // Used during snapshot collection
+ nni_list s_children;
+ nni_stat * s_parent;
+ nni_list_node s_node;
+ nni_time s_timestamp;
+ union {
+ int sv_id;
+ bool sv_bool;
+ uint64_t sv_value;
+ char * sv_string;
+ } s_val;
};
#ifdef NNG_ENABLE_STATS
static nni_stat_item stats_root;
static nni_mtx stats_lock;
-static nni_mtx * stats_held = NULL;
+static nni_mtx stats_val_lock;
#endif
void
@@ -68,135 +69,149 @@ nni_stat_register(nni_stat_item *child)
#endif
}
+#ifdef NNG_ENABLE_STATS
+void
+stat_unregister(nni_stat_item *item)
+{
+ nni_stat_item *child;
+ while ((child = nni_list_first(&item->si_children)) != NULL) {
+ stat_unregister(child);
+ }
+ if ((item->si_info->si_alloc) &&
+ (item->si_info->si_type == NNG_STAT_STRING)) {
+ nni_strfree(item->si_value.sv_string);
+ item->si_value.sv_string = NULL;
+ }
+ nni_list_node_remove(&item->si_node);
+}
+#endif
+
void
-nni_stat_unregister(nni_stat_item *stat)
+nni_stat_unregister(nni_stat_item *item)
{
#ifdef NNG_ENABLE_STATS
nni_mtx_lock(&stats_lock);
- nni_list_node_remove(&stat->si_node);
+ stat_unregister(item);
nni_mtx_unlock(&stats_lock);
#else
- NNI_ARG_UNUSED(child);
+ NNI_ARG_UNUSED(item);
#endif
}
-#ifdef NNG_ENABLE_STATS
void
-nni_stat_init(nni_stat_item *stat, const char *name, const char *desc)
+nni_stat_init(nni_stat_item *item, const nni_stat_info *info)
{
- NNI_LIST_INIT(&stat->si_children, nni_stat_item, si_node);
- stat->si_name = name;
- stat->si_desc = desc;
- stat->si_lock = NULL;
- stat->si_update = NULL;
- stat->si_string = NULL;
- stat->si_number = 0;
- stat->si_type = NNG_STAT_COUNTER;
- stat->si_unit = NNG_UNIT_NONE;
+#ifdef NNG_ENABLE_STATS
+ memset(item, 0, sizeof(*item));
+ NNI_LIST_INIT(&item->si_children, nni_stat_item, si_node);
+ item->si_info = info;
+#else
+ NNI_ARG_UNUSED(item);
+ NNI_ARG_UNUSED(info);
+#endif
}
void
-nni_stat_init_scope(nni_stat_item *stat, const char *name, const char *desc)
+nni_stat_inc(nni_stat_item *item, uint64_t inc)
{
- nni_stat_init(stat, name, desc);
- stat->si_type = NNG_STAT_SCOPE;
- stat->si_unit = NNG_UNIT_NONE;
+#ifdef NNG_ENABLE_STATS
+ if (item->si_info->si_atomic) {
+ nni_atomic_add64(&item->si_value.sv_atomic, inc);
+ } else {
+ item->si_value.sv_number += inc;
+ }
+#else
+ NNI_ARG_UNUSED(item);
+ NNI_ARG_UNUSED(inc);
+#endif
}
void
-nni_stat_init_string(
- nni_stat_item *stat, const char *name, const char *desc, const char *str)
+nni_stat_dec(nni_stat_item *item, uint64_t inc)
{
- nni_stat_init(stat, name, desc);
- stat->si_string = str;
- stat->si_type = NNG_STAT_STRING;
- stat->si_unit = NNG_UNIT_NONE;
-}
+#ifdef NNG_ENABLE_STATS
-void
-nni_stat_init_id(
- nni_stat_item *stat, const char *name, const char *desc, uint64_t id)
-{
- nni_stat_init(stat, name, desc);
- stat->si_number = id;
- stat->si_type = NNG_STAT_ID;
- stat->si_unit = NNG_UNIT_NONE;
+ if (item->si_info->si_atomic) {
+ nni_atomic_sub64(&item->si_value.sv_atomic, inc);
+ } else {
+ item->si_value.sv_number -= inc;
+ }
+#else
+ NNI_ARG_UNUSED(item);
+ NNI_ARG_UNUSED(inc);
+#endif
}
void
-nni_stat_init_bool(
- nni_stat_item *stat, const char *name, const char *desc, bool v)
+nni_stat_set_id(nni_stat_item *item, int id)
{
- nni_stat_init(stat, name, desc);
- stat->si_number = v ? 1 : 0;
- stat->si_type = NNG_STAT_BOOLEAN;
- stat->si_unit = NNG_UNIT_NONE;
-}
-
-static void
-stat_atomic_update(nni_stat_item *stat)
-{
- stat->si_number = nni_atomic_get64(&stat->si_atomic);
+#ifdef NNG_ENABLE_STATS
+ // IDs don't change, so just set it.
+ item->si_value.sv_id = id;
+#else
+ NNI_ARG_UNUSED(item);
+ NNI_ARG_UNUSED(id);
+#endif
}
void
-nni_stat_init_atomic(nni_stat_item *stat, const char *name, const char *desc)
+nni_stat_set_bool(nni_stat_item *item, bool b)
{
- nni_stat_init(stat, name, desc);
- stat->si_number = 0;
- stat->si_update = stat_atomic_update;
- nni_atomic_init64(&stat->si_atomic);
+#ifdef NNG_ENABLE_STATS
+ // bool is atomic by definitions.
+ item->si_value.sv_bool = b;
+#else
+ NNI_ARG_UNUSED(item);
+ NNI_ARG_UNUSED(id);
+#endif
}
void
-nni_stat_inc_atomic(nni_stat_item *stat, uint64_t inc)
+nni_stat_set_string(nni_stat_item *item, const char *s)
{
- nni_atomic_add64(&stat->si_atomic, inc);
-}
+#ifdef NNG_ENABLE_STATS
+ const nni_stat_info *info = item->si_info;
+ char * old = item->si_value.sv_string;
+
+ nni_mtx_lock(&stats_val_lock);
+ if ((s != NULL) && (old != NULL) && (strcmp(s, old) == 0)) {
+ // no change
+ nni_mtx_unlock(&stats_val_lock);
+ return;
+ }
-void
-nni_stat_dec_atomic(nni_stat_item *stat, uint64_t inc)
-{
- nni_atomic_sub64(&stat->si_atomic, inc);
-}
-#endif
+ if (!info->si_alloc) {
+ // no allocation, just set it.
+ item->si_value.sv_string = (char *) s;
+ nni_mtx_unlock(&stats_val_lock);
+ return;
+ }
-void
-nni_stat_set_value(nni_stat_item *stat, uint64_t v)
-{
-#ifdef NNG_ENABLE_STATS
- stat->si_number = v;
+ item->si_value.sv_string = nni_strdup(s);
+ nni_mtx_unlock(&stats_val_lock);
+
+ nni_strfree(old);
#else
- NNI_ARG_UNUSED(stat);
- NNI_ARG_UNUSED(v);
+ NNG_ARG_UNUSED(item);
+ NNG_ARG_UNUSED(s);
#endif
}
void
-nni_stat_set_lock(nni_stat_item *stat, nni_mtx *mtx)
+nni_stat_set_value(nni_stat_item *item, uint64_t v)
{
#ifdef NNG_ENABLE_STATS
- stat->si_lock = mtx;
+ if (item->si_info->si_atomic) {
+ nni_atomic_set64(&item->si_value.sv_atomic, v);
+ } else {
+ item->si_value.sv_number = v;
+ }
#else
NNI_ARG_UNUSED(stat);
- NNI_ARG_UNUSED(mtx);
+ NNI_ARG_UNUSED(v);
#endif
}
-#ifdef NNG_ENABLE_STATS
-void
-nni_stat_set_type(nni_stat_item *stat, int type)
-{
- stat->si_type = type;
-}
-
-void
-nni_stat_set_unit(nni_stat_item *stat, int unit)
-{
- stat->si_unit = unit;
-}
-#endif
-
void
nng_stats_free(nni_stat *st)
{
@@ -207,9 +222,9 @@ nng_stats_free(nni_stat *st)
nni_list_remove(&st->s_children, child);
nng_stats_free(child);
}
- nni_strfree(st->s_name);
- nni_strfree(st->s_desc);
- nni_strfree(st->s_string);
+ if (st->s_info->si_alloc) {
+ nni_strfree(st->s_val.sv_string);
+ }
NNI_FREE_STRUCT(st);
#else
NNI_ARG_UNUSED(st);
@@ -228,19 +243,8 @@ stat_make_tree(nni_stat_item *item, nni_stat **sp)
}
NNI_LIST_INIT(&stat->s_children, nni_stat, s_node);
- if (((stat->s_name = nni_strdup(item->si_name)) == NULL) ||
- ((stat->s_desc = nni_strdup(item->si_desc)) == NULL)) {
- nng_stats_free(stat);
- return (NNG_ENOMEM);
- }
- if ((item->si_type == NNG_STAT_STRING) &&
- ((stat->s_string = nni_strdup(item->si_string)) == NULL)) {
- nng_stats_free(stat);
- return (NNG_ENOMEM);
- }
+ stat->s_info = item->si_info;
stat->s_item = item;
- stat->s_type = item->si_type;
- stat->s_unit = item->si_unit;
stat->s_parent = NULL;
NNI_LIST_FOREACH (&item->si_children, child) {
@@ -260,23 +264,52 @@ stat_make_tree(nni_stat_item *item, nni_stat **sp)
static void
stat_update(nni_stat *stat)
{
- nni_stat_item *item = stat->s_item;
+ const nni_stat_item *item = stat->s_item;
+ const nni_stat_info *info = item->si_info;
+ char * old;
+ char * str;
- if (item->si_lock != stats_held) {
- if (stats_held != NULL) {
- nni_mtx_unlock(stats_held);
- stats_held = NULL;
+ switch (info->si_type) {
+ case NNG_STAT_SCOPE:
+ case NNG_STAT_ID:
+ stat->s_val.sv_id = item->si_value.sv_id;
+ break;
+ case NNG_STAT_BOOLEAN:
+ stat->s_val.sv_bool = item->si_value.sv_bool;
+ break;
+ case NNG_STAT_COUNTER:
+ case NNG_STAT_LEVEL:
+ if (info->si_atomic) {
+ stat->s_val.sv_value = nni_atomic_get64(
+ (nni_atomic_u64 *) &item->si_value.sv_atomic);
+ } else {
+ stat->s_val.sv_value = item->si_value.sv_number;
}
- if (item->si_lock != NULL) {
- nni_mtx_lock(item->si_lock);
- stats_held = item->si_lock;
+ break;
+ case NNG_STAT_STRING:
+ nni_mtx_lock(&stats_val_lock);
+ old = stat->s_val.sv_string;
+ str = item->si_value.sv_string;
+
+ // If we have to allocate a new string, do so. But
+ // only do it if new string is different.
+ if ((info->si_alloc) && (str != NULL) &&
+ ((old == NULL) || (strcmp(str, old) != 0))) {
+
+ stat->s_val.sv_string = nni_strdup(str);
+ nni_strfree(old);
+
+ } else if (info->si_alloc) {
+ nni_strfree(stat->s_val.sv_string);
+ stat->s_val.sv_string = NULL;
+
+ } else {
+ stat->s_val.sv_string = str;
}
+ nni_mtx_unlock(&stats_val_lock);
+ break;
}
- if (item->si_update != NULL) {
- item->si_update(item);
- }
- stat->s_value = item->si_number;
- stat->s_time = nni_clock();
+ stat->s_timestamp = nni_clock();
}
static void
@@ -304,10 +337,6 @@ nni_stat_snapshot(nni_stat **statp, nni_stat_item *item)
return (rv);
}
stat_update_tree(stat);
- if (stats_held != NULL) {
- nni_mtx_unlock(stats_held);
- stats_held = NULL;
- }
nni_mtx_unlock(&stats_lock);
*statp = stat;
return (0);
@@ -353,43 +382,53 @@ nng_stat_child(nng_stat *stat)
const char *
nng_stat_name(nni_stat *stat)
{
- return (stat->s_name);
+ return (stat->s_info->si_name);
}
uint64_t
nng_stat_value(nni_stat *stat)
{
- return (stat->s_value);
+ return (stat->s_val.sv_value);
+}
+
+bool
+nng_stat_bool(nni_stat *stat)
+{
+ return (stat->s_val.sv_bool);
}
+
const char *
nng_stat_string(nng_stat *stat)
{
- return (stat->s_string);
+ if (stat->s_info->si_type != NNG_STAT_STRING) {
+ return ("");
+ }
+ return (stat->s_val.sv_string);
}
uint64_t
nng_stat_timestamp(nng_stat *stat)
{
- return ((uint64_t) stat->s_time);
+ return ((uint64_t) stat->s_timestamp);
}
int
nng_stat_type(nng_stat *stat)
{
- return (stat->s_type);
+ return (stat->s_info->si_type);
}
int
nng_stat_unit(nng_stat *stat)
{
- return (stat->s_unit);
+ return (stat->s_info->si_unit);
}
const char *
nng_stat_desc(nng_stat *stat)
{
- return (stat->s_desc);
+ return (stat->s_info->si_desc);
}
nng_stat *
@@ -399,7 +438,28 @@ nng_stat_find(nng_stat *stat, const char *name)
if (stat == NULL) {
return (NULL);
}
- if (strcmp(name, stat->s_name) == 0) {
+ if (strcmp(name, stat->s_info->si_name) == 0) {
+ return (stat);
+ }
+ NNI_LIST_FOREACH (&stat->s_children, child) {
+ nng_stat *result;
+ if ((result = nng_stat_find(child, name)) != NULL) {
+ return (result);
+ }
+ }
+ return (NULL);
+}
+
+nng_stat *
+nng_stat_find_scope(nng_stat *stat, const char *name, int id)
+{
+ nng_stat *child;
+ if (stat == NULL) {
+ return (NULL);
+ }
+ if ((stat->s_val.sv_id == id) &&
+ (stat->s_info->si_type == NNG_STAT_SCOPE) &&
+ (strcmp(name, stat->s_info->si_name) == 0)) {
return (stat);
}
NNI_LIST_FOREACH (&stat->s_children, child) {
@@ -414,35 +474,33 @@ nng_stat_find(nng_stat *stat, const char *name)
nng_stat *
nng_stat_find_socket(nng_stat *stat, nng_socket s)
{
- char name[16];
- (void) snprintf(name, sizeof(name), "socket%d", nng_socket_id(s));
- return (nng_stat_find(stat, name));
+ return (nng_stat_find_scope(stat, "socket", nng_socket_id(s)));
}
nng_stat *
nng_stat_find_dialer(nng_stat *stat, nng_dialer d)
{
- char name[16];
- (void) snprintf(name, sizeof(name), "dialer%d", nng_dialer_id(d));
- return (nng_stat_find(stat, name));
+ return (nng_stat_find_scope(stat, "dialer", nng_dialer_id(d)));
}
nng_stat *
nng_stat_find_listener(nng_stat *stat, nng_listener l)
{
- char name[16];
- (void) snprintf(name, sizeof(name), "listener%d", nng_listener_id(l));
- return (nng_stat_find(stat, name));
+ return (nng_stat_find_scope(stat, "listener", nng_listener_id(l)));
}
int
nni_stat_sys_init(void)
{
#ifdef NNG_ENABLE_STATS
+ static const nni_stat_info root = {
+ .si_name = "",
+ .si_desc = "all statistics",
+ .si_type = NNG_STAT_SCOPE,
+ };
nni_mtx_init(&stats_lock);
- NNI_LIST_INIT(&stats_root.si_children, nni_stat_item, si_node);
- stats_root.si_name = "";
- stats_root.si_desc = "all statistics";
+ nni_mtx_init(&stats_val_lock);
+ nni_stat_init(&stats_root, &root);
#endif
return (0);
}
@@ -452,6 +510,7 @@ nni_stat_sys_fini(void)
{
#ifdef NNG_ENABLE_STATS
nni_mtx_fini(&stats_lock);
+ nni_mtx_fini(&stats_val_lock);
#endif
}
@@ -462,8 +521,9 @@ stat_sprint_scope(nni_stat *stat, char **scope, int *lenp)
if (stat->s_parent != NULL) {
stat_sprint_scope(stat->s_parent, scope, lenp);
}
- if (strlen(stat->s_name) > 0) {
- snprintf(*scope, *lenp, "%s.", stat->s_name);
+ if (strlen(stat->s_info->si_name) > 0) {
+ snprintf(*scope, *lenp, "%s#%d.", stat->s_info->si_name,
+ stat->s_val.sv_id);
} else {
(*scope)[0] = '\0';
}
@@ -503,9 +563,8 @@ nng_stats_dump(nng_stat *stat)
nng_stat_string(stat));
break;
case NNG_STAT_BOOLEAN:
- val = nng_stat_value(stat);
nni_plat_printf("%s%-32s%s\n", indent, nng_stat_name(stat),
- val != 0 ? "true" : "false");
+ nng_stat_bool(stat) ? "true" : "false");
break;
case NNG_STAT_LEVEL:
case NNG_STAT_COUNTER:
@@ -520,7 +579,7 @@ nng_stats_dump(nng_stat *stat)
nni_plat_printf(" msgs\n");
break;
case NNG_UNIT_MILLIS:
- nni_plat_printf(" msec\n");
+ nni_plat_printf(" ms\n");
break;
case NNG_UNIT_NONE:
case NNG_UNIT_EVENTS:
diff --git a/src/core/stats.h b/src/core/stats.h
index 0375979e..950df78f 100644
--- a/src/core/stats.h
+++ b/src/core/stats.h
@@ -24,6 +24,7 @@
// acquire the lock on the stat first though.
typedef struct nni_stat_item nni_stat_item;
+typedef struct nni_stat_info nni_stat_info;
typedef void (*nni_stat_update)(nni_stat_item *);
typedef enum nng_stat_type_enum nni_stat_type;
@@ -35,21 +36,26 @@ typedef enum nng_unit_enum nni_stat_unit;
// avoid having to spend dereference costs or (worse) to have to include
// extra conditionals on hot code paths.
struct nni_stat_item {
-#ifdef NNG_ENABLE_STATS
- nni_list_node si_node; // list node, framework use only
- nni_list si_children; // children, framework use only
- const char * si_name; // name of statistic
- const char * si_desc; // description of statistic (English)
- nni_mtx * si_lock; // lock for accessing, can be NULL
- nni_stat_type si_type; // type of stat, e.g. NNG_STAT_LEVEL
- nni_stat_unit si_unit; // units, e.g. NNG_UNIT_MILLIS
- nni_stat_update si_update; // update function (can be NULL)
- const char * si_string; // string value (NULL for numerics)
- uint64_t si_number; // numeric value
- nni_atomic_u64 si_atomic; // atomic value
-#else
- char si_disabled; // place holder, cannot be empty in C
-#endif
+ nni_list_node si_node; // list node, framework use only
+ nni_list si_children; // children, framework use only
+ const nni_stat_info *si_info; // statistic description
+ union {
+ uint64_t sv_number;
+ nni_atomic_u64 sv_atomic;
+ char * sv_string;
+ bool sv_bool;
+ int sv_id;
+ } si_value;
+};
+
+struct nni_stat_info {
+ const char * si_name; // name of statistic
+ const char * si_desc; // description of statistic (English)
+ nni_stat_type si_type; // statistic type, e.g. NNG_STAT_LEVEL
+ nni_stat_unit si_unit; // statistic unit, e.g. NNG_UNIT_MILLIS
+ nni_stat_update si_update; // update function (can be NULL)
+ bool si_atomic : 1; // stat is atomic
+ bool si_alloc : 1; // stat string is allocated
};
// nni_stat_add adds a statistic, but the operation is unlocked, and the
@@ -64,37 +70,12 @@ void nni_stat_register(nni_stat_item *);
void nni_stat_unregister(nni_stat_item *);
void nni_stat_set_value(nni_stat_item *, uint64_t);
-void nni_stat_set_lock(nni_stat_item *, nni_mtx *);
-
-#ifdef NNG_ENABLE_STATS
-void nni_stat_init(nni_stat_item *, const char *, const char *);
-void nni_stat_init_scope(nni_stat_item *, const char *, const char *);
-void nni_stat_init_string(
- nni_stat_item *, const char *, const char *, const char *);
-void nni_stat_init_id(nni_stat_item *, const char *, const char *, uint64_t);
-void nni_stat_init_bool(nni_stat_item *, const char *, const char *, bool);
-void nni_stat_init_atomic(nni_stat_item *, const char *, const char *);
-void nni_stat_inc_atomic(nni_stat_item *, uint64_t);
-void nni_stat_dec_atomic(nni_stat_item *, uint64_t);
-void nni_stat_set_type(nni_stat_item *, int);
-void nni_stat_set_unit(nni_stat_item *, int);
-#else
-// We override initialization so that we can avoid compiling static strings
-// into the binary. Presumably if stats are disabled, we are trying to save
-// space for constrained environments. We do evaluate an unused arg to
-// prevent the compiler from bitching about unused values.
-#define nni_stat_init(a, b, c) ((void) (a))
-#define nni_stat_init_scope(a, b, c) ((void) (a))
-#define nni_stat_init_atomic(a, b, c) ((void) (a))
-#define nni_stat_init_id(a, b, c, d) ((void) (a))
-#define nni_stat_init_bool(a, b, c, d) ((void) (a))
-#define nni_stat_init_string(a, b, c, d) ((void) (a))
-#define nni_stat_set_unit(a, b) ((void) (a))
-#define nni_stat_set_type(a, b) ((void) (a))
-#define nni_stat_inc_atomic(stat, inc)
-#define nni_stat_dec_atomic(stat, inc)
-#endif
-
+void nni_stat_set_id(nni_stat_item *, int);
+void nni_stat_set_bool(nni_stat_item *, bool);
+void nni_stat_set_string(nni_stat_item *, const char *);
+void nni_stat_init(nni_stat_item *, const nni_stat_info *);
+void nni_stat_inc(nni_stat_item *, uint64_t);
+void nni_stat_dec(nni_stat_item *, uint64_t);
int nni_stat_sys_init(void);
void nni_stat_sys_fini(void);
diff --git a/src/protocol/pair1/pair.c b/src/protocol/pair1/pair.c
index 0492119a..cc726306 100644
--- a/src/protocol/pair1/pair.c
+++ b/src/protocol/pair1/pair.c
@@ -15,7 +15,11 @@
// Pair protocol. The PAIRv1 protocol is a simple 1:1 messaging pattern.
-#define BUMP_STAT(x) nni_stat_inc_atomic(x, 1)
+#ifdef NNG_ENABLE_STATS
+#define BUMP_STAT(x) nni_stat_inc(x, 1)
+#else
+#define BUMP_STAT(x)
+#endif
typedef struct pair1_pipe pair1_pipe;
typedef struct pair1_sock pair1_sock;
@@ -37,14 +41,16 @@ struct pair1_sock {
nni_id_map pipes;
nni_list plist;
bool started;
- nni_stat_item stat_poly;
- nni_stat_item stat_raw;
- nni_stat_item stat_reject_mismatch;
- nni_stat_item stat_reject_already;
- nni_stat_item stat_ttl_drop;
- nni_stat_item stat_rx_malformed;
- nni_stat_item stat_tx_malformed;
- nni_stat_item stat_tx_drop;
+#ifdef NNG_ENABLE_STATS
+ nni_stat_item stat_poly;
+ nni_stat_item stat_raw;
+ nni_stat_item stat_reject_mismatch;
+ nni_stat_item stat_reject_already;
+ nni_stat_item stat_ttl_drop;
+ nni_stat_item stat_rx_malformed;
+ nni_stat_item stat_tx_malformed;
+ nni_stat_item stat_tx_drop;
+#endif
#ifdef NNG_TEST_LIB
bool inject_header;
#endif
@@ -70,6 +76,16 @@ pair1_sock_fini(void *arg)
nni_mtx_fini(&s->mtx);
}
+#ifdef NNG_ENABLE_STATS
+static void
+pair1_add_sock_stat(
+ pair1_sock *s, nni_stat_item *item, const nni_stat_info *info)
+{
+ nni_stat_init(item, info);
+ nni_sock_add_stat(s->sock, item);
+}
+#endif
+
static int
pair1_sock_init_impl(void *arg, nni_sock *sock, bool raw)
{
@@ -80,50 +96,81 @@ pair1_sock_init_impl(void *arg, nni_sock *sock, bool raw)
// Raw mode uses this.
nni_mtx_init(&s->mtx);
+ s->sock = sock;
- nni_stat_init_bool(
- &s->stat_poly, "polyamorous", "polyamorous mode?", false);
- nni_sock_add_stat(sock, &s->stat_poly);
-
- nni_stat_init_bool(&s->stat_raw, "raw", "raw mode?", raw);
- nni_sock_add_stat(sock, &s->stat_raw);
-
- nni_stat_init_atomic(&s->stat_reject_mismatch, "mismatch",
- "pipes rejected (protocol mismatch)");
- nni_sock_add_stat(sock, &s->stat_reject_mismatch);
-
- nni_stat_init_atomic(&s->stat_reject_already, "already",
- "pipes rejected (already connected)");
- nni_sock_add_stat(sock, &s->stat_reject_already);
-
- nni_stat_init_atomic(&s->stat_ttl_drop, "ttl_drop",
- "messages dropped due to too many hops");
- nni_stat_set_unit(&s->stat_ttl_drop, NNG_UNIT_MESSAGES);
- nni_sock_add_stat(sock, &s->stat_ttl_drop);
-
- // This can only increment in polyamorous mode.
- nni_stat_init_atomic(
- &s->stat_tx_drop, "tx_drop", "messages dropped undeliverable");
- nni_stat_set_unit(&s->stat_tx_drop, NNG_UNIT_MESSAGES);
- nni_sock_add_stat(sock, &s->stat_tx_drop);
-
- nni_stat_init_atomic(&s->stat_rx_malformed, "rx_malformed",
- "malformed messages received");
- nni_stat_set_unit(&s->stat_rx_malformed, NNG_UNIT_MESSAGES);
- nni_sock_add_stat(sock, &s->stat_rx_malformed);
+#ifdef NNG_ENABLE_STATS
+ static const nni_stat_info poly_info = {
+ .si_name = "poly",
+ .si_desc = "polyamorous mode?",
+ .si_type = NNG_STAT_BOOLEAN,
+ };
+ static const nni_stat_info raw_info = {
+ .si_name = "raw",
+ .si_desc = "raw mode?",
+ .si_type = NNG_STAT_BOOLEAN,
+ };
+ static const nni_stat_info mismatch_info = {
+ .si_name = "mismatch",
+ .si_desc = "pipes rejected (protocol mismatch)",
+ .si_type = NNG_STAT_COUNTER,
+ .si_atomic = true,
+ };
+ static const nni_stat_info already_info = {
+ .si_name = "already",
+ .si_desc = "pipes rejected (already connected)",
+ .si_type = NNG_STAT_COUNTER,
+ .si_atomic = true,
+ };
+ static const nni_stat_info ttl_drop_info = {
+ .si_name = "ttl_drop",
+ .si_desc = "messages dropped due to too many hops",
+ .si_type = NNG_STAT_COUNTER,
+ .si_unit = NNG_UNIT_MESSAGES,
+ .si_atomic = true,
+ };
+ static const nni_stat_info tx_drop_info = {
+ .si_name = "tx_drop",
+ .si_desc = "messages dropped undeliverable",
+ .si_type = NNG_STAT_COUNTER,
+ .si_unit = NNG_UNIT_MESSAGES,
+ .si_atomic = true,
+ };
+ static const nni_stat_info rx_malformed_info = {
+ .si_name = "rx_malformed",
+ .si_desc = "malformed messages received",
+ .si_type = NNG_STAT_COUNTER,
+ .si_unit = NNG_UNIT_MESSAGES,
+ .si_atomic = true,
+ };
+ static const nni_stat_info tx_malformed_info = {
+ .si_name = "tx_malformed",
+ .si_desc = "malformed messages not sent",
+ .si_type = NNG_STAT_COUNTER,
+ .si_unit = NNG_UNIT_MESSAGES,
+ .si_atomic = true,
+ };
+
+ pair1_add_sock_stat(s, &s->stat_poly, &poly_info);
+ pair1_add_sock_stat(s, &s->stat_raw, &raw_info);
+ pair1_add_sock_stat(s, &s->stat_reject_mismatch, &mismatch_info);
+ pair1_add_sock_stat(s, &s->stat_reject_already, &already_info);
+ pair1_add_sock_stat(s, &s->stat_ttl_drop, &ttl_drop_info);
+ pair1_add_sock_stat(s, &s->stat_tx_drop, &tx_drop_info);
+ pair1_add_sock_stat(s, &s->stat_rx_malformed, &rx_malformed_info);
- nni_stat_init_atomic(&s->stat_tx_malformed, "tx_malformed",
- "malformed messages not sent");
- nni_stat_set_unit(&s->stat_tx_malformed, NNG_UNIT_MESSAGES);
if (raw) {
// This stat only makes sense in raw mode.
- nni_sock_add_stat(sock, &s->stat_tx_malformed);
+ pair1_add_sock_stat(
+ s, &s->stat_tx_malformed, &tx_malformed_info);
}
- s->sock = sock;
- s->raw = raw;
- s->uwq = nni_sock_sendq(sock);
- s->urq = nni_sock_recvq(sock);
+ nni_stat_set_bool(&s->stat_raw, raw);
+ nni_stat_set_bool(&s->stat_poly, false);
+#endif
+
+ s->raw = raw;
+ s->uwq = nni_sock_sendq(sock);
+ s->urq = nni_sock_recvq(sock);
nni_atomic_init(&s->ttl);
nni_atomic_set(&s->ttl, 8);
diff --git a/src/protocol/pair1/pair1_poly.c b/src/protocol/pair1/pair1_poly.c
index fc1bbf6a..6c16745c 100644
--- a/src/protocol/pair1/pair1_poly.c
+++ b/src/protocol/pair1/pair1_poly.c
@@ -21,7 +21,11 @@
// THIS FEATURE IS DEPRECATED. We discourage use in new applications.
-#define BUMP_STAT(x) nni_stat_inc_atomic(x, 1)
+#ifdef NNG_ENABLE_STATS
+#define BUMP_STAT(x) nni_stat_inc(x, 1)
+#else
+#define BUMP_STAT(x)
+#endif
typedef struct pair1poly_pipe pair1poly_pipe;
typedef struct pair1poly_sock pair1poly_sock;
@@ -76,6 +80,16 @@ pair1poly_sock_fini(void *arg)
nni_mtx_fini(&s->mtx);
}
+#ifdef NNG_ENABLE_STATS
+static void
+pair1_add_sock_stat(
+ pair1poly_sock *s, nni_stat_item *item, const nni_stat_info *info)
+{
+ nni_stat_init(item, info);
+ nni_sock_add_stat(s->sock, item);
+}
+#endif
+
static int
pair1poly_sock_init(void *arg, nni_sock *sock)
{
@@ -83,49 +97,80 @@ pair1poly_sock_init(void *arg, nni_sock *sock)
nni_id_map_init(&s->pipes, 0, 0, false);
NNI_LIST_INIT(&s->plist, pair1poly_pipe, node);
+ s->sock = sock;
// Raw mode uses this.
nni_mtx_init(&s->mtx);
nni_aio_init(&s->aio_get, pair1poly_sock_get_cb, s);
- nni_stat_init_bool(
- &s->stat_poly, "polyamorous", "polyamorous mode?", true);
- nni_sock_add_stat(sock, &s->stat_poly);
-
- nni_stat_init_bool(&s->stat_raw, "raw", "raw mode?", false);
-
- nni_stat_init_atomic(&s->stat_reject_mismatch, "mismatch",
- "pipes rejected (protocol mismatch)");
- nni_sock_add_stat(sock, &s->stat_reject_mismatch);
-
- nni_stat_init_atomic(&s->stat_reject_already, "already",
- "pipes rejected (already connected)");
- nni_sock_add_stat(sock, &s->stat_reject_already);
-
- nni_stat_init_atomic(&s->stat_ttl_drop, "ttl_drop",
- "messages dropped due to too many hops");
- nni_stat_set_unit(&s->stat_ttl_drop, NNG_UNIT_MESSAGES);
- nni_sock_add_stat(sock, &s->stat_ttl_drop);
-
- // This can only increment in polyamorous mode.
- nni_stat_init_atomic(
- &s->stat_tx_drop, "tx_drop", "messages dropped undeliverable");
- nni_stat_set_unit(&s->stat_tx_drop, NNG_UNIT_MESSAGES);
- nni_sock_add_stat(sock, &s->stat_tx_drop);
-
- nni_stat_init_atomic(&s->stat_rx_malformed, "rx_malformed",
- "malformed messages received");
- nni_stat_set_unit(&s->stat_rx_malformed, NNG_UNIT_MESSAGES);
- nni_sock_add_stat(sock, &s->stat_rx_malformed);
-
- nni_stat_init_atomic(&s->stat_tx_malformed, "tx_malformed",
- "malformed messages not sent");
- nni_stat_set_unit(&s->stat_tx_malformed, NNG_UNIT_MESSAGES);
-
- s->sock = sock;
- s->uwq = nni_sock_sendq(sock);
- s->urq = nni_sock_recvq(sock);
+#ifdef NNG_ENABLE_STATS
+ static const nni_stat_info poly_info = {
+ .si_name = "poly",
+ .si_desc = "polyamorous mode?",
+ .si_type = NNG_STAT_BOOLEAN,
+ };
+ static const nni_stat_info raw_info = {
+ .si_name = "raw",
+ .si_desc = "raw mode?",
+ .si_type = NNG_STAT_BOOLEAN,
+ };
+ static const nni_stat_info mismatch_info = {
+ .si_name = "mismatch",
+ .si_desc = "pipes rejected (protocol mismatch)",
+ .si_type = NNG_STAT_COUNTER,
+ .si_atomic = true,
+ };
+ static const nni_stat_info already_info = {
+ .si_name = "already",
+ .si_desc = "pipes rejected (already connected)",
+ .si_type = NNG_STAT_COUNTER,
+ .si_atomic = true,
+ };
+ static const nni_stat_info ttl_drop_info = {
+ .si_name = "ttl_drop",
+ .si_desc = "messages dropped due to too many hops",
+ .si_type = NNG_STAT_COUNTER,
+ .si_unit = NNG_UNIT_MESSAGES,
+ .si_atomic = true,
+ };
+ static const nni_stat_info tx_drop_info = {
+ .si_name = "tx_drop",
+ .si_desc = "messages dropped undeliverable",
+ .si_type = NNG_STAT_COUNTER,
+ .si_unit = NNG_UNIT_MESSAGES,
+ .si_atomic = true,
+ };
+ static const nni_stat_info rx_malformed_info = {
+ .si_name = "rx_malformed",
+ .si_desc = "malformed messages received",
+ .si_type = NNG_STAT_COUNTER,
+ .si_unit = NNG_UNIT_MESSAGES,
+ .si_atomic = true,
+ };
+ static const nni_stat_info tx_malformed_info = {
+ .si_name = "tx_malformed",
+ .si_desc = "malformed messages not sent",
+ .si_type = NNG_STAT_COUNTER,
+ .si_unit = NNG_UNIT_MESSAGES,
+ .si_atomic = true,
+ };
+
+ pair1_add_sock_stat(s, &s->stat_poly, &poly_info);
+ pair1_add_sock_stat(s, &s->stat_raw, &raw_info);
+ pair1_add_sock_stat(s, &s->stat_reject_mismatch, &mismatch_info);
+ pair1_add_sock_stat(s, &s->stat_reject_already, &already_info);
+ pair1_add_sock_stat(s, &s->stat_ttl_drop, &ttl_drop_info);
+ pair1_add_sock_stat(s, &s->stat_tx_drop, &tx_drop_info);
+ pair1_add_sock_stat(s, &s->stat_rx_malformed, &rx_malformed_info);
+ pair1_add_sock_stat(s, &s->stat_tx_malformed, &tx_malformed_info);
+
+ nni_stat_set_bool(&s->stat_raw, false);
+ nni_stat_set_bool(&s->stat_poly, true);
+#endif
+
+ s->uwq = nni_sock_sendq(sock);
+ s->urq = nni_sock_recvq(sock);
nni_atomic_init(&s->ttl);
nni_atomic_set(&s->ttl, 8);
diff --git a/src/transport/ipc/ipc.c b/src/transport/ipc/ipc.c
index 16fbc42b..ea135ad8 100644
--- a/src/transport/ipc/ipc.c
+++ b/src/transport/ipc/ipc.c
@@ -70,7 +70,9 @@ struct ipc_ep {
nni_list wait_pipes; // pipes waiting to match to socket
nni_list neg_pipes; // pipes busy negotiating
nni_reap_item reap;
- nni_stat_item st_rcv_max;
+#ifdef NNG_ENABLE_STATS
+ nni_stat_item st_rcv_max;
+#endif
};
static void ipc_pipe_send_start(ipc_pipe *p);
@@ -807,9 +809,16 @@ ipc_ep_init(ipc_ep **epp, nni_sock *sock)
ep->proto = nni_sock_proto_id(sock);
- nni_stat_init(&ep->st_rcv_max, "rcvmaxsz", "maximum receive size");
- nni_stat_set_type(&ep->st_rcv_max, NNG_STAT_LEVEL);
- nni_stat_set_unit(&ep->st_rcv_max, NNG_UNIT_BYTES);
+#ifdef NNG_ENABLE_STATS
+ static const nni_stat_info rcv_max_info = {
+ .si_name = "rcv_max",
+ .si_desc = "maximum receive size",
+ .si_type = NNG_STAT_LEVEL,
+ .si_unit = NNG_UNIT_BYTES,
+ .si_atomic = true,
+ };
+ nni_stat_init(&ep->st_rcv_max, &rcv_max_info);
+#endif
*epp = ep;
return (0);
@@ -831,8 +840,9 @@ ipc_ep_init_dialer(void **dp, nni_url *url, nni_dialer *dialer)
ipc_ep_fini(ep);
return (rv);
}
-
+#ifdef NNG_ENABLE_STATS
nni_dialer_add_stat(dialer, &ep->st_rcv_max);
+#endif
*dp = ep;
return (0);
}
@@ -855,7 +865,9 @@ ipc_ep_init_listener(void **dp, nni_url *url, nni_listener *listener)
return (rv);
}
+#ifdef NNG_ENABLE_STATS
nni_listener_add_stat(listener, &ep->st_rcv_max);
+#endif
*dp = ep;
return (0);
}
@@ -934,8 +946,10 @@ ipc_ep_set_recv_max_sz(void *arg, const void *v, size_t sz, nni_type t)
NNI_LIST_FOREACH (&ep->busy_pipes, p) {
p->rcv_max = val;
}
- nni_stat_set_value(&ep->st_rcv_max, val);
nni_mtx_unlock(&ep->mtx);
+#ifdef NNG_ENABLE_STATS
+ nni_stat_set_value(&ep->st_rcv_max, val);
+#endif
}
return (rv);
}
diff --git a/src/transport/tcp/tcp.c b/src/transport/tcp/tcp.c
index c978b279..02bc078e 100644
--- a/src/transport/tcp/tcp.c
+++ b/src/transport/tcp/tcp.c
@@ -68,7 +68,10 @@ struct tcptran_ep {
nni_reap_item reap;
nng_stream_dialer * dialer;
nng_stream_listener *listener;
- nni_stat_item st_rcvmaxsz;
+
+#ifdef NNG_ENABLE_STATS
+ nni_stat_item st_rcv_max;
+#endif
};
static void tcptran_pipe_send_start(tcptran_pipe *);
@@ -173,7 +176,8 @@ tcptran_pipe_alloc(tcptran_pipe **pipep)
nni_mtx_init(&p->mtx);
if (((rv = nni_aio_alloc(&p->txaio, tcptran_pipe_send_cb, p)) != 0) ||
((rv = nni_aio_alloc(&p->rxaio, tcptran_pipe_recv_cb, p)) != 0) ||
- ((rv = nni_aio_alloc(&p->negoaio, tcptran_pipe_nego_cb, p)) != 0)) {
+ ((rv = nni_aio_alloc(&p->negoaio, tcptran_pipe_nego_cb, p)) !=
+ 0)) {
tcptran_pipe_fini(p);
return (rv);
}
@@ -857,9 +861,16 @@ tcptran_ep_init(tcptran_ep **epp, nng_url *url, nni_sock *sock)
ep->proto = nni_sock_proto_id(sock);
ep->url = url;
- nni_stat_init(&ep->st_rcvmaxsz, "rcvmaxsz", "maximum receive size");
- nni_stat_set_type(&ep->st_rcvmaxsz, NNG_STAT_LEVEL);
- nni_stat_set_unit(&ep->st_rcvmaxsz, NNG_UNIT_BYTES);
+#ifdef NNG_ENABLE_STATS
+ static const nni_stat_info rcv_max_info = {
+ .si_name = "rcv_max",
+ .si_desc = "maximum receive size",
+ .si_type = NNG_STAT_LEVEL,
+ .si_unit = NNG_UNIT_BYTES,
+ .si_atomic = true,
+ };
+ nni_stat_init(&ep->st_rcv_max, &rcv_max_info);
+#endif
*epp = ep;
return (0);
@@ -905,7 +916,9 @@ tcptran_dialer_init(void **dp, nng_url *url, nni_dialer *ndialer)
return (rv);
}
- nni_dialer_add_stat(ndialer, &ep->st_rcvmaxsz);
+#ifdef NNG_ENABLE_STATS
+ nni_dialer_add_stat(ndialer, &ep->st_rcv_max);
+#endif
*dp = ep;
return (0);
}
@@ -936,7 +949,9 @@ tcptran_listener_init(void **lp, nng_url *url, nni_listener *nlistener)
tcptran_ep_fini(ep);
return (rv);
}
- nni_listener_add_stat(nlistener, &ep->st_rcvmaxsz);
+#ifdef NNG_ENABLE_STATS
+ nni_listener_add_stat(nlistener, &ep->st_rcv_max);
+#endif
*lp = ep;
return (0);
@@ -1036,8 +1051,10 @@ tcptran_ep_set_recvmaxsz(void *arg, const void *v, size_t sz, nni_opt_type t)
NNI_LIST_FOREACH (&ep->busypipes, p) {
p->rcvmax = val;
}
- nni_stat_set_value(&ep->st_rcvmaxsz, val);
nni_mtx_unlock(&ep->mtx);
+#ifdef NNG_ENABLE_STATS
+ nni_stat_set_value(&ep->st_rcv_max, val);
+#endif
}
return (rv);
}
diff --git a/src/transport/tls/tls.c b/src/transport/tls/tls.c
index b9fa064e..ae5d86ec 100644
--- a/src/transport/tls/tls.c
+++ b/src/transport/tls/tls.c
@@ -78,7 +78,7 @@ struct tlstran_ep {
const char * host;
nng_sockaddr src;
nng_sockaddr sa;
- nni_stat_item st_rcvmaxsz;
+ nni_stat_item st_rcv_max;
};
static void tlstran_pipe_send_start(tlstran_pipe *);
@@ -833,9 +833,16 @@ tlstran_ep_init(tlstran_ep **epp, nng_url *url, nni_sock *sock)
ep->proto = nni_sock_proto_id(sock);
ep->url = url;
- nni_stat_init(&ep->st_rcvmaxsz, "rcvmaxsz", "maximum receive size");
- nni_stat_set_type(&ep->st_rcvmaxsz, NNG_STAT_LEVEL);
- nni_stat_set_unit(&ep->st_rcvmaxsz, NNG_UNIT_BYTES);
+#ifdef NNG_ENABLE_STATS
+ static const nni_stat_info rcv_max_info = {
+ .si_name = "rcv_max",
+ .si_desc = "maximum receive size",
+ .si_type = NNG_STAT_LEVEL,
+ .si_unit = NNG_UNIT_BYTES,
+ .si_atomic = true,
+ };
+ nni_stat_init(&ep->st_rcv_max, &rcv_max_info);
+#endif
*epp = ep;
return (0);
@@ -881,7 +888,9 @@ tlstran_ep_init_dialer(void **dp, nni_url *url, nni_dialer *ndialer)
tlstran_ep_fini(ep);
return (rv);
}
- nni_dialer_add_stat(ndialer, &ep->st_rcvmaxsz);
+#ifdef NNG_ENABLE_STATS
+ nni_dialer_add_stat(ndialer, &ep->st_rcv_max);
+#endif
*dp = ep;
return (0);
}
@@ -949,8 +958,9 @@ tlstran_ep_init_listener(void **lp, nni_url *url, nni_listener *nlistener)
tlstran_ep_fini(ep);
return (rv);
}
-
- nni_listener_add_stat(nlistener, &ep->st_rcvmaxsz);
+#ifdef NNG_ENABLE_STATS
+ nni_listener_add_stat(nlistener, &ep->st_rcv_max);
+#endif
*lp = ep;
return (0);
}
@@ -1066,9 +1076,10 @@ tlstran_ep_set_recvmaxsz(void *arg, const void *v, size_t sz, nni_type t)
NNI_LIST_FOREACH (&ep->busypipes, p) {
p->rcvmax = val;
}
- nni_stat_set_value(&ep->st_rcvmaxsz, val);
-
nni_mtx_unlock(&ep->mtx);
+#ifdef NNG_ENABLE_STATS
+ nni_stat_set_value(&ep->st_rcv_max, val);
+#endif
}
return (rv);
}