aboutsummaryrefslogtreecommitdiff
path: root/src/core/init.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/init.c')
-rw-r--r--src/core/init.c52
1 files changed, 52 insertions, 0 deletions
diff --git a/src/core/init.c b/src/core/init.c
index 4a7fd974..cb6dbeee 100644
--- a/src/core/init.c
+++ b/src/core/init.c
@@ -1,6 +1,7 @@
//
// Copyright 2017 Garrett D'Amore <garrett@damore.org>
// Copyright 2017 Capitar IT Group BV <info@capitar.com>
+// Copyright 2017 Staysail Systems, Inc. <info@staysail.tech>
//
// This software is supplied under the terms of the MIT License, a
// copy of which should be located in the distribution where this
@@ -10,15 +11,25 @@
#include "core/nng_impl.h"
+#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
+static nni_mtx nni_init_mtx;
+static nni_list nni_init_list;
+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;
+
if (((rv = nni_taskq_sys_init()) != 0) ||
+ ((rv = nni_reap_sys_init()) != 0) ||
((rv = nni_timer_sys_init()) != 0) ||
((rv = nni_aio_sys_init()) != 0) ||
((rv = nni_random_sys_init()) != 0) ||
@@ -29,6 +40,7 @@ nni_init_helper(void)
((rv = nni_tran_sys_init()) != 0)) {
nni_fini();
}
+
return (rv);
}
@@ -41,14 +53,54 @@ nni_init(void)
void
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_tran_sys_fini();
nni_proto_sys_fini();
nni_pipe_sys_fini();
nni_ep_sys_fini();
nni_sock_sys_fini();
nni_random_sys_fini();
+ nni_reap_sys_fini(); // must be before timer and aio (expire)
nni_aio_sys_fini();
nni_timer_sys_fini();
nni_taskq_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);
}