aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2017-06-21 14:59:11 -0700
committerGarrett D'Amore <garrett@damore.org>2017-06-21 14:59:11 -0700
commit815926bb8a8c206ce64be33de5c24be6ddcbe6f7 (patch)
treeadddb553af838b0297191b2741a21d4959e2cd5b /src
parent763b8deee1fd38566b85d4745a83adae245d9b26 (diff)
downloadnng-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.c7
-rw-r--r--src/nng.h10
-rw-r--r--src/platform/posix/posix_thread.c23
3 files changed, 31 insertions, 9 deletions
diff --git a/src/nng.c b/src/nng.c
index 81e21ea2..59c003a7 100644
--- a/src/nng.c
+++ b/src/nng.c
@@ -37,6 +37,13 @@ nng_open(nng_socket *sidp, uint16_t proto)
}
+void
+nng_fini(void)
+{
+ nni_fini();
+}
+
+
int
nng_shutdown(nng_socket sid)
{
diff --git a/src/nng.h b/src/nng.h
index 5c1a2322..875bf995 100644
--- a/src/nng.h
+++ b/src/nng.h
@@ -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);