aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2016-12-10 22:48:57 -0800
committerGarrett D'Amore <garrett@damore.org>2016-12-10 22:48:57 -0800
commit6d8cabe8f4f1abc304c60dd832e05f18f069451b (patch)
treefe43d68bb4fb4357b60cb5d85b15de7736ea08ff
parent6a7f5a2a113cd63add78ad72601683529899b2ed (diff)
downloadnng-6d8cabe8f4f1abc304c60dd832e05f18f069451b.tar.gz
nng-6d8cabe8f4f1abc304c60dd832e05f18f069451b.tar.bz2
nng-6d8cabe8f4f1abc304c60dd832e05f18f069451b.zip
Condition variable implementation.
-rw-r--r--src/nng.h8
-rw-r--r--src/platform/platform.h12
-rw-r--r--src/platform/posix/posix_synch.h61
3 files changed, 71 insertions, 10 deletions
diff --git a/src/nng.h b/src/nng.h
index 1075b95a..16596fa6 100644
--- a/src/nng.h
+++ b/src/nng.h
@@ -415,9 +415,11 @@ NNG_DECL int nng_device(nng_socket_t, nng_socket_t);
* Error codes. These may happen to align to errnos used on your platform,
* but do not count on this.
*/
-#define NNG_ENOMEM (-2)
-#define NNG_EINVAL (-3)
-#define NNG_EBUSY (-4)
+#define NNG_ENOMEM (-2)
+#define NNG_EINVAL (-3)
+#define NNG_EBUSY (-4)
+#define NNG_ETIMEDOUT (-5)
+#define NNG_ECONNREFUSED (-6)
#ifdef __cplusplus
}
diff --git a/src/platform/platform.h b/src/platform/platform.h
index 05f55be9..36ec207c 100644
--- a/src/platform/platform.h
+++ b/src/platform/platform.h
@@ -26,6 +26,7 @@
#include <stdlib.h>
#include <stdint.h>
#include <stdarg.h>
+#include <string.h>
/*
* These are the APIs that a platform must implement to support nng.
@@ -95,22 +96,19 @@ void nni_cond_destroy(nni_cond_t);
* nni_cond_broadcast wakes all waiters on the condition. This should be
* called with the lock held.
*/
-int nni_cond_broadcast(nni_cond_t);
+void nni_cond_broadcast(nni_cond_t);
/*
* nni_cond_signal wakes a signal waiter.
*/
-int nni_cond_signal(nni_cond_t);
+void nni_cond_signal(nni_cond_t);
/*
* nni_condwait waits for a wake up on the condition variable. The
* associated lock is atomically released and reacquired upon wake up.
- * Callers can be spuriously woken. The return value is 0 on success,
- * or an error code. (Most implementations should never return an error.)
- * Most callers will ignore the return value. The associated lock must
- * be held.
+ * Callers can be spuriously woken. The associated lock must be held.
*/
-int nni_cond_wait(nni_cond_t);
+void nni_cond_wait(nni_cond_t);
/*
* nni_cond_timedwait waits for a wakeup on the condition variable, just
diff --git a/src/platform/posix/posix_synch.h b/src/platform/posix/posix_synch.h
index 4a3a152d..0eae133e 100644
--- a/src/platform/posix/posix_synch.h
+++ b/src/platform/posix/posix_synch.h
@@ -32,6 +32,7 @@
*/
#include <pthread.h>
+#include <time.h>
struct nni_mutex {
pthread_mutex_t mx;
@@ -141,3 +142,63 @@ nni_cond_destroy(nni_cond_t c)
}
nni_free(c, sizeof (*c));
}
+
+void
+nni_cond_signal(nni_cond_t c)
+{
+ if (pthread_cond_signal(&c->cv) != 0) {
+ nni_panic("pthread_cond_signal failed");
+ }
+}
+
+void
+nni_cond_broadcast(nni_cond_t c)
+{
+ if (pthread_cond_broadcast(&c->cv) != 0) {
+ nni_panic("pthread_cond_broadcast failed");
+ }
+}
+
+void
+nni_cond_wait(nni_cond_t c)
+{
+ if (pthread_cond_wait(&c->cv, c->mx) != 0) {
+ nni_panic("pthread_cond_wait failed");
+ }
+}
+
+int
+nni_cond_timedwait(nni_cond_t c, int msec)
+{
+ struct timespec ts;
+ int rv;
+ /* POSIX says clock_gettime exists since SUSv2 at least. */
+
+ rv = clock_gettime(CLOCK_REALTIME, &ts);
+ if (rv != 0) {
+ /*
+ * If the clock_gettime() is not working, its a problem with
+ * the platform. Arguably we could use gettimeofday instead,
+ * but for now we just panic(). We can fix this when someone
+ * finds a platform that returns ENOSYS here.
+ */
+ nni_panic("clock_gettime failed: %s", strerror(errno));
+ }
+
+ ts.tv_nsec += (msec * 1000000);
+
+ /* Normalize -- its not clear if this is strictly necessary. */
+ while (ts.tv_nsec > 1000000000) {
+ ts.tv_nsec -= 1000000000;
+ ts.tv_sec++;
+ }
+
+ 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);
+ }
+ }
+ return (0);
+}