diff options
| author | Garrett D'Amore <garrett@damore.org> | 2016-12-13 22:41:35 -0800 |
|---|---|---|
| committer | Garrett D'Amore <garrett@damore.org> | 2016-12-13 22:41:35 -0800 |
| commit | ec9f917101371baaae34ca10ae952392c2c2343d (patch) | |
| tree | 9ad7b85748d4d70248c7e720e5e3045ef2d77f6b /src/platform/posix/posix_thread.h | |
| parent | 4919519754a0b5aee826add75273c291c33c4b5f (diff) | |
| download | nng-ec9f917101371baaae34ca10ae952392c2c2343d.tar.gz nng-ec9f917101371baaae34ca10ae952392c2c2343d.tar.bz2 nng-ec9f917101371baaae34ca10ae952392c2c2343d.zip | |
More comments, and detection of fork-reentrancy. Much effort was spent
trying to come to a fork-safe solution, but ultimately we gave up.
Diffstat (limited to 'src/platform/posix/posix_thread.h')
| -rw-r--r-- | src/platform/posix/posix_thread.h | 56 |
1 files changed, 55 insertions, 1 deletions
diff --git a/src/platform/posix/posix_thread.h b/src/platform/posix/posix_thread.h index 239959f8..27ad888f 100644 --- a/src/platform/posix/posix_thread.h +++ b/src/platform/posix/posix_thread.h @@ -37,8 +37,23 @@ struct nni_thread { pthread_t tid; + void *arg; + void (*func)(void *); }; +static pthread_mutex_t plat_lock = PTHREAD_MUTEX_INITIALIZER; +static int plat_init = 0; +static int plat_fork = 0; + +static void * +thrfunc(void *arg) +{ + nni_thread_t thr = arg; + + thr->func(thr->arg); + return (NULL); +} + int nni_thread_create(nni_thread_t *tp, void (*fn)(void *), void *arg) { @@ -48,7 +63,10 @@ nni_thread_create(nni_thread_t *tp, void (*fn)(void *), void *arg) if ((thr = nni_alloc(sizeof (*thr))) == NULL) { return (NNG_ENOMEM); } - if ((rv = pthread_create(&thr->tid, NULL, (void *)fn, arg)) != 0) { + thr->func = fn; + thr->arg = arg; + + if ((rv = pthread_create(&thr->tid, thr, thrfunc, arg)) != 0) { nni_free(thr, sizeof (*thr)); return (NNG_ENOMEM); } @@ -65,3 +83,39 @@ nni_thread_reap(nni_thread_t thr) } nni_free(thr, sizeof (*thr)); } + +void +atfork_child(void) +{ + plat_fork = 1; +} + +int +nni_platform_init(void) +{ + if (plat_fork) { + nni_panic("nng is fork-reentrant safe"); + } + if (plat_init) { + return (0); /* fast path */ + } + pthread_mutex_lock(&plat_lock); + if (plat_init) { /* check again under the lock to be sure */ + pthread_mutex_unlock(&plat_lock); + return (0); + } + if (pthread_atfork(NULL, NULL, atfork_child) != 0) { + pthread_mutex_unlock(&plat_lock); + return (NNG_ENOMEM); + } + plat_init = 1; + pthread_mutex_unlock(&plat_lock); + + return (0); +} + +void +nni_platform_fini(void) +{ + /* XXX: NOTHING *YET* */ +}
\ No newline at end of file |
