diff options
| author | Garrett D'Amore <garrett@damore.org> | 2016-12-10 22:48:57 -0800 |
|---|---|---|
| committer | Garrett D'Amore <garrett@damore.org> | 2016-12-10 22:48:57 -0800 |
| commit | 6d8cabe8f4f1abc304c60dd832e05f18f069451b (patch) | |
| tree | fe43d68bb4fb4357b60cb5d85b15de7736ea08ff /src | |
| parent | 6a7f5a2a113cd63add78ad72601683529899b2ed (diff) | |
| download | nng-6d8cabe8f4f1abc304c60dd832e05f18f069451b.tar.gz nng-6d8cabe8f4f1abc304c60dd832e05f18f069451b.tar.bz2 nng-6d8cabe8f4f1abc304c60dd832e05f18f069451b.zip | |
Condition variable implementation.
Diffstat (limited to 'src')
| -rw-r--r-- | src/nng.h | 8 | ||||
| -rw-r--r-- | src/platform/platform.h | 12 | ||||
| -rw-r--r-- | src/platform/posix/posix_synch.h | 61 |
3 files changed, 71 insertions, 10 deletions
@@ -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); +} |
