diff --git a/src/core/dialer.c b/src/core/dialer.c index 2945fded6..dfed5c4d4 100644 --- a/src/core/dialer.c +++ b/src/core/dialer.c @@ -20,6 +20,7 @@ static void dialer_connect_start(nni_dialer *); static void dialer_connect_cb(void *); static void dialer_timer_cb(void *); +static void dialer_destroy(void *); static nni_id_map dialers = NNI_ID_MAP_INITIALIZER(1, 0x7fffffff, 0); static nni_mtx dialers_lk = NNI_MTX_INITIALIZER; @@ -30,11 +31,10 @@ nni_dialer_id(nni_dialer *d) return (d->d_id); } -void -nni_dialer_destroy(nni_dialer *d) +static void +dialer_destroy(void *arg) { - nni_aio_stop(&d->d_con_aio); - nni_aio_stop(&d->d_tmo_aio); + nni_dialer *d = arg; nni_aio_fini(&d->d_con_aio); nni_aio_fini(&d->d_tmo_aio); @@ -209,11 +209,9 @@ nni_dialer_init(nni_dialer *d, nni_sock *s, nni_sp_tran *tran) { int rv; - d->d_closed = false; - d->d_data = NULL; - d->d_ref = 1; - d->d_sock = s; - d->d_tran = tran; + d->d_data = NULL; + d->d_sock = s; + d->d_tran = tran; nni_atomic_flag_reset(&d->d_started); // Make a copy of the endpoint operations. This allows us to @@ -229,10 +227,14 @@ nni_dialer_init(nni_dialer *d, nni_sock *s, nni_sp_tran *tran) nni_aio_init(&d->d_con_aio, dialer_connect_cb, d); nni_aio_init(&d->d_tmo_aio, dialer_timer_cb, d); + nni_refcnt_init(&d->d_refcnt, 2, d, dialer_destroy); + nni_mtx_lock(&dialers_lk); rv = nni_id_alloc32(&dialers, &d->d_id, d); nni_mtx_unlock(&dialers_lk); + nni_sock_hold(s); + #ifdef NNG_ENABLE_STATS dialer_stats_init(d); #endif @@ -240,12 +242,8 @@ nni_dialer_init(nni_dialer *d, nni_sock *s, nni_sp_tran *tran) if ((rv != 0) || ((rv = d->d_ops.d_init(&d->d_data, &d->d_url, d)) != 0) || ((rv = nni_sock_add_dialer(s, d)) != 0)) { - nni_mtx_lock(&dialers_lk); - nni_id_remove(&dialers, d->d_id); - nni_mtx_unlock(&dialers_lk); -#ifdef NNG_ENABLE_STATS - nni_stat_unregister(&d->st_root); -#endif + nni_dialer_close(d); + nni_dialer_rele(d); return (rv); } @@ -271,7 +269,6 @@ nni_dialer_create_url(nni_dialer **dp, nni_sock *s, const nng_url *url) return (rv); } if ((rv = nni_dialer_init(d, s, tran)) != 0) { - nni_dialer_destroy(d); return (rv); } *dp = d; @@ -301,44 +298,7 @@ nni_dialer_create(nni_dialer **dp, nni_sock *s, const char *url_str) NNI_FREE_STRUCT(d); return (rv); } - d->d_closed = false; - d->d_data = NULL; - d->d_ref = 1; - d->d_sock = s; - d->d_tran = tran; - nni_atomic_flag_reset(&d->d_started); - - // 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. - d->d_ops = *tran->tran_dialer; - - NNI_LIST_NODE_INIT(&d->d_node); - NNI_LIST_INIT(&d->d_pipes, nni_pipe, p_ep_node); - - nni_mtx_init(&d->d_mtx); - - nni_aio_init(&d->d_con_aio, dialer_connect_cb, d); - nni_aio_init(&d->d_tmo_aio, dialer_timer_cb, d); - - nni_mtx_lock(&dialers_lk); - rv = nni_id_alloc32(&dialers, &d->d_id, d); - nni_mtx_unlock(&dialers_lk); - -#ifdef NNG_ENABLE_STATS - dialer_stats_init(d); -#endif - - if ((rv != 0) || - ((rv = d->d_ops.d_init(&d->d_data, &d->d_url, d)) != 0) || - ((rv = nni_sock_add_dialer(s, d)) != 0)) { - nni_mtx_lock(&dialers_lk); - nni_id_remove(&dialers, d->d_id); - nni_mtx_unlock(&dialers_lk); -#ifdef NNG_ENABLE_STATS - nni_stat_unregister(&d->st_root); -#endif - nni_dialer_destroy(d); + if ((rv = nni_dialer_init(d, s, tran)) != 0) { return (rv); } @@ -353,61 +313,58 @@ nni_dialer_find(nni_dialer **dp, uint32_t id) nni_mtx_lock(&dialers_lk); if ((d = nni_id_get(&dialers, id)) != NULL) { - d->d_ref++; + nni_dialer_hold(d); *dp = d; } nni_mtx_unlock(&dialers_lk); return (d == NULL ? NNG_ENOENT : 0); } -int +void nni_dialer_hold(nni_dialer *d) { - int rv; - nni_mtx_lock(&dialers_lk); - if (d->d_closed) { - rv = NNG_ECLOSED; - } else { - d->d_ref++; - rv = 0; - } - nni_mtx_unlock(&dialers_lk); - return (rv); + nni_refcnt_hold(&d->d_refcnt); } void nni_dialer_rele(nni_dialer *d) { - bool reap; + nni_refcnt_rele(&d->d_refcnt); +} - nni_mtx_lock(&dialers_lk); - NNI_ASSERT(d->d_ref > 0); - d->d_ref--; - reap = ((d->d_ref == 0) && (d->d_closed)); - nni_mtx_unlock(&dialers_lk); +static void +dialer_reap(void *arg) +{ + nni_dialer *d = arg; - if (reap) { - nni_dialer_reap(d); + nni_aio_stop(&d->d_tmo_aio); + nni_aio_stop(&d->d_con_aio); + if (d->d_data != NULL) { + d->d_ops.d_close(d->d_data); } + + nni_dialer_shutdown(d); + nni_dialer_rele(d); } +static nni_reap_list dialer_reap_list = { + .rl_offset = offsetof(nni_dialer, d_reap), + .rl_func = dialer_reap, +}; + void nni_dialer_close(nni_dialer *d) { - nni_mtx_lock(&dialers_lk); - if (d->d_closed) { - nni_mtx_unlock(&dialers_lk); - nni_dialer_rele(d); + if (nni_atomic_flag_test_and_set(&d->d_closing)) { return; } - d->d_closed = true; + nni_mtx_lock(&dialers_lk); nni_id_remove(&dialers, d->d_id); nni_mtx_unlock(&dialers_lk); + nni_aio_close(&d->d_tmo_aio); + nni_aio_close(&d->d_con_aio); - nni_dialer_shutdown(d); - - nni_sock_remove_dialer(d); - nni_dialer_rele(d); + nni_reap(&dialer_reap_list, d); } static void @@ -507,14 +464,6 @@ nni_dialer_start(nni_dialer *d, unsigned flags) return (rv); } -void -nni_dialer_stop(nni_dialer *d) -{ - nni_aio_stop(&d->d_tmo_aio); - nni_aio_stop(&d->d_con_aio); - d->d_ops.d_close(d->d_data); -} - nni_sock * nni_dialer_sock(nni_dialer *d) { diff --git a/src/core/dialer.h b/src/core/dialer.h index f3fac7f15..41d07b968 100644 --- a/src/core/dialer.h +++ b/src/core/dialer.h @@ -13,7 +13,7 @@ #define CORE_DIALER_H extern int nni_dialer_find(nni_dialer **, uint32_t); -extern int nni_dialer_hold(nni_dialer *); +extern void nni_dialer_hold(nni_dialer *); extern void nni_dialer_rele(nni_dialer *); extern uint32_t nni_dialer_id(nni_dialer *); extern int nni_dialer_create(nni_dialer **, nni_sock *, const char *); diff --git a/src/core/listener.c b/src/core/listener.c index 9107e3a4b..1563fea5d 100644 --- a/src/core/listener.c +++ b/src/core/listener.c @@ -11,6 +11,7 @@ #include "core/defs.h" #include "core/nng_impl.h" +#include "core/platform.h" #include "core/strs.h" #include "nng/nng.h" #include "sockimpl.h" @@ -33,10 +34,11 @@ nni_listener_id(nni_listener *l) return (l->l_id); } -void -nni_listener_destroy(nni_listener *l) +static void +listener_destroy(void *arg) { - // NB: both these will have already been stopped. + nni_listener *l = arg; + nni_aio_fini(&l->l_acc_aio); nni_aio_fini(&l->l_tmo_aio); @@ -197,11 +199,9 @@ nni_listener_init(nni_listener *l, nni_sock *s, nni_sp_tran *tran) { int rv; - l->l_closed = false; - l->l_data = NULL; - l->l_ref = 1; - l->l_sock = s; - l->l_tran = tran; + l->l_data = NULL; + l->l_sock = s; + l->l_tran = tran; nni_atomic_flag_reset(&l->l_started); // Make a copy of the endpoint operations. This allows us to @@ -215,10 +215,14 @@ nni_listener_init(nni_listener *l, nni_sock *s, nni_sp_tran *tran) nni_aio_init(&l->l_acc_aio, listener_accept_cb, l); nni_aio_init(&l->l_tmo_aio, listener_timer_cb, l); + nni_refcnt_init(&l->l_refcnt, 2, l, listener_destroy); + nni_mtx_lock(&listeners_lk); rv = nni_id_alloc32(&listeners, &l->l_id, l); nni_mtx_unlock(&listeners_lk); + nni_sock_hold(s); + #ifdef NNG_ENABLE_STATS listener_stats_init(l); #endif @@ -226,12 +230,8 @@ nni_listener_init(nni_listener *l, nni_sock *s, nni_sp_tran *tran) if ((rv != 0) || ((rv = l->l_ops.l_init(&l->l_data, &l->l_url, l)) != 0) || ((rv = nni_sock_add_listener(s, l)) != 0)) { - nni_mtx_lock(&listeners_lk); - nni_id_remove(&listeners, l->l_id); - nni_mtx_unlock(&listeners_lk); -#ifdef NNG_ENABLE_STATS - nni_stat_unregister(&l->st_root); -#endif + nni_listener_close(l); + nni_listener_rele(l); return (rv); } @@ -257,7 +257,6 @@ nni_listener_create_url(nni_listener **lp, nni_sock *s, const nng_url *url) return (rv); } if ((rv = nni_listener_init(l, s, tran)) != 0) { - nni_listener_destroy(l); return (rv); } @@ -289,7 +288,6 @@ nni_listener_create(nni_listener **lp, nni_sock *s, const char *url_str) return (rv); } if ((rv = nni_listener_init(l, s, tran)) != 0) { - nni_listener_destroy(l); return (rv); } *lp = l; @@ -303,60 +301,58 @@ nni_listener_find(nni_listener **lp, uint32_t id) nni_mtx_lock(&listeners_lk); if ((l = nni_id_get(&listeners, id)) != NULL) { - l->l_ref++; + nni_listener_hold(l); *lp = l; } nni_mtx_unlock(&listeners_lk); return (l == NULL ? NNG_ENOENT : 0); } -int +void nni_listener_hold(nni_listener *l) { - int rv; - nni_mtx_lock(&listeners_lk); - if (l->l_closed) { - rv = NNG_ECLOSED; - } else { - l->l_ref++; - rv = 0; - } - nni_mtx_unlock(&listeners_lk); - return (rv); + nni_refcnt_hold(&l->l_refcnt); } void nni_listener_rele(nni_listener *l) { - bool reap; + nni_refcnt_rele(&l->l_refcnt); +} - nni_mtx_lock(&listeners_lk); - NNI_ASSERT(l->l_ref > 0); - l->l_ref--; - reap = ((l->l_ref == 0) && (l->l_closed)); - nni_mtx_unlock(&listeners_lk); - if (reap) { - nni_listener_reap(l); +static void +listener_reap(void *arg) +{ + nni_listener *l = arg; + + nni_aio_stop(&l->l_tmo_aio); + nni_aio_stop(&l->l_acc_aio); + if (l->l_data) { + l->l_ops.l_close(l->l_data); } + + nni_listener_shutdown(l); + nni_listener_rele(l); } +static nni_reap_list listener_reap_list = { + .rl_offset = offsetof(nni_listener, l_reap), + .rl_func = listener_reap, +}; + void nni_listener_close(nni_listener *l) { - nni_mtx_lock(&listeners_lk); - if (l->l_closed) { - nni_mtx_unlock(&listeners_lk); - nni_listener_rele(l); + if (nni_atomic_flag_test_and_set(&l->l_closing)) { return; } - l->l_closed = true; + nni_mtx_lock(&listeners_lk); nni_id_remove(&listeners, l->l_id); nni_mtx_unlock(&listeners_lk); + nni_aio_close(&l->l_tmo_aio); + nni_aio_close(&l->l_acc_aio); - nni_listener_shutdown(l); - - nni_sock_remove_listener(l); - nni_listener_rele(l); // This will reap if reference count is zero. + nni_reap(&listener_reap_list, l); } static void @@ -447,14 +443,6 @@ nni_listener_start(nni_listener *l, int flags) return (0); } -void -nni_listener_stop(nni_listener *l) -{ - nni_aio_stop(&l->l_tmo_aio); - nni_aio_stop(&l->l_acc_aio); - l->l_ops.l_close(l->l_data); -} - nni_sock * nni_listener_sock(nni_listener *l) { diff --git a/src/core/listener.h b/src/core/listener.h index 5902d4bc8..0de32e81e 100644 --- a/src/core/listener.h +++ b/src/core/listener.h @@ -13,7 +13,7 @@ #define CORE_LISTENER_H extern int nni_listener_find(nni_listener **, uint32_t); -extern int nni_listener_hold(nni_listener *); +extern void nni_listener_hold(nni_listener *); extern void nni_listener_rele(nni_listener *); extern uint32_t nni_listener_id(nni_listener *); extern int nni_listener_create(nni_listener **, nni_sock *, const char *); diff --git a/src/core/socket.c b/src/core/socket.c index fe1b62d2b..9ce835b74 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -632,18 +632,12 @@ nni_sock_shutdown(nni_sock *sock) // Mark us closing, so no more EPs or changes can occur. sock->s_closing = true; - while ((l = nni_list_first(&sock->s_listeners)) != NULL) { - nni_listener_hold(l); - nni_mtx_unlock(&sock->s_mx); + NNI_LIST_FOREACH (&sock->s_listeners, l) { nni_listener_close(l); - nni_mtx_lock(&sock->s_mx); } - while ((d = nni_list_first(&sock->s_dialers)) != NULL) { - nni_dialer_hold(d); - nni_mtx_unlock(&sock->s_mx); + NNI_LIST_FOREACH (&sock->s_dialers, d) { nni_dialer_close(d); - nni_mtx_lock(&sock->s_mx); } nni_mtx_unlock(&sock->s_mx); @@ -848,11 +842,6 @@ nni_sock_add_listener(nni_sock *s, nni_listener *l) { int rv; - // grab a hold on the listener for the socket - if ((rv = nni_listener_hold(l)) != 0) { - return (rv); - } - // copy initial values for some options from socket for (int i = 0; ep_options[i].eo_name != NULL; i++) { uint64_t val; // big enough @@ -863,7 +852,6 @@ nni_sock_add_listener(nni_sock *s, nni_listener *l) l, o->eo_name, &val, 0, o->eo_type); } if (rv != 0 && rv != NNG_ENOTSUP) { - nni_listener_rele(l); return (rv); } } @@ -871,7 +859,6 @@ nni_sock_add_listener(nni_sock *s, nni_listener *l) nni_mtx_lock(&s->s_mx); if (s->s_closing) { nni_mtx_unlock(&s->s_mx); - nni_listener_rele(l); return (NNG_ECLOSED); } @@ -885,28 +872,11 @@ nni_sock_add_listener(nni_sock *s, nni_listener *l) return (0); } -void -nni_sock_remove_listener(nni_listener *l) -{ - nni_sock *s = l->l_sock; - nni_mtx_lock(&s->s_mx); - NNI_ASSERT(nni_list_node_active(&l->l_node)); - nni_list_node_remove(&l->l_node); - nni_mtx_unlock(&s->s_mx); - - // also drop the hold from the socket - nni_listener_rele(l); -} - int nni_sock_add_dialer(nni_sock *s, nni_dialer *d) { int rv; - // grab a hold on the dialer for the socket - if ((rv = nni_dialer_hold(d)) != 0) { - return (rv); - } // copy initial values for some options from socket for (int i = 0; ep_options[i].eo_name != NULL; i++) { uint64_t val; // big enough @@ -917,7 +887,6 @@ nni_sock_add_dialer(nni_sock *s, nni_dialer *d) d, o->eo_name, &val, 0, o->eo_type); } if (rv != 0 && rv != NNG_ENOTSUP) { - nni_dialer_rele(d); return (rv); } } @@ -925,7 +894,6 @@ nni_sock_add_dialer(nni_sock *s, nni_dialer *d) nni_mtx_lock(&s->s_mx); if (s->s_closing) { nni_mtx_unlock(&s->s_mx); - nni_dialer_rele(d); return (NNG_ECLOSED); } @@ -939,19 +907,6 @@ nni_sock_add_dialer(nni_sock *s, nni_dialer *d) return (0); } -void -nni_sock_remove_dialer(nni_dialer *d) -{ - nni_sock *s = d->d_sock; - nni_mtx_lock(&s->s_mx); - NNI_ASSERT(nni_list_node_active(&d->d_node)); - nni_list_node_remove(&d->d_node); - nni_mtx_unlock(&s->s_mx); - - // also drop the hold from the socket - nni_dialer_rele(d); -} - int nni_sock_setopt( nni_sock *s, const char *name, const void *v, size_t sz, nni_type t) @@ -1347,60 +1302,17 @@ nni_dialer_shutdown(nni_dialer *d) nni_sock *s = d->d_sock; nni_pipe *p; - if (nni_atomic_flag_test_and_set(&d->d_closing)) { - return; - } - - nni_dialer_stop(d); - nni_mtx_lock(&s->s_mx); NNI_LIST_FOREACH (&d->d_pipes, p) { nni_pipe_close(p); } + nni_list_node_remove(&d->d_node); nni_mtx_unlock(&s->s_mx); -} - -static void dialer_reap(void *); - -static nni_reap_list dialer_reap_list = { - .rl_offset = offsetof(nni_dialer, d_reap), - .rl_func = dialer_reap, -}; - -static void -dialer_reap(void *arg) -{ - nni_dialer *d = arg; - nni_sock *s = d->d_sock; #ifdef NNG_ENABLE_STATS nni_stat_unregister(&d->st_root); #endif - - nni_mtx_lock(&s->s_mx); - if (!nni_list_empty(&d->d_pipes)) { - nni_pipe *p; - // This should already have been done, but be certain! - NNI_LIST_FOREACH (&d->d_pipes, p) { - nni_pipe_close(p); - } - nni_mtx_unlock(&s->s_mx); - // Go back to the end of reap list. - nni_dialer_reap(d); - return; - } - - nni_mtx_unlock(&s->s_mx); - - nni_sock_rele(s); - - nni_dialer_destroy(d); -} - -void -nni_dialer_reap(nni_dialer *d) -{ - nni_reap(&dialer_reap_list, d); + nni_sock_rele(d->d_sock); } void @@ -1463,61 +1375,17 @@ nni_listener_shutdown(nni_listener *l) nni_sock *s = l->l_sock; nni_pipe *p; - if (nni_atomic_flag_test_and_set(&l->l_closing)) { - return; - } - - nni_listener_stop(l); - nni_mtx_lock(&s->s_mx); NNI_LIST_FOREACH (&l->l_pipes, p) { nni_pipe_close(p); } + nni_list_node_remove(&l->l_node); nni_mtx_unlock(&s->s_mx); -} - -static void listener_reap(void *); - -static nni_reap_list listener_reap_list = { - .rl_offset = offsetof(nni_listener, l_reap), - .rl_func = listener_reap, -}; - -static void -listener_reap(void *arg) -{ - nni_listener *l = arg; - nni_sock *s = l->l_sock; #ifdef NNG_ENABLE_STATS nni_stat_unregister(&l->st_root); #endif - - nni_mtx_lock(&s->s_mx); - if (!nni_list_empty(&l->l_pipes)) { - nni_pipe *p; - // This should already have been done, but be certain! - NNI_LIST_FOREACH (&l->l_pipes, p) { - nni_pipe_close(p); - } - nni_mtx_unlock(&s->s_mx); - // Go back to the end of reap list. - nni_reap(&listener_reap_list, l); - return; - } - - nni_list_node_remove(&l->l_node); - nni_mtx_unlock(&s->s_mx); - nni_sock_rele(s); - - nni_listener_destroy(l); -} - -void -nni_listener_reap(nni_listener *l) -{ - nni_reap(&listener_reap_list, l); } void diff --git a/src/core/sockimpl.h b/src/core/sockimpl.h index 801ef7b1b..58e663ff6 100644 --- a/src/core/sockimpl.h +++ b/src/core/sockimpl.h @@ -1,5 +1,5 @@ // -// Copyright 2023 Staysail Systems, Inc. +// Copyright 2024 Staysail Systems, Inc. // Copyright 2018 Capitar IT Group BV // // This software is supplied under the terms of the MIT License, a @@ -23,10 +23,6 @@ struct nni_dialer { nni_list_node d_node; // per socket list nni_sock *d_sock; nni_pipe *d_pipe; // active pipe (for re-dialer) - int d_ref; - bool d_closed; // full shutdown - nni_atomic_flag d_closing; - nni_atomic_flag d_started; nni_mtx d_mtx; nni_list d_pipes; nni_aio *d_user_aio; @@ -35,8 +31,11 @@ struct nni_dialer { nni_duration d_maxrtime; // maximum time for reconnect nni_duration d_currtime; // current time for reconnect nni_duration d_inirtime; // initial time for reconnect - nni_reap_node d_reap; nng_url d_url; + nni_reap_node d_reap; + nni_atomic_flag d_closing; + nni_atomic_flag d_started; + nni_refcnt d_refcnt; #ifdef NNG_ENABLE_STATS nni_stat_item st_root; @@ -63,15 +62,14 @@ struct nni_listener { uint32_t l_id; // endpoint id nni_list_node l_node; // per socket list nni_sock *l_sock; - int l_ref; - bool l_closed; // full shutdown - nni_atomic_flag l_closing; // close started (shutdown) - nni_atomic_flag l_started; nni_list l_pipes; nni_aio l_acc_aio; nni_aio l_tmo_aio; - nni_reap_node l_reap; nng_url l_url; + nni_reap_node l_reap; + nni_atomic_flag l_closing; // close started (shutdown) + nni_atomic_flag l_started; + nni_refcnt l_refcnt; #ifdef NNG_ENABLE_STATS nni_stat_item st_root; @@ -120,23 +118,15 @@ struct nni_pipe { #endif }; -extern int nni_sock_add_dialer(nni_sock *, nni_dialer *); -extern int nni_sock_add_listener(nni_sock *, nni_listener *); -extern void nni_sock_remove_listener(nni_listener *); -extern void nni_sock_remove_dialer(nni_dialer *); +extern int nni_sock_add_dialer(nni_sock *, nni_dialer *); +extern int nni_sock_add_listener(nni_sock *, nni_listener *); extern void nni_dialer_add_pipe(nni_dialer *, void *); extern void nni_dialer_shutdown(nni_dialer *); -extern void nni_dialer_reap(nni_dialer *); -extern void nni_dialer_destroy(nni_dialer *); extern void nni_dialer_timer_start(nni_dialer *); -extern void nni_dialer_stop(nni_dialer *); extern void nni_listener_add_pipe(nni_listener *, void *); extern void nni_listener_shutdown(nni_listener *); -extern void nni_listener_reap(nni_listener *); -extern void nni_listener_destroy(nni_listener *); -extern void nni_listener_stop(nni_listener *); extern void nni_pipe_remove(nni_pipe *); extern bool nni_pipe_is_closed(nni_pipe *); diff --git a/src/nng.c b/src/nng.c index 2276f2e1a..69de2542d 100644 --- a/src/nng.c +++ b/src/nng.c @@ -501,6 +501,8 @@ nng_dial(nng_socket sid, const char *addr, nng_dialer *dp, int flags) } if ((rv = nni_dialer_start(d, flags)) != 0) { nni_dialer_close(d); + nni_dialer_rele(d); + nni_sock_rele(s); return (rv); } if (dp != NULL) { @@ -509,6 +511,7 @@ nng_dial(nng_socket sid, const char *addr, nng_dialer *dp, int flags) *dp = did; } nni_dialer_rele(d); + nni_sock_rele(s); return (0); } @@ -528,6 +531,8 @@ nng_dial_url(nng_socket sid, const nng_url *url, nng_dialer *dp, int flags) } if ((rv = nni_dialer_start(d, flags)) != 0) { nni_dialer_close(d); + nni_dialer_rele(d); + nni_sock_rele(s); return (rv); } if (dp != NULL) { @@ -536,6 +541,7 @@ nng_dial_url(nng_socket sid, const nng_url *url, nng_dialer *dp, int flags) *dp = did; } nni_dialer_rele(d); + nni_sock_rele(s); return (0); } @@ -555,6 +561,8 @@ nng_listen(nng_socket sid, const char *addr, nng_listener *lp, int flags) } if ((rv = nni_listener_start(l, flags)) != 0) { nni_listener_close(l); + nni_listener_rele(l); + nni_sock_rele(s); return (rv); } @@ -564,6 +572,7 @@ nng_listen(nng_socket sid, const char *addr, nng_listener *lp, int flags) *lp = lid; } nni_listener_rele(l); + nni_sock_rele(s); return (rv); } @@ -583,6 +592,8 @@ nng_listen_url(nng_socket sid, const nng_url *url, nng_listener *lp, int flags) } if ((rv = nni_listener_start(l, flags)) != 0) { nni_listener_close(l); + nni_listener_rele(l); + nni_sock_rele(s); return (rv); } @@ -592,6 +603,7 @@ nng_listen_url(nng_socket sid, const nng_url *url, nng_listener *lp, int flags) *lp = lid; } nni_listener_rele(l); + nni_sock_rele(s); return (rv); } @@ -613,6 +625,7 @@ nng_listener_create(nng_listener *lp, nng_socket sid, const char *addr) lid.id = nni_listener_id(l); *lp = lid; nni_listener_rele(l); + nni_sock_rele(s); return (0); } @@ -634,6 +647,7 @@ nng_listener_create_url(nng_listener *lp, nng_socket sid, const nng_url *url) lid.id = nni_listener_id(l); *lp = lid; nni_listener_rele(l); + nni_sock_rele(s); return (0); } @@ -675,6 +689,7 @@ nng_dialer_create(nng_dialer *dp, nng_socket sid, const char *addr) did.id = nni_dialer_id(d); *dp = did; nni_dialer_rele(d); + nni_sock_rele(s); return (0); } @@ -696,6 +711,7 @@ nng_dialer_create_url(nng_dialer *dp, nng_socket sid, const nng_url *url) did.id = nni_dialer_id(d); *dp = did; nni_dialer_rele(d); + nni_sock_rele(s); return (0); } @@ -1048,6 +1064,7 @@ nng_dialer_close(nng_dialer did) return (rv); } nni_dialer_close(d); + nni_dialer_rele(d); return (0); } @@ -1061,6 +1078,7 @@ nng_listener_close(nng_listener lid) return (rv); } nni_listener_close(l); + nni_listener_rele(l); return (0); }