aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2021-12-05 22:11:24 -0500
committerGarrett D'Amore <garrett@damore.org>2021-12-05 23:04:45 -0500
commitc9bbe8eb574fe10ff16cc71a23fcc9b31fb8ed04 (patch)
tree3a135bbee8750cc1b1869cfca6a2e6f24bf8e59c
parenteee06d1e8365ea1b1aa9363a3c6445745b002324 (diff)
downloadnng-c9bbe8eb574fe10ff16cc71a23fcc9b31fb8ed04.tar.gz
nng-c9bbe8eb574fe10ff16cc71a23fcc9b31fb8ed04.tar.bz2
nng-c9bbe8eb574fe10ff16cc71a23fcc9b31fb8ed04.zip
Use static initialization for lists and mutexes.
This eliminates some run-time initialization, moving it to compile time. Additional follow up work will expand on this to simplify initialization and reduce the need for certain locks.
-rw-r--r--src/core/dialer.c4
-rw-r--r--src/core/idhash.h26
-rw-r--r--src/core/init.c47
-rw-r--r--src/core/init.h19
-rw-r--r--src/core/list.h10
-rw-r--r--src/core/listener.c4
-rw-r--r--src/core/socket.c20
-rw-r--r--src/core/stats.c29
-rw-r--r--src/platform/posix/posix_impl.h6
-rw-r--r--src/platform/posix/posix_thread.c2
-rw-r--r--src/platform/windows/win_impl.h6
-rw-r--r--src/platform/windows/win_thread.c2
-rw-r--r--src/sp/transport.c9
-rw-r--r--src/supplemental/http/http_client.c30
-rw-r--r--src/supplemental/http/http_server.c31
-rw-r--r--src/supplemental/tls/tls_common.c1
16 files changed, 65 insertions, 181 deletions
diff --git a/src/core/dialer.c b/src/core/dialer.c
index 3a749085..e3f435db 100644
--- a/src/core/dialer.c
+++ b/src/core/dialer.c
@@ -21,20 +21,18 @@ static void dialer_connect_cb(void *);
static void dialer_timer_cb(void *);
static nni_id_map dialers;
-static nni_mtx dialers_lk;
+static nni_mtx dialers_lk = NNI_MTX_INITIALIZER;
void
nni_dialer_sys_init(void)
{
nni_id_map_init(&dialers, 1, 0x7fffffff, false);
- nni_mtx_init(&dialers_lk);
}
void
nni_dialer_sys_fini(void)
{
nni_reap_drain();
- nni_mtx_fini(&dialers_lk);
nni_id_map_fini(&dialers);
}
diff --git a/src/core/idhash.h b/src/core/idhash.h
index 0c9043ce..b2259853 100644
--- a/src/core/idhash.h
+++ b/src/core/idhash.h
@@ -1,5 +1,5 @@
//
-// Copyright 2020 Staysail Systems, Inc. <info@staysail.tech>
+// Copyright 2021 Staysail Systems, Inc. <info@staysail.tech>
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
//
// This software is supplied under the terms of the MIT License, a
@@ -23,28 +23,28 @@
// use table sizes that are powers of two. Note that hash items
// must be non-NULL. The table is protected by an internal lock.
-typedef struct nni_id_map nni_id_map;
-typedef struct nni_id_entry nni_id_entry;
+typedef struct nni_id_map nni_id_map;
+typedef struct nni_id_entry nni_id_entry;
// NB: These details are entirely private to the hash implementation.
// They are provided here to facilitate inlining in structures.
struct nni_id_map {
- size_t id_cap;
- size_t id_count;
- size_t id_load;
- size_t id_min_load; // considers placeholders
- size_t id_max_load;
+ uint32_t id_cap;
+ uint32_t id_count;
+ uint32_t id_load;
+ uint32_t id_min_load; // considers placeholders
+ uint32_t id_max_load;
uint32_t id_min_val;
uint32_t id_max_val;
uint32_t id_dyn_val;
nni_id_entry *id_entries;
};
-extern void nni_id_map_init(nni_id_map *, uint32_t, uint32_t, bool);
-extern void nni_id_map_fini(nni_id_map *);
+extern void nni_id_map_init(nni_id_map *, uint32_t, uint32_t, bool);
+extern void nni_id_map_fini(nni_id_map *);
extern void *nni_id_get(nni_id_map *, uint32_t);
-extern int nni_id_set(nni_id_map *, uint32_t, void *);
-extern int nni_id_alloc(nni_id_map *, uint32_t *, void *);
-extern int nni_id_remove(nni_id_map *, uint32_t);
+extern int nni_id_set(nni_id_map *, uint32_t, void *);
+extern int nni_id_alloc(nni_id_map *, uint32_t *, void *);
+extern int nni_id_remove(nni_id_map *, uint32_t);
#endif // CORE_IDHASH_H
diff --git a/src/core/init.c b/src/core/init.c
index c923fdf0..f9dee9e2 100644
--- a/src/core/init.c
+++ b/src/core/init.c
@@ -14,21 +14,16 @@
#include <stdio.h>
#include <stdlib.h>
-static nni_mtx nni_init_mtx;
-static nni_list nni_init_list;
-static bool nni_inited = false;
-
-extern int nni_tls_sys_init(void);
+extern int nni_tls_sys_init(void);
extern void nni_tls_sys_fini(void);
+static bool nni_inited = false;
+
static int
nni_init_helper(void)
{
int rv;
- nni_mtx_init(&nni_init_mtx);
- NNI_LIST_INIT(&nni_init_list, nni_initializer, i_node);
- nni_inited = true;
#ifdef NNG_TEST_LIB
static bool cleanup = false;
if (!cleanup) {
@@ -54,6 +49,8 @@ nni_init_helper(void)
nni_pipe_sys_init();
nni_sp_tran_sys_init();
+ nni_inited = true;
+
return (0);
}
@@ -69,19 +66,6 @@ nni_fini(void)
if (!nni_inited) {
return;
}
- if (!nni_list_empty(&nni_init_list)) {
- nni_initializer *init;
-
- nni_mtx_lock(&nni_init_mtx);
- while ((init = nni_list_first(&nni_init_list)) != NULL) {
- if (init->i_fini != NULL) {
- init->i_fini();
- }
- init->i_once = 0;
- nni_list_remove(&nni_init_list, init);
- }
- nni_mtx_unlock(&nni_init_mtx);
- }
nni_sp_tran_sys_fini();
nni_tls_sys_fini();
nni_pipe_sys_fini();
@@ -95,27 +79,6 @@ nni_fini(void)
nni_reap_sys_fini(); // must be before timer and aio (expire)
nni_stat_sys_fini();
- nni_mtx_fini(&nni_init_mtx);
nni_plat_fini();
nni_inited = false;
}
-
-int
-nni_initialize(nni_initializer *init)
-{
- int rv;
- if (init->i_once) {
- return (0);
- }
- nni_mtx_lock(&nni_init_mtx);
- if (init->i_once) {
- nni_mtx_unlock(&nni_init_mtx);
- return (0);
- }
- if ((rv = init->i_init()) == 0) {
- init->i_once = 1;
- nni_list_append(&nni_init_list, init);
- }
- nni_mtx_unlock(&nni_init_mtx);
- return (rv);
-}
diff --git a/src/core/init.h b/src/core/init.h
index d21bb4c5..7875ba4c 100644
--- a/src/core/init.h
+++ b/src/core/init.h
@@ -23,23 +23,4 @@ int nni_init(void);
// that all resources used by the library are released back to the system.
void nni_fini(void);
-typedef struct nni_initializer {
- int (*i_init)(void); // i_init is called exactly once
- void (*i_fini)(void); // i_fini is called on shutdown
- int i_once; // private -- initialize to zero
- nni_list_node i_node; // private -- initialize to zero
-} nni_initializer;
-
-// nni_initialize will call the initialization routine exactly once. This is
-// done efficiently, so that if the caller has initialized already, then
-// subsequent calls are "cheap" (no synchronization cost). The initialization
-// function must not itself cause any further calls to nni_initialize; the
-// function should limit itself to initialization of locks and static data
-// structures. When shutting down, the finalizer will be called. The
-// order in which finalizers are called is unspecified.
-//
-// An initializer may fail (due to resource exhaustion), in which case the
-// return value of nni_initialize will be non-zero.
-int nni_initialize(nni_initializer *);
-
#endif // CORE_INIT_H
diff --git a/src/core/list.h b/src/core/list.h
index 204057a2..d3c703bb 100644
--- a/src/core/list.h
+++ b/src/core/list.h
@@ -29,6 +29,16 @@ extern void nni_list_init_offset(nni_list *list, size_t offset);
#define NNI_LIST_INIT(list, type, field) \
nni_list_init_offset(list, offsetof(type, field))
+// NNI_LIST_INITIALIZER is used to initialize structures at declaration time.
+// The list argument is the structure being initialized and the type and
+// offset determine where the node lives within each item.
+#define NNI_LIST_INITIALIZER(list, type, field) \
+ { \
+ .ll_head.ln_next = &(list).ll_head, \
+ .ll_head.ln_prev = &(list).ll_head, \
+ .ll_offset = offsetof(type, field) \
+ }
+
#define NNI_LIST_NODE_INIT(node) \
do { \
(node)->ln_prev = (node)->ln_next = 0; \
diff --git a/src/core/listener.c b/src/core/listener.c
index 74e5e22b..4d4a4e24 100644
--- a/src/core/listener.c
+++ b/src/core/listener.c
@@ -22,20 +22,18 @@ static void listener_accept_cb(void *);
static void listener_timer_cb(void *);
static nni_id_map listeners;
-static nni_mtx listeners_lk;
+static nni_mtx listeners_lk = NNI_MTX_INITIALIZER;
void
nni_listener_sys_init(void)
{
nni_id_map_init(&listeners, 1, 0x7fffffff, false);
- nni_mtx_init(&listeners_lk);
}
void
nni_listener_sys_fini(void)
{
nni_reap_drain();
- nni_mtx_fini(&listeners_lk);
nni_id_map_fini(&listeners);
}
diff --git a/src/core/socket.c b/src/core/socket.c
index 6c43e43d..d9ac12b6 100644
--- a/src/core/socket.c
+++ b/src/core/socket.c
@@ -16,12 +16,6 @@
// Socket implementation.
-static nni_list sock_list;
-static nni_id_map sock_ids;
-static nni_mtx sock_lk;
-static nni_id_map ctx_ids;
-static bool inited;
-
struct nni_ctx {
nni_list_node c_node;
nni_sock *c_sock;
@@ -107,6 +101,11 @@ struct nni_socket {
#endif
};
+static nni_list sock_list = NNI_LIST_INITIALIZER(sock_list, nni_sock, s_node);
+static nni_mtx sock_lk = NNI_MTX_INITIALIZER;
+static nni_id_map sock_ids;
+static nni_id_map ctx_ids;
+
static void nni_ctx_destroy(nni_ctx *);
#define SOCK(s) ((nni_sock *) (s))
@@ -611,12 +610,8 @@ nni_sock_create(nni_sock **sp, const nni_proto *proto)
void
nni_sock_sys_init(void)
{
- NNI_LIST_INIT(&sock_list, nni_sock, s_node);
- nni_mtx_init(&sock_lk);
-
nni_id_map_init(&sock_ids, 1, 0x7fffffff, false);
nni_id_map_init(&ctx_ids, 1, 0x7fffffff, false);
- inited = true;
}
void
@@ -624,8 +619,6 @@ nni_sock_sys_fini(void)
{
nni_id_map_fini(&sock_ids);
nni_id_map_fini(&ctx_ids);
- nni_mtx_fini(&sock_lk);
- inited = false;
}
int
@@ -822,9 +815,6 @@ nni_sock_closeall(void)
{
nni_sock *s;
- if (!inited) {
- return;
- }
for (;;) {
nni_mtx_lock(&sock_lk);
if ((s = nni_list_first(&sock_list)) == NULL) {
diff --git a/src/core/stats.c b/src/core/stats.c
index e4765078..f7e52fb0 100644
--- a/src/core/stats.c
+++ b/src/core/stats.c
@@ -19,21 +19,21 @@ struct nng_stat {
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_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;
+ char *sv_string;
} s_val;
};
#ifdef NNG_ENABLE_STATS
static nni_stat_item stats_root;
-static nni_mtx stats_lock;
-static nni_mtx stats_val_lock;
+static nni_mtx stats_lock = NNI_MTX_INITIALIZER;
+static nni_mtx stats_val_lock = NNI_MTX_INITIALIZER;
#endif
void
@@ -171,7 +171,7 @@ nni_stat_set_string(nni_stat_item *item, const char *s)
{
#ifdef NNG_ENABLE_STATS
const nni_stat_info *info = item->si_info;
- char * old = item->si_u.sv_string;
+ char *old = item->si_u.sv_string;
nni_mtx_lock(&stats_val_lock);
if ((s != NULL) && (old != NULL) && (strcmp(s, old) == 0)) {
@@ -235,7 +235,7 @@ nng_stats_free(nni_stat *st)
static int
stat_make_tree(nni_stat_item *item, nni_stat **sp)
{
- nni_stat * stat;
+ nni_stat *stat;
nni_stat_item *child;
if ((stat = NNI_ALLOC_STRUCT(stat)) == NULL) {
@@ -266,8 +266,8 @@ stat_update(nni_stat *stat)
{
const nni_stat_item *item = stat->s_item;
const nni_stat_info *info = item->si_info;
- char * old;
- char * str;
+ char *old;
+ char *str;
switch (info->si_type) {
case NNG_STAT_SCOPE:
@@ -397,7 +397,6 @@ nng_stat_bool(nni_stat *stat)
return (stat->s_val.sv_bool);
}
-
const char *
nng_stat_string(nng_stat *stat)
{
@@ -498,8 +497,6 @@ nni_stat_sys_init(void)
.si_desc = "all statistics",
.si_type = NNG_STAT_SCOPE,
};
- nni_mtx_init(&stats_lock);
- nni_mtx_init(&stats_val_lock);
nni_stat_init(&stats_root, &root);
#endif
return (0);
@@ -508,10 +505,6 @@ nni_stat_sys_init(void)
void
nni_stat_sys_fini(void)
{
-#ifdef NNG_ENABLE_STATS
- nni_mtx_fini(&stats_lock);
- nni_mtx_fini(&stats_val_lock);
-#endif
}
#ifdef NNG_ENABLE_STATS
@@ -538,10 +531,10 @@ nng_stats_dump(nng_stat *stat)
#ifdef NNG_ENABLE_STATS
static char buf[128]; // to minimize recursion, not thread safe
int len;
- char * scope;
- char * indent = " ";
+ char *scope;
+ char *indent = " ";
unsigned long long val;
- nni_stat * child;
+ nni_stat *child;
switch (nng_stat_type(stat)) {
case NNG_STAT_SCOPE:
diff --git a/src/platform/posix/posix_impl.h b/src/platform/posix/posix_impl.h
index 234d1501..97924a45 100644
--- a/src/platform/posix/posix_impl.h
+++ b/src/platform/posix/posix_impl.h
@@ -58,10 +58,16 @@ struct nni_plat_mtx {
pthread_mutex_t mtx;
};
+#define NNI_MTX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER }
+
struct nni_rwlock {
pthread_rwlock_t rwl;
};
+#define NNI_RWLOCK_INITIALIZER { PTHREAD_RWLOCK_INITIALIZER }
+
+// No static form of CV initialization because of the need to use
+// attributes to set the clock type.
struct nni_plat_cv {
pthread_cond_t cv;
nni_plat_mtx *mtx;
diff --git a/src/platform/posix/posix_thread.c b/src/platform/posix/posix_thread.c
index c47bcec6..b7cd5e1e 100644
--- a/src/platform/posix/posix_thread.c
+++ b/src/platform/posix/posix_thread.c
@@ -34,7 +34,7 @@
#endif
static pthread_mutex_t nni_plat_init_lock = PTHREAD_MUTEX_INITIALIZER;
-static int nni_plat_inited = 0;
+static volatile int nni_plat_inited = 0;
static int nni_plat_forked = 0;
pthread_condattr_t nni_cvattr;
diff --git a/src/platform/windows/win_impl.h b/src/platform/windows/win_impl.h
index 608a065e..b3c08edf 100644
--- a/src/platform/windows/win_impl.h
+++ b/src/platform/windows/win_impl.h
@@ -37,15 +37,17 @@ struct nni_plat_thr {
struct nni_plat_mtx {
SRWLOCK srl;
- DWORD owner;
- int init;
};
+#define NNI_MTX_INITIALIZER { SRWLOCK_INIT }
+
struct nni_rwlock {
SRWLOCK rwl;
BOOLEAN exclusive;
};
+#define NNI_RWLOCK_INITIALIZER { SRWLOCK_INIT }
+
struct nni_plat_cv {
CONDITION_VARIABLE cv;
PSRWLOCK srl;
diff --git a/src/platform/windows/win_thread.c b/src/platform/windows/win_thread.c
index 31e783a3..b131c067 100644
--- a/src/platform/windows/win_thread.c
+++ b/src/platform/windows/win_thread.c
@@ -55,13 +55,11 @@ void
nni_plat_mtx_init(nni_plat_mtx *mtx)
{
InitializeSRWLock(&mtx->srl);
- mtx->init = 1;
}
void
nni_plat_mtx_fini(nni_plat_mtx *mtx)
{
- mtx->init = 0;
}
void
diff --git a/src/sp/transport.c b/src/sp/transport.c
index ed27ebeb..9f4c6522 100644
--- a/src/sp/transport.c
+++ b/src/sp/transport.c
@@ -14,8 +14,9 @@
#include <stdio.h>
#include <string.h>
-static nni_list sp_tran_list;
-static nni_rwlock sp_tran_lk;
+static nni_list sp_tran_list =
+ NNI_LIST_INITIALIZER(sp_tran_list, nni_sp_tran, tran_link);
+static nni_rwlock sp_tran_lk = NNI_RWLOCK_INITIALIZER;
void
nni_sp_tran_register(nni_sp_tran *tran)
@@ -73,9 +74,6 @@ extern void nni_sp_zt_register(void);
void
nni_sp_tran_sys_init(void)
{
- NNI_LIST_INIT(&sp_tran_list, nni_sp_tran, tran_link);
- nni_rwlock_init(&sp_tran_lk);
-
#ifdef NNG_TRANSPORT_INPROC
nni_sp_inproc_register();
#endif
@@ -110,5 +108,4 @@ nni_sp_tran_sys_fini(void)
nni_list_remove(&sp_tran_list, t);
t->tran_fini();
}
- nni_rwlock_fini(&sp_tran_lk);
}
diff --git a/src/supplemental/http/http_client.c b/src/supplemental/http/http_client.c
index 3737cb7b..b156794c 100644
--- a/src/supplemental/http/http_client.c
+++ b/src/supplemental/http/http_client.c
@@ -1,5 +1,5 @@
//
-// Copyright 2020 Staysail Systems, Inc. <info@staysail.tech>
+// Copyright 2021 Staysail Systems, Inc. <info@staysail.tech>
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
// Copyright 2019 Devolutions <info@devolutions.net>
//
@@ -19,7 +19,7 @@
#include "http_api.h"
-static nni_mtx http_txn_lk;
+static nni_mtx http_txn_lk = NNI_MTX_INITIALIZER;
struct nng_http_client {
nni_list aios;
@@ -198,15 +198,6 @@ nni_http_client_connect(nni_http_client *c, nni_aio *aio)
nni_mtx_unlock(&c->mtx);
}
-static int http_client_sys_init(void);
-static void http_client_sys_fini(void);
-
-static nni_initializer http_client_initializer = {
- .i_init = http_client_sys_init,
- .i_fini = http_client_sys_fini,
- .i_once = 0,
-};
-
typedef enum http_txn_state {
HTTP_CONNECTING,
HTTP_SENDING,
@@ -385,8 +376,6 @@ nni_http_transact_conn(
http_txn *txn;
int rv;
- nni_initialize(&http_client_initializer);
-
if (nni_aio_begin(aio) != 0) {
return;
}
@@ -430,8 +419,6 @@ nni_http_transact(nni_http_client *client, nni_http_req *req,
http_txn *txn;
int rv;
- nni_initialize(&http_client_initializer);
-
if (nni_aio_begin(aio) != 0) {
return;
}
@@ -470,16 +457,3 @@ nni_http_transact(nni_http_client *client, nni_http_req *req,
nni_http_client_connect(client, txn->aio);
nni_mtx_unlock(&http_txn_lk);
}
-
-static int
-http_client_sys_init(void)
-{
- nni_mtx_init(&http_txn_lk);
- return (0);
-}
-
-static void
-http_client_sys_fini(void)
-{
- nni_mtx_fini(&http_txn_lk);
-}
diff --git a/src/supplemental/http/http_server.c b/src/supplemental/http/http_server.c
index 7f6f9abe..b7e7ac80 100644
--- a/src/supplemental/http/http_server.c
+++ b/src/supplemental/http/http_server.c
@@ -22,15 +22,6 @@
#include "http_api.h"
-static int http_server_sys_init(void);
-static void http_server_sys_fini(void);
-
-static nni_initializer http_server_initializer = {
- .i_init = http_server_sys_init,
- .i_fini = http_server_sys_fini,
- .i_once = 0,
-};
-
struct nng_http_handler {
nni_list_node node;
char * uri;
@@ -279,8 +270,9 @@ nni_http_handler_set_method(nni_http_handler *h, const char *method)
return (0);
}
-static nni_list http_servers;
-static nni_mtx http_servers_lk;
+static nni_list http_servers =
+ NNI_LIST_INITIALIZER(http_servers, nni_http_server, node);
+static nni_mtx http_servers_lk = NNI_MTX_INITIALIZER;
static void
http_sc_reap(void *arg)
@@ -1001,8 +993,6 @@ nni_http_server_init(nni_http_server **serverp, const nni_url *url)
int rv;
nni_http_server *s;
- nni_initialize(&http_server_initializer);
-
nni_mtx_lock(&http_servers_lk);
NNI_LIST_FOREACH (&http_servers, s) {
if ((!s->closed) && (atoi(url->u_port) == s->port) &&
@@ -1924,18 +1914,3 @@ nni_http_server_fini(nni_http_server *s)
}
nni_mtx_unlock(&http_servers_lk);
}
-
-static int
-http_server_sys_init(void)
-{
- NNI_LIST_INIT(&http_servers, nni_http_server, node);
- nni_mtx_init(&http_servers_lk);
- return (0);
-}
-
-static void
-http_server_sys_fini(void)
-{
- nni_reap_drain();
- nni_mtx_fini(&http_servers_lk);
-}
diff --git a/src/supplemental/tls/tls_common.c b/src/supplemental/tls/tls_common.c
index 3e497b0c..357c8411 100644
--- a/src/supplemental/tls/tls_common.c
+++ b/src/supplemental/tls/tls_common.c
@@ -1495,7 +1495,6 @@ nni_tls_sys_init(void)
void
nni_tls_sys_fini(void)
{
- nni_reap_drain();
NNG_TLS_ENGINE_FINI();
}