diff options
| author | Garrett D'Amore <garrett@damore.org> | 2019-12-26 16:23:11 -0800 |
|---|---|---|
| committer | Garrett D'Amore <garrett@damore.org> | 2019-12-26 16:56:33 -0800 |
| commit | a31df988bb59e438e0eca9f7fb057a2c8ff7b54b (patch) | |
| tree | e5f7ba187069125e227235473da6290d234aeb43 /src/platform/posix/posix_tcpdial.c | |
| parent | d590eceab74772a8d5fa50c94074b09927577ee4 (diff) | |
| download | nng-a31df988bb59e438e0eca9f7fb057a2c8ff7b54b.tar.gz nng-a31df988bb59e438e0eca9f7fb057a2c8ff7b54b.tar.bz2 nng-a31df988bb59e438e0eca9f7fb057a2c8ff7b54b.zip | |
fixes #1037 http client crashes (pthread lock bugs)
This reference counts both TCP and IPC dialers running on POSIX
configurations, as we need to take care not to destroy the dialer
until any streams associated with are completely destroyed.
Diffstat (limited to 'src/platform/posix/posix_tcpdial.c')
| -rw-r--r-- | src/platform/posix/posix_tcpdial.c | 33 |
1 files changed, 31 insertions, 2 deletions
diff --git a/src/platform/posix/posix_tcpdial.c b/src/platform/posix/posix_tcpdial.c index 457a64ea..418eb17e 100644 --- a/src/platform/posix/posix_tcpdial.c +++ b/src/platform/posix/posix_tcpdial.c @@ -31,6 +31,8 @@ struct nni_tcp_dialer { struct sockaddr_storage src; size_t srclen; nni_mtx mtx; + int refcnt; + bool fini; }; // Dialer stuff. @@ -71,12 +73,38 @@ nni_tcp_dialer_close(nni_tcp_dialer *d) nni_mtx_unlock(&d->mtx); } +static void +tcp_dialer_fini(nni_tcp_dialer *d) +{ + nni_mtx_fini(&d->mtx); + NNI_FREE_STRUCT(d); +} + void nni_tcp_dialer_fini(nni_tcp_dialer *d) { nni_tcp_dialer_close(d); - nni_mtx_fini(&d->mtx); - NNI_FREE_STRUCT(d); + nni_mtx_lock(&d->mtx); + d->fini = true; + if (d->refcnt) { + nni_mtx_unlock(&d->mtx); + return; + } + nni_mtx_unlock(&d->mtx); + tcp_dialer_fini(d); +} + +void +nni_posix_tcp_dialer_rele(nni_tcp_dialer *d) +{ + nni_mtx_lock(&d->mtx); + d->refcnt--; + if ((d->refcnt > 0) || (!d->fini)) { + nni_mtx_unlock(&d->mtx); + return; + } + nni_mtx_unlock(&d->mtx); + tcp_dialer_fini(d); } static void @@ -203,6 +231,7 @@ nni_tcp_dial(nni_tcp_dialer *d, nni_aio *aio) nni_posix_pfd_set_cb(pfd, tcp_dialer_cb, c); nni_mtx_lock(&d->mtx); + d->refcnt++; if (d->closed) { rv = NNG_ECLOSED; goto error; |
