aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2017-08-05 07:22:07 -0700
committerGarrett D'Amore <garrett@damore.org>2017-08-05 07:22:07 -0700
commit23c4a6eab39c0d24ad0ff5d5ec7e9879b1788a9b (patch)
treeb38e82c37e27cec60d14ee04de2dd93300d34762
parent719bc93e11f6607d302d908475b240e1d50f5a89 (diff)
downloadnng-23c4a6eab39c0d24ad0ff5d5ec7e9879b1788a9b.tar.gz
nng-23c4a6eab39c0d24ad0ff5d5ec7e9879b1788a9b.tar.bz2
nng-23c4a6eab39c0d24ad0ff5d5ec7e9879b1788a9b.zip
Use dedicate reap thread for endpoints too.
This change mirrors the change we made for pipes yesterday, moving the endpoint cleanup to its own thread, ensuring that the blocking operations we need to perform during clean up do not gum up the works in the main system taskq.
-rw-r--r--src/core/endpt.c62
-rw-r--r--src/core/endpt.h2
2 files changed, 58 insertions, 6 deletions
diff --git a/src/core/endpt.c b/src/core/endpt.c
index aa4c5a31..76545fcc 100644
--- a/src/core/endpt.c
+++ b/src/core/endpt.c
@@ -23,27 +23,51 @@ static void nni_ep_connect_done(void *);
static void nni_ep_backoff_start(nni_ep *);
static void nni_ep_backoff_done(void *);
static void nni_ep_reap(nni_ep *);
+static void nni_ep_reaper(void *);
static nni_idhash *nni_eps;
+static nni_list nni_ep_reap_list;
+static nni_mtx nni_ep_reap_lk;
+static nni_cv nni_ep_reap_cv;
+static nni_thr nni_ep_reap_thr;
+static int nni_ep_reap_stop;
+static int nni_ep_reap_start;
+
int
nni_ep_sys_init(void)
{
int rv;
- if ((rv = nni_idhash_init(&nni_eps)) != 0) {
+ NNI_LIST_INIT(&nni_ep_reap_list, nni_ep, ep_reap_node);
+
+ if (((rv = nni_mtx_init(&nni_ep_reap_lk)) != 0) ||
+ ((rv = nni_cv_init(&nni_ep_reap_cv, &nni_ep_reap_lk)) != 0) ||
+ ((rv = nni_thr_init(&nni_ep_reap_thr, nni_ep_reaper, 0)) != 0) ||
+ ((rv = nni_idhash_init(&nni_eps)) != 0)) {
return (rv);
}
-
nni_idhash_set_limits(
nni_eps, 1, 0x7fffffff, nni_random() & 0x7fffffff);
+ nni_ep_reap_start = 1;
+ nni_thr_run(&nni_ep_reap_thr);
+
return (0);
}
void
nni_ep_sys_fini(void)
{
+ if (nni_ep_reap_start) {
+ nni_mtx_lock(&nni_ep_reap_lk);
+ nni_ep_reap_stop = 1;
+ nni_cv_wake(&nni_ep_reap_cv);
+ nni_mtx_unlock(&nni_ep_reap_lk);
+ 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);
nni_eps = NULL;
}
@@ -108,7 +132,6 @@ nni_ep_create(nni_ep **epp, nni_sock *sock, const char *addr, int mode)
ep->ep_refcnt = 0;
NNI_LIST_NODE_INIT(&ep->ep_node);
- nni_task_init(NULL, &ep->ep_reap_task, (nni_cb) nni_ep_reap, ep);
nni_pipe_ep_list_init(&ep->ep_pipes);
@@ -229,9 +252,12 @@ nni_ep_stop(nni_ep *ep)
NNI_LIST_FOREACH (&ep->ep_pipes, pipe) {
nni_pipe_stop(pipe);
}
-
- nni_task_dispatch(&ep->ep_reap_task);
nni_mtx_unlock(&ep->ep_mtx);
+
+ nni_mtx_lock(&nni_ep_reap_lk);
+ nni_list_append(&nni_ep_reap_list, ep);
+ nni_cv_wake(&nni_ep_reap_cv);
+ nni_mtx_unlock(&nni_ep_reap_lk);
}
static void
@@ -503,3 +529,29 @@ nni_ep_list_init(nni_list *list)
{
NNI_LIST_INIT(list, nni_ep, ep_node);
}
+
+void
+nni_ep_reaper(void *notused)
+{
+ NNI_ARG_UNUSED(notused);
+
+ nni_mtx_lock(&nni_ep_reap_lk);
+ for (;;) {
+ nni_ep *ep;
+
+ if ((ep = nni_list_first(&nni_ep_reap_list)) != NULL) {
+ nni_list_remove(&nni_ep_reap_list, ep);
+ nni_mtx_unlock(&nni_ep_reap_lk);
+ nni_ep_reap(ep);
+ nni_mtx_lock(&nni_ep_reap_lk);
+ continue;
+ }
+
+ if (nni_ep_reap_stop) {
+ break;
+ }
+
+ nni_cv_wait(&nni_ep_reap_cv);
+ }
+ nni_mtx_unlock(&nni_ep_reap_lk);
+} \ No newline at end of file
diff --git a/src/core/endpt.h b/src/core/endpt.h
index 942ba978..5a923bd5 100644
--- a/src/core/endpt.h
+++ b/src/core/endpt.h
@@ -44,7 +44,7 @@ struct nni_ep {
nni_duration ep_currtime; // current time for reconnect
nni_duration ep_inirtime; // initial time for reconnect
nni_time ep_conntime; // time of last good connect
- nni_task ep_reap_task;
+ nni_list_node ep_reap_node;
};
enum nni_ep_mode {