aboutsummaryrefslogtreecommitdiff
path: root/src/platform/posix
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2016-12-13 22:41:35 -0800
committerGarrett D'Amore <garrett@damore.org>2016-12-13 22:41:35 -0800
commitec9f917101371baaae34ca10ae952392c2c2343d (patch)
tree9ad7b85748d4d70248c7e720e5e3045ef2d77f6b /src/platform/posix
parent4919519754a0b5aee826add75273c291c33c4b5f (diff)
downloadnng-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')
-rw-r--r--src/platform/posix/posix_synch.h18
-rw-r--r--src/platform/posix/posix_thread.h56
2 files changed, 61 insertions, 13 deletions
diff --git a/src/platform/posix/posix_synch.h b/src/platform/posix/posix_synch.h
index 94058d32..d3e44411 100644
--- a/src/platform/posix/posix_synch.h
+++ b/src/platform/posix/posix_synch.h
@@ -85,11 +85,6 @@ nni_mutex_destroy(nni_mutex_t m)
if (pthread_mutex_destroy(&m->mx) != 0) {
nni_panic("pthread_mutex_destroy failed");
}
- /*
- * If destroy fails for some reason, we can't really do
- * anything about it. This would actually represent a programming
- * bug, and the right thing to do here would be to panic.
- */
nni_free(m, sizeof (*m));
}
@@ -183,7 +178,6 @@ nni_cond_create(nni_cond_t *cvp, nni_mutex_t mx)
nni_free(c, sizeof (*c));
return (NNG_ENOMEM);
}
-
*cvp = c;
return (0);
}
@@ -232,12 +226,12 @@ nni_cond_timedwait(nni_cond_t c, uint64_t usec)
ts.tv_sec = usec / 1000000;
ts.tv_nsec = (usec % 10000) * 1000;
- if ((rv = pthread_cond_timedwait(&c->cv, c->mx, &ts)) != 0) {
- if (rv == ETIMEDOUT) {
- return (NNG_ETIMEDOUT);
- } else {
- nni_panic("pthread_cond_timedwait returned %d", rv);
- }
+ rv = pthread_cond_timedwait(&c->cv, c->mx, &ts);
+
+ if (rv == ETIMEDOUT) {
+ return (NNG_ETIMEDOUT);
+ } else if (rv != 0) {
+ nni_panic("pthread_cond_timedwait returned %d", rv);
}
return (0);
}
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