diff options
| author | Garrett D'Amore <garrett@damore.org> | 2017-07-05 15:51:29 -0700 |
|---|---|---|
| committer | Garrett D'Amore <garrett@damore.org> | 2017-07-05 15:51:29 -0700 |
| commit | 372d03889b1398016056d1641d31705b75d97c9a (patch) | |
| tree | e26d06ee7e07820e8da08e9259832b2ce4180934 /src/core/pipe.c | |
| parent | 0b08b59786e4af19f57bf00ebc20ee8f96453679 (diff) | |
| download | nng-372d03889b1398016056d1641d31705b75d97c9a.tar.gz nng-372d03889b1398016056d1641d31705b75d97c9a.tar.bz2 nng-372d03889b1398016056d1641d31705b75d97c9a.zip | |
Move IPC negotiation out of connect/accept.
This prevents a slow partner from blocking new connections from being
established on the server. Before this a single partner could cause
the server to block waiting to complete the negotiation.
Diffstat (limited to 'src/core/pipe.c')
| -rw-r--r-- | src/core/pipe.c | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/src/core/pipe.c b/src/core/pipe.c index 08d3dee7..eaf4fa1c 100644 --- a/src/core/pipe.c +++ b/src/core/pipe.c @@ -53,6 +53,7 @@ nni_pipe_dtor(void *ptr) p->p_tran_ops.p_fini(p->p_tran_data); } + nni_aio_fini(&p->p_start_aio); nni_mtx_fini(&p->p_mtx); NNI_FREE_STRUCT(p); } @@ -170,6 +171,28 @@ nni_pipe_peer(nni_pipe *p) } +static void +nni_pipe_start_cb(void *arg) +{ + nni_pipe *p = arg; + nni_aio *aio = &p->p_start_aio; + int rv; + + nni_mtx_lock(&p->p_mtx); + if ((rv = nni_aio_result(aio)) != 0) { + nni_mtx_unlock(&p->p_mtx); + nni_pipe_stop(p); + return; + } + + nni_mtx_unlock(&p->p_mtx); + + if ((rv = nni_sock_pipe_ready(p->p_sock, p)) != 0) { + nni_pipe_stop(p); + } +} + + int nni_pipe_create(nni_pipe **pp, nni_ep *ep, nni_sock *sock, nni_tran *tran) { @@ -182,6 +205,10 @@ nni_pipe_create(nni_pipe **pp, nni_ep *ep, nni_sock *sock, nni_tran *tran) if (rv != 0) { return (rv); } + if ((rv = nni_aio_init(&p->p_start_aio, nni_pipe_start_cb, p)) != 0) { + nni_objhash_unref(nni_pipes, p->p_id); + return (rv); + } p->p_sock = sock; p->p_ep = ep; @@ -225,10 +252,12 @@ nni_pipe_start(nni_pipe *p) { int rv; - if ((rv = nni_sock_pipe_ready(p->p_sock, p)) != 0) { + if (p->p_tran_ops.p_start == NULL) { + rv = nni_sock_pipe_ready(p->p_sock, p); return (rv); } + p->p_tran_ops.p_start(p->p_tran_data, &p->p_start_aio); // XXX: Publish event return (0); |
