diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/endpt.c | 4 | ||||
| -rw-r--r-- | src/core/pipe.c | 14 | ||||
| -rw-r--r-- | src/core/pipe.h | 11 |
3 files changed, 16 insertions, 13 deletions
diff --git a/src/core/endpt.c b/src/core/endpt.c index d8f94d9b..7784de73 100644 --- a/src/core/endpt.c +++ b/src/core/endpt.c @@ -254,7 +254,7 @@ nni_ep_connect_sync(nni_ep *ep) } rv = nni_ep_connect_aio(ep, &pipe->p_tran_data); if (rv != 0) { - nni_pipe_remove(pipe); + nni_pipe_stop(pipe); return (rv); } nni_pipe_start(pipe); @@ -435,7 +435,7 @@ nni_ep_accept_sync(nni_ep *ep) } rv = nni_ep_accept_aio(ep, &pipe->p_tran_data); if (rv != 0) { - nni_pipe_remove(pipe); + nni_pipe_stop(pipe); return (rv); } nni_pipe_start(pipe); diff --git a/src/core/pipe.c b/src/core/pipe.c index a912e736..aceff611 100644 --- a/src/core/pipe.c +++ b/src/core/pipe.c @@ -110,15 +110,17 @@ nni_pipe_close(nni_pipe *p) nni_mtx_unlock(&p->p_mtx); } -// We have to stop asynchronously using a task, because otherwise we can -// wind up having a callback from an AIO trying to cancel itself. That -// simply will not work. -void -nni_pipe_remove(nni_pipe *p) +// Pipe reap is called on a taskq when the pipe should be closed. No +// locks are held. This routine must take care to synchronously ensure +// that no further references to the pipe are possible, then it may +// destroy the pipe. +static void +nni_pipe_reap(nni_pipe *p) { // Transport close... nni_pipe_close(p); + // Unlink the endpoint and pipe. nni_ep_pipe_remove(p->p_ep, p); // Tell the protocol to stop. @@ -139,7 +141,7 @@ nni_pipe_stop(nni_pipe *p) } p->p_stop = 1; nni_mtx_unlock(&p->p_mtx); - nni_taskq_ent_init(&p->p_reap_tqe, (nni_cb) nni_pipe_remove, p); + nni_taskq_ent_init(&p->p_reap_tqe, (nni_cb) nni_pipe_reap, p); nni_taskq_dispatch(NULL, &p->p_reap_tqe); } diff --git a/src/core/pipe.h b/src/core/pipe.h index 8fba2c52..2f56e788 100644 --- a/src/core/pipe.h +++ b/src/core/pipe.h @@ -50,11 +50,12 @@ extern uint32_t nni_pipe_id(nni_pipe *); // operations against will return NNG_ECLOSED. extern void nni_pipe_close(nni_pipe *); -// nni_pipe_remove is called by the protocol when it is done with the socket. -// The pipe should already be closed; it will be unregistered and it's -// resources released back to the system. The protocol MUST not reference -// the pipe after this. -extern void nni_pipe_remove(nni_pipe *); +// nni_pipe_stop is called to begin the process of tearing down the socket. +// This function runs asynchronously, and takes care to ensure that no +// other consumers are referencing the pipe. We assume that either the +// socket (protocol code) or endpoint may have references to the pipe +// when this function is called. The pipe cleanup is asynchronous and +// make take a while depending on scheduling, etc. extern void nni_pipe_stop(nni_pipe *); // Used only by the socket core - as we don't wish to expose the details |
