aboutsummaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2017-08-07 16:12:41 -0700
committerGarrett D'Amore <garrett@damore.org>2017-08-07 16:12:41 -0700
commit22d991fda77578dd03c8d477f8427631e6383cee (patch)
treec81eb35a13fbeb1dab8f8e6ca62dc8ccf42636e0 /src/core
parentc5354ea49184a359df8d477e844b1c52aeb234d5 (diff)
downloadnng-22d991fda77578dd03c8d477f8427631e6383cee.tar.gz
nng-22d991fda77578dd03c8d477f8427631e6383cee.tar.bz2
nng-22d991fda77578dd03c8d477f8427631e6383cee.zip
Subsystem initialize is idempotent; simplify cleanup.
Diffstat (limited to 'src/core')
-rw-r--r--src/core/aio.c15
-rw-r--r--src/core/endpt.c2
-rw-r--r--src/core/init.c48
-rw-r--r--src/core/pipe.c2
-rw-r--r--src/core/taskq.c28
-rw-r--r--src/core/timer.c17
-rw-r--r--src/core/transport.c18
-rw-r--r--src/core/transport.h2
8 files changed, 56 insertions, 76 deletions
diff --git a/src/core/aio.c b/src/core/aio.c
index 792b63f2..273ce22e 100644
--- a/src/core/aio.c
+++ b/src/core/aio.c
@@ -14,7 +14,7 @@
static nni_mtx nni_aio_lk;
// These are used for expiration.
static nni_cv nni_aio_expire_cv;
-static int nni_aio_expire_exit;
+static int nni_aio_expire_run;
static nni_thr nni_aio_expire_thr;
static nni_list nni_aio_expire_aios;
@@ -295,7 +295,7 @@ nni_aio_expire_loop(void *arg)
for (;;) {
nni_mtx_lock(&nni_aio_lk);
- if (nni_aio_expire_exit) {
+ if (nni_aio_expire_run == 0) {
nni_mtx_unlock(&nni_aio_lk);
return;
}
@@ -358,6 +358,7 @@ nni_aio_sys_init(void)
goto fail;
}
NNI_LIST_INIT(&nni_aio_expire_aios, nni_aio, a_expire_node);
+ nni_aio_expire_run = 1;
nni_thr_run(thr);
return (0);
@@ -375,10 +376,12 @@ nni_aio_sys_fini(void)
nni_cv * cv = &nni_aio_expire_cv;
nni_thr *thr = &nni_aio_expire_thr;
- nni_mtx_lock(mtx);
- nni_aio_expire_exit = 1;
- nni_cv_wake(cv);
- nni_mtx_unlock(mtx);
+ if (nni_aio_expire_run) {
+ nni_mtx_lock(mtx);
+ nni_aio_expire_run = 0;
+ nni_cv_wake(cv);
+ nni_mtx_unlock(mtx);
+ }
nni_thr_fini(thr);
nni_cv_fini(cv);
diff --git a/src/core/endpt.c b/src/core/endpt.c
index 0a5862f0..a5865acf 100644
--- a/src/core/endpt.c
+++ b/src/core/endpt.c
@@ -62,8 +62,8 @@ nni_ep_sys_fini(void)
nni_ep_reap_run = 0;
nni_cv_wake(&nni_ep_reap_cv);
nni_mtx_unlock(&nni_ep_reap_lk);
- nni_thr_fini(&nni_ep_reap_thr);
}
+ nni_thr_fini(&nni_ep_reap_thr);
nni_cv_fini(&nni_ep_reap_cv);
nni_mtx_fini(&nni_ep_reap_lk);
nni_idhash_fini(nni_eps);
diff --git a/src/core/init.c b/src/core/init.c
index 7de2a497..24a7b118 100644
--- a/src/core/init.c
+++ b/src/core/init.c
@@ -17,45 +17,17 @@ nni_init_helper(void)
{
int rv;
- if ((rv = nni_taskq_sys_init()) != 0) {
- return (rv);
+ if (((rv = nni_taskq_sys_init()) != 0) ||
+ ((rv = nni_timer_sys_init()) != 0) ||
+ ((rv = nni_aio_sys_init()) != 0) ||
+ ((rv = nni_random_sys_init()) != 0) ||
+ ((rv = nni_sock_sys_init()) != 0) ||
+ ((rv = nni_ep_sys_init()) != 0) ||
+ ((rv = nni_pipe_sys_init()) != 0) ||
+ ((rv = nni_tran_sys_init()) != 0)) {
+ nni_fini();
}
- if ((rv = nni_timer_sys_init()) != 0) {
- nni_taskq_sys_fini();
- return (rv);
- }
- if ((rv = nni_aio_sys_init()) != 0) {
- nni_taskq_sys_fini();
- return (rv);
- }
- if ((rv = nni_random_sys_init()) != 0) {
- nni_aio_sys_fini();
- nni_taskq_sys_fini();
- return (rv);
- }
- if ((rv = nni_sock_sys_init()) != 0) {
- nni_random_sys_fini();
- nni_aio_sys_fini();
- nni_taskq_sys_fini();
- return (rv);
- }
- if ((rv = nni_ep_sys_init()) != 0) {
- nni_sock_sys_fini();
- nni_random_sys_fini();
- nni_aio_sys_fini();
- nni_taskq_sys_fini();
- return (rv);
- }
- if ((rv = nni_pipe_sys_init()) != 0) {
- nni_ep_sys_fini();
- nni_sock_sys_fini();
- nni_random_sys_fini();
- nni_aio_sys_fini();
- nni_taskq_sys_fini();
- return (rv);
- }
- nni_tran_sys_init();
- return (0);
+ return (rv);
}
int
diff --git a/src/core/pipe.c b/src/core/pipe.c
index d13e703f..1658aabc 100644
--- a/src/core/pipe.c
+++ b/src/core/pipe.c
@@ -61,9 +61,9 @@ nni_pipe_sys_fini(void)
nni_pipe_reap_run = 0;
nni_cv_wake(&nni_pipe_reap_cv);
nni_mtx_unlock(&nni_pipe_reap_lk);
- nni_thr_fini(&nni_pipe_reap_thr);
}
+ nni_thr_fini(&nni_pipe_reap_thr);
nni_cv_fini(&nni_pipe_reap_cv);
nni_mtx_fini(&nni_pipe_reap_lk);
if (nni_pipes != NULL) {
diff --git a/src/core/taskq.c b/src/core/taskq.c
index 14b04085..e32983e9 100644
--- a/src/core/taskq.c
+++ b/src/core/taskq.c
@@ -23,7 +23,7 @@ struct nni_taskq {
nni_cv tq_cv;
nni_taskq_thr *tq_threads;
int tq_nthreads;
- int tq_close;
+ int tq_run;
int tq_waiting;
};
@@ -61,7 +61,7 @@ nni_taskq_thread(void *self)
tq->tq_waiting = 0;
nni_cv_wake(&tq->tq_cv);
}
- if (tq->tq_close) {
+ if (!tq->tq_run) {
break;
}
nni_cv_wait(&tq->tq_cv);
@@ -88,7 +88,6 @@ nni_taskq_init(nni_taskq **tqp, int nthr)
NNI_FREE_STRUCT(tq);
return (rv);
}
- tq->tq_close = 0;
NNI_LIST_INIT(&tq->tq_tasks, nni_task, task_node);
tq->tq_threads = nni_alloc(sizeof(nni_taskq_thr) * nthr);
@@ -109,6 +108,7 @@ nni_taskq_init(nni_taskq **tqp, int nthr)
}
}
tq->tq_nthreads = nthr;
+ tq->tq_run = 1;
for (i = 0; i < tq->tq_nthreads; i++) {
nni_thr_run(&tq->tq_threads[i].tqt_thread);
}
@@ -157,19 +157,19 @@ nni_taskq_drain(nni_taskq *tq)
void
nni_taskq_fini(nni_taskq *tq)
{
- int i;
-
// First drain the taskq completely. This is necessary since some
// tasks that are presently running may need to schedule additional
// tasks, and we don't want those to block.
- nni_mtx_lock(&tq->tq_mtx);
- nni_taskq_drain_locked(tq);
+ if (tq->tq_run) {
+ nni_mtx_lock(&tq->tq_mtx);
+ nni_taskq_drain_locked(tq);
- tq->tq_close = 1;
- nni_cv_wake(&tq->tq_cv);
- nni_mtx_unlock(&tq->tq_mtx);
- for (i = 0; i < tq->tq_nthreads; i++) {
+ tq->tq_run = 0;
+ nni_cv_wake(&tq->tq_cv);
+ nni_mtx_unlock(&tq->tq_mtx);
+ }
+ for (int i = 0; i < tq->tq_nthreads; i++) {
nni_thr_fini(&tq->tq_threads[i].tqt_thread);
}
nni_free(tq->tq_threads, tq->tq_nthreads * sizeof(nni_taskq_thr));
@@ -201,7 +201,6 @@ void
nni_task_wait(nni_task *task)
{
nni_taskq *tq = task->task_tq;
- int i;
int running;
nni_mtx_lock(&tq->tq_mtx);
@@ -210,7 +209,7 @@ nni_task_wait(nni_task *task)
if (nni_list_active(&tq->tq_tasks, task)) {
running = 1;
} else {
- for (i = 0; i < tq->tq_nthreads; i++) {
+ for (int i = 0; i < tq->tq_nthreads; i++) {
if (tq->tq_threads[i].tqt_running == task) {
running = 1;
break;
@@ -231,14 +230,13 @@ int
nni_task_cancel(nni_task *task)
{
nni_taskq *tq = task->task_tq;
- int i;
int running;
nni_mtx_lock(&tq->tq_mtx);
running = 1;
for (;;) {
running = 0;
- for (i = 0; i < tq->tq_nthreads; i++) {
+ for (int i = 0; i < tq->tq_nthreads; i++) {
if (tq->tq_threads[i].tqt_running == task) {
running = 1;
break;
diff --git a/src/core/timer.c b/src/core/timer.c
index 6058b067..e8aa563c 100644
--- a/src/core/timer.c
+++ b/src/core/timer.c
@@ -1,5 +1,6 @@
//
// Copyright 2017 Garrett D'Amore <garrett@damore.org>
+// Copyright 2017 Capitar IT Group BV <info@capitar.com>
//
// This software is supplied under the terms of the MIT License, a
// copy of which should be located in the distribution where this
@@ -20,7 +21,7 @@ struct nni_timer {
nni_cv t_cv;
nni_list t_entries;
nni_thr t_thr;
- int t_close;
+ int t_run;
int t_waiting;
nni_timer_node *t_active; // Must never ever be dereferenced!
};
@@ -37,7 +38,6 @@ nni_timer_sys_init(void)
memset(timer, 0, sizeof(*timer));
NNI_LIST_INIT(&timer->t_entries, nni_timer_node, t_node);
- timer->t_close = 0;
if (((rv = nni_mtx_init(&timer->t_mx)) != 0) ||
((rv = nni_cv_init(&timer->t_cv, &timer->t_mx)) != 0) ||
@@ -45,6 +45,7 @@ nni_timer_sys_init(void)
nni_timer_sys_fini();
return (rv);
}
+ timer->t_run = 1;
nni_thr_run(&timer->t_thr);
return (0);
}
@@ -54,10 +55,12 @@ nni_timer_sys_fini(void)
{
nni_timer *timer = &nni_global_timer;
- nni_mtx_lock(&timer->t_mx);
- timer->t_close = 1;
- nni_cv_wake(&timer->t_cv);
- nni_mtx_unlock(&timer->t_mx);
+ if (timer->t_run) {
+ nni_mtx_lock(&timer->t_mx);
+ timer->t_run = 0;
+ nni_cv_wake(&timer->t_cv);
+ nni_mtx_unlock(&timer->t_mx);
+ }
nni_thr_fini(&timer->t_thr);
nni_cv_fini(&timer->t_cv);
@@ -137,7 +140,7 @@ nni_timer_loop(void *arg)
timer->t_waiting = 1;
nni_cv_wake(&timer->t_cv);
}
- if (timer->t_close) {
+ if (!timer->t_run) {
nni_mtx_unlock(&timer->t_mx);
break;
}
diff --git a/src/core/transport.c b/src/core/transport.c
index 61b1a0c3..ff72c754 100644
--- a/src/core/transport.c
+++ b/src/core/transport.c
@@ -1,5 +1,6 @@
//
-// Copyright 2016 Garrett D'Amore <garrett@damore.org>
+// Copyright 2017 Garrett D'Amore <garrett@damore.org>
+// Copyright 2017 Capitar IT Group BV <info@capitar.com>
//
// This software is supplied under the terms of the MIT License, a
// copy of which should be located in the distribution where this
@@ -50,15 +51,19 @@ nni_tran_find(const char *addr)
// nni_tran_sys_init initializes the entire transport subsystem, including
// each individual transport.
-void
+int
nni_tran_sys_init(void)
{
- int i;
nni_tran *tran;
- for (i = 0; (tran = transports[i]) != NULL; i++) {
- tran->tran_init();
+ for (int i = 0; (tran = transports[i]) != NULL; i++) {
+ int rv;
+ if ((rv = tran->tran_init()) != 0) {
+ nni_tran_sys_fini();
+ return (rv);
+ }
}
+ return (0);
}
// nni_tran_sys_fini finalizes the entire transport system, including all
@@ -66,10 +71,9 @@ nni_tran_sys_init(void)
void
nni_tran_sys_fini(void)
{
- int i;
nni_tran *tran;
- for (i = 0; (tran = transports[i]) != NULL; i++) {
+ for (int i = 0; (tran = transports[i]) != NULL; i++) {
if (tran->tran_fini != NULL) {
tran->tran_fini();
}
diff --git a/src/core/transport.h b/src/core/transport.h
index 72f4cc61..a739e7d2 100644
--- a/src/core/transport.h
+++ b/src/core/transport.h
@@ -118,7 +118,7 @@ struct nni_tran_pipe {
// These APIs are used by the framework internally, and not for use by
// transport implementations.
extern nni_tran *nni_tran_find(const char *);
-extern void nni_tran_sys_init(void);
+extern int nni_tran_sys_init(void);
extern void nni_tran_sys_fini(void);
#endif // CORE_TRANSPORT_H