diff options
| author | Garrett D'Amore <garrett@damore.org> | 2017-06-21 14:59:11 -0700 |
|---|---|---|
| committer | Garrett D'Amore <garrett@damore.org> | 2017-06-21 14:59:11 -0700 |
| commit | 815926bb8a8c206ce64be33de5c24be6ddcbe6f7 (patch) | |
| tree | adddb553af838b0297191b2741a21d4959e2cd5b /src | |
| parent | 763b8deee1fd38566b85d4745a83adae245d9b26 (diff) | |
| download | nng-815926bb8a8c206ce64be33de5c24be6ddcbe6f7.tar.gz nng-815926bb8a8c206ce64be33de5c24be6ddcbe6f7.tar.bz2 nng-815926bb8a8c206ce64be33de5c24be6ddcbe6f7.zip | |
Expose a library finalizer suitable for atexit().
Diffstat (limited to 'src')
| -rw-r--r-- | src/nng.c | 7 | ||||
| -rw-r--r-- | src/nng.h | 10 | ||||
| -rw-r--r-- | src/platform/posix/posix_thread.c | 23 |
3 files changed, 31 insertions, 9 deletions
@@ -37,6 +37,13 @@ nng_open(nng_socket *sidp, uint16_t proto) } +void +nng_fini(void) +{ + nni_fini(); +} + + int nng_shutdown(nng_socket sid) { @@ -55,6 +55,16 @@ typedef struct nng_stat nng_stat; // mode. NNG_DECL int nng_open(nng_socket *, uint16_t proto); +// nng_fini is used to terminate the library, freeing certain global resources. +// Its a good idea to call this with atexit() or during application shutdown. +// For most cases, this call is optional, but failure to do so may cause +// memory checkers like valgrind to incorrectly flag memory leaks. Note that +// this particular API is NOT THREADSAFE, and MUST NOT BE CALLED WHILE ANY +// OTHER APIS ARE IN USE. (It is safe however to call other functions such +// as nng_open *after* this function returns, provided that the functions do +// not run concurrently!) +NNG_DECL void nng_fini(void); + // nng_close closes the socket, terminating all activity and // closing any underlying connections and releasing any associated // resources. Memory associated with the socket is freed, so it is an diff --git a/src/platform/posix/posix_thread.c b/src/platform/posix/posix_thread.c index 72e1bcaf..0d57e7ef 100644 --- a/src/platform/posix/posix_thread.c +++ b/src/platform/posix/posix_thread.c @@ -227,46 +227,50 @@ int nni_plat_init(int (*helper)(void)) { int rv; + int devnull; if (nni_plat_forked) { - nni_panic("nng is fork-reentrant safe"); + nni_panic("nng is not fork-reentrant safe"); } if (nni_plat_inited) { return (0); // fast path } - - if ((nni_plat_devnull = open("/dev/null", O_RDONLY)) < 0) { + if ((devnull = open("/dev/null", O_RDONLY)) < 0) { return (nni_plat_errno(errno)); } + pthread_mutex_lock(&nni_plat_lock); if (nni_plat_inited) { // check again under the lock to be sure pthread_mutex_unlock(&nni_plat_lock); - (void) close(nni_plat_devnull); + close(devnull); return (0); } if (pthread_condattr_init(&nni_cvattr) != 0) { pthread_mutex_unlock(&nni_plat_lock); - (void) close(nni_plat_devnull); + (void) close(devnull); return (NNG_ENOMEM); } #if !defined(NNG_USE_GETTIMEOFDAY) && NNG_USE_CLOCKID != CLOCK_REALTIME if (pthread_condattr_setclock(&nni_cvattr, NNG_USE_CLOCKID) != 0) { pthread_mutex_unlock(&nni_plat_lock); - (void) close(nni_plat_devnull); + (void) close(devnull); return (NNG_ENOMEM); } #endif if (pthread_mutexattr_init(&nni_mxattr) != 0) { pthread_mutex_unlock(&nni_plat_lock); - (void) close(nni_plat_devnull); + pthread_condattr_destroy(&nni_cvattr); + (void) close(devnull); return (NNG_ENOMEM); } rv = pthread_mutexattr_settype(&nni_mxattr, PTHREAD_MUTEX_ERRORCHECK); if (rv != 0) { pthread_mutex_unlock(&nni_plat_lock); - (void) close(nni_plat_devnull); + (void) close(devnull); + pthread_mutexattr_destroy(&nni_mxattr); + pthread_condattr_destroy(&nni_cvattr); return (NNG_ENOMEM); } @@ -287,7 +291,7 @@ nni_plat_init(int (*helper)(void)) if (pthread_atfork(NULL, NULL, nni_atfork_child) != 0) { pthread_mutex_unlock(&nni_plat_lock); - (void) close(nni_plat_devnull); + (void) close(devnull); pthread_mutexattr_destroy(&nni_mxattr); pthread_condattr_destroy(&nni_cvattr); pthread_attr_destroy(&nni_pthread_attr); @@ -296,6 +300,7 @@ nni_plat_init(int (*helper)(void)) if ((rv = helper()) == 0) { nni_plat_inited = 1; } + nni_plat_devnull = devnull; pthread_mutex_unlock(&nni_plat_lock); return (rv); |
