diff options
| author | Garrett D'Amore <garrett@damore.org> | 2017-07-16 12:36:32 -0700 |
|---|---|---|
| committer | Garrett D'Amore <garrett@damore.org> | 2017-07-16 12:36:32 -0700 |
| commit | 09b31812fa2af4e67d9d9193aaae0d7111ded15f (patch) | |
| tree | cc0b1fce9c5ce181ac86430e2c49f11ae63714c0 /src/core/pipe.c | |
| parent | b48b18b6be688d9611b71ca60d51491c5b5127c6 (diff) | |
| download | nng-09b31812fa2af4e67d9d9193aaae0d7111ded15f.tar.gz nng-09b31812fa2af4e67d9d9193aaae0d7111ded15f.tar.bz2 nng-09b31812fa2af4e67d9d9193aaae0d7111ded15f.zip | |
Fix locking errors in endpoints, and simplify some logic.
This cleans up the pipe creation logic greatly, and eliminates
a nasty potential deadlock (lock-order incorrect.) It also
adds a corret binary exponential and randomized backoff on both
accept and connect.
Diffstat (limited to 'src/core/pipe.c')
| -rw-r--r-- | src/core/pipe.c | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/src/core/pipe.c b/src/core/pipe.c index 664ababa..2fd19464 100644 --- a/src/core/pipe.c +++ b/src/core/pipe.c @@ -170,6 +170,57 @@ nni_pipe_start_cb(void *arg) } int +nni_pipe_create(nni_ep *ep, void *tdata) +{ + nni_pipe *p; + int rv; + nni_tran *tran = ep->ep_tran; + nni_sock *sock = ep->ep_sock; + + if ((p = NNI_ALLOC_STRUCT(p)) == NULL) { + // In this case we just toss the pipe... + tran->tran_pipe->p_fini(p); + return (NNG_ENOMEM); + } + + // Make a private copy of the transport ops. + p->p_tran_ops = *tran->tran_pipe; + p->p_tran_data = tdata; + p->p_proto_data = NULL; + + if ((rv = nni_mtx_init(&p->p_mtx)) != 0) { + nni_pipe_destroy(p); + return (rv); + } + if ((rv = nni_idhash_alloc(nni_pipes, &p->p_id, p)) != 0) { + nni_pipe_destroy(p); + return (rv); + } + + NNI_LIST_NODE_INIT(&p->p_sock_node); + NNI_LIST_NODE_INIT(&p->p_ep_node); + + if ((rv = nni_aio_init(&p->p_start_aio, nni_pipe_start_cb, p)) != 0) { + nni_pipe_destroy(p); + return (rv); + } + + p->p_tran_ops = *tran->tran_pipe; + p->p_tran_data = tdata; + + // Attempt to initialize protocol data. + if ((rv = nni_sock_pipe_init(sock, p)) != 0) { + nni_pipe_destroy(p); + return (rv); + } + + // Start the pipe running. + nni_pipe_start(p); + return (0); +} + +#if 0 +int nni_pipe_create(nni_pipe **pp, nni_sock *sock, nni_tran *tran) { nni_pipe *p; @@ -211,6 +262,7 @@ nni_pipe_create(nni_pipe **pp, nni_sock *sock, nni_tran *tran) *pp = p; return (0); } +#endif int nni_pipe_getopt(nni_pipe *p, int opt, void *val, size_t *szp) |
