summaryrefslogtreecommitdiff
path: root/src/core/endpt.c
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2017-01-18 11:49:05 -0800
committerGarrett D'Amore <garrett@damore.org>2017-01-18 11:49:46 -0800
commite88e28fcf5e5dd5b478d0a7a462836026da975fe (patch)
treeedba090c97d32f07fdb1b46dfe6e107e5e4d9596 /src/core/endpt.c
parenta56ce392b5e2c45232a1bd1299d83c215bcd6653 (diff)
downloadnng-e88e28fcf5e5dd5b478d0a7a462836026da975fe.tar.gz
nng-e88e28fcf5e5dd5b478d0a7a462836026da975fe.tar.bz2
nng-e88e28fcf5e5dd5b478d0a7a462836026da975fe.zip
Reduce lock contention and simplify logic for endpoint creation.
Diffstat (limited to 'src/core/endpt.c')
-rw-r--r--src/core/endpt.c40
1 files changed, 24 insertions, 16 deletions
diff --git a/src/core/endpt.c b/src/core/endpt.c
index 58b30b9f..2366a8e8 100644
--- a/src/core/endpt.c
+++ b/src/core/endpt.c
@@ -37,41 +37,49 @@ nni_ep_create(nni_ep **epp, nni_sock *sock, const char *addr)
ep->ep_bound = 0;
ep->ep_pipe = NULL;
ep->ep_tran = tran;
-
- nni_mtx_lock(nni_idlock);
- rv = nni_idhash_alloc(nni_endpoints, &ep->ep_id, ep);
- nni_mtx_unlock(nni_idlock);
- if (rv != 0) {
- NNI_FREE_STRUCT(ep);
- return (rv);
- }
+ NNI_LIST_NODE_INIT(&ep->ep_node);
+ // Could safely use strcpy here, but this avoids discussion.
+ (void) snprintf(ep->ep_addr, sizeof (ep->ep_addr), "%s", addr);
// Make a copy of the endpoint operations. This allows us to
// modify them (to override NULLs for example), and avoids an extra
// dereference on hot paths.
ep->ep_ops = *tran->tran_ep;
- NNI_LIST_NODE_INIT(&ep->ep_node);
- if ((rv = nni_cv_init(&ep->ep_cv, &ep->ep_sock->s_mx)) != 0) {
- nni_mtx_lock(nni_idlock);
- nni_idhash_remove(nni_endpoints, ep->ep_id);
- nni_mtx_unlock(nni_idlock);
+ if ((rv = nni_cv_init(&ep->ep_cv, &sock->s_mx)) != 0) {
NNI_FREE_STRUCT(ep);
- return (NNG_ENOMEM);
+ return (rv);
}
- // Could safely use strcpy here, but this avoids discussion.
- (void) snprintf(ep->ep_addr, sizeof (ep->ep_addr), "%s", addr);
+ nni_mtx_lock(&sock->s_mx);
+ if (sock->s_closing) {
+ nni_mtx_unlock(&sock->s_mx);
+ nni_cv_fini(&ep->ep_cv);
+ NNI_FREE_STRUCT(ep);
+ return (NNG_ECLOSED);
+ }
+ nni_mtx_lock(nni_idlock);
+ rv = nni_idhash_alloc(nni_endpoints, &ep->ep_id, ep);
+ nni_mtx_unlock(nni_idlock);
+ if (rv != 0) {
+ nni_mtx_unlock(&sock->s_mx);
+ nni_cv_fini(&ep->ep_cv);
+ NNI_FREE_STRUCT(ep);
+ return (rv);
+ }
rv = ep->ep_ops.ep_init(&ep->ep_data, addr, nni_sock_proto(sock));
if (rv != 0) {
nni_mtx_lock(nni_idlock);
nni_idhash_remove(nni_endpoints, ep->ep_id);
nni_mtx_unlock(nni_idlock);
+ nni_mtx_unlock(&sock->s_mx);
nni_cv_fini(&ep->ep_cv);
NNI_FREE_STRUCT(ep);
return (rv);
}
+ nni_list_append(&sock->s_eps, ep);
+ nni_mtx_unlock(&sock->s_mx);
*epp = ep;
return (0);