aboutsummaryrefslogtreecommitdiff
path: root/src/core/pipe.c
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2017-07-16 12:36:32 -0700
committerGarrett D'Amore <garrett@damore.org>2017-07-16 12:36:32 -0700
commit09b31812fa2af4e67d9d9193aaae0d7111ded15f (patch)
treecc0b1fce9c5ce181ac86430e2c49f11ae63714c0 /src/core/pipe.c
parentb48b18b6be688d9611b71ca60d51491c5b5127c6 (diff)
downloadnng-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.c52
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)