aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2017-08-24 19:32:01 -0700
committerGarrett D'Amore <garrett@damore.org>2017-08-24 19:32:01 -0700
commit405f6e5849c492705f3e30974c9eec3f595ed6bb (patch)
tree6e9b7de866ff1e3effe2a1106ac80dd1f8be321e /src
parentea50bfbc237eb2e263fdbf341dce0df0707dda5c (diff)
downloadnng-405f6e5849c492705f3e30974c9eec3f595ed6bb.tar.gz
nng-405f6e5849c492705f3e30974c9eec3f595ed6bb.tar.bz2
nng-405f6e5849c492705f3e30974c9eec3f595ed6bb.zip
Endpoint cancellation needs lock protection.
Diffstat (limited to 'src')
-rw-r--r--src/core/aio.c3
-rw-r--r--src/core/endpt.c19
2 files changed, 16 insertions, 6 deletions
diff --git a/src/core/aio.c b/src/core/aio.c
index ee5724a6..5b8c7970 100644
--- a/src/core/aio.c
+++ b/src/core/aio.c
@@ -171,8 +171,7 @@ nni_aio_finish_impl(
{
nni_mtx_lock(&nni_aio_lk);
- // provider only calls us *once*, but expiration may be in flight
- NNI_ASSERT(aio->a_expiring || aio->a_pend == 0);
+ NNI_ASSERT(aio->a_pend == 0); // provider only calls us *once*
nni_list_node_remove(&aio->a_expire_node);
aio->a_pend = 1;
diff --git a/src/core/endpt.c b/src/core/endpt.c
index 10608575..f6aaf629 100644
--- a/src/core/endpt.c
+++ b/src/core/endpt.c
@@ -27,6 +27,7 @@ struct nni_ep {
int ep_closed; // full shutdown
int ep_closing; // close pending (waiting on refcnt)
int ep_refcnt;
+ int ep_tmo_run;
nni_mtx ep_mtx;
nni_cv ep_cv;
nni_list ep_pipes;
@@ -243,6 +244,7 @@ nni_ep_shutdown(nni_ep *ep)
return (NNG_ECLOSED);
}
ep->ep_closing = 1;
+ nni_mtx_unlock(&ep->ep_mtx);
// Abort any remaining in-flight operations.
nni_aio_cancel(&ep->ep_acc_aio, NNG_ECLOSED);
@@ -253,8 +255,6 @@ nni_ep_shutdown(nni_ep *ep)
// Stop the underlying transport.
ep->ep_ops.ep_close(ep->ep_data);
- nni_mtx_unlock(&ep->ep_mtx);
-
return (0);
}
@@ -294,8 +294,16 @@ nni_ep_close(nni_ep *ep)
static void
nni_ep_tmo_cancel(nni_aio *aio, int rv)
{
+ nni_ep *ep = aio->a_prov_data;
// The only way this ever gets "finished", is via cancellation.
- nni_aio_finish_error(aio, rv);
+ if (ep != NULL) {
+ nni_mtx_lock(&ep->ep_mtx);
+ if (ep->ep_tmo_run) {
+ nni_aio_finish_error(aio, rv);
+ }
+ ep->ep_tmo_run = 0;
+ nni_mtx_unlock(&ep->ep_mtx);
+ }
}
static void
@@ -322,7 +330,10 @@ nni_ep_tmo_start(nni_ep *ep)
ep->ep_tmo_aio.a_expire =
nni_clock() + (backoff ? nni_random() % backoff : 0);
- nni_aio_start(&ep->ep_tmo_aio, nni_ep_tmo_cancel, ep);
+ ep->ep_tmo_run = 1;
+ if (nni_aio_start(&ep->ep_tmo_aio, nni_ep_tmo_cancel, ep) != 0) {
+ ep->ep_tmo_run = 0;
+ }
}
static void