diff options
| author | Garrett D'Amore <garrett@damore.org> | 2016-12-22 13:22:18 -0800 |
|---|---|---|
| committer | Garrett D'Amore <garrett@damore.org> | 2016-12-22 13:22:18 -0800 |
| commit | ee969ad99dc1e07e1c38876223e7aed13463b121 (patch) | |
| tree | 40bde325d041532661e7dcc3441185aca7701e53 /src/platform/posix/posix_synch.c | |
| parent | 6c1325a2b17548a4249d26a846bc32b95b7d747d (diff) | |
| download | nng-ee969ad99dc1e07e1c38876223e7aed13463b121.tar.gz nng-ee969ad99dc1e07e1c38876223e7aed13463b121.tar.bz2 nng-ee969ad99dc1e07e1c38876223e7aed13463b121.zip | |
Synchronization enhancements - inproc & msgqueue. Absolute waits...
Diffstat (limited to 'src/platform/posix/posix_synch.c')
| -rw-r--r-- | src/platform/posix/posix_synch.c | 120 |
1 files changed, 57 insertions, 63 deletions
diff --git a/src/platform/posix/posix_synch.c b/src/platform/posix/posix_synch.c index a3129f62..c0a2721c 100644 --- a/src/platform/posix/posix_synch.c +++ b/src/platform/posix/posix_synch.c @@ -1,23 +1,14 @@ -/* - * Copyright 2016 Garrett D'Amore <garrett@damore.org> - * - * This software is supplied under the terms of the MIT License, a - * copy of which should be located in the distribution where this - * file was obtained (LICENSE.txt). A copy of the license may also be - * found online at https://opensource.org/licenses/MIT. - */ - -/* - * This is more of a direct #include of a .c rather than .h file. - * But having it be a .h makes compiler rules work out properly. Do - * not include this more than once into your program, or you will - * get multiple symbols defined. - */ - -/* - * POSIX synchronization (mutexes and condition variables). This uses - * pthreads. - */ +// +// Copyright 2016 Garrett D'Amore <garrett@damore.org> +// +// This software is supplied under the terms of the MIT License, a +// copy of which should be located in the distribution where this +// file was obtained (LICENSE.txt). A copy of the license may also be +// found online at https://opensource.org/licenses/MIT. +// + +// POSIX synchronization (mutexes and condition variables). This uses +// pthreads. #include "core/nng_impl.h" @@ -51,6 +42,7 @@ nni_mutex_fini(nni_mutex *mp) } +// XXX: REMOVE THIS FUNCTION int nni_mutex_create(nni_mutex_t *mp) { @@ -62,7 +54,7 @@ nni_mutex_create(nni_mutex_t *mp) return (NNG_ENOMEM); } - /* We ask for more error checking... */ + // We ask for more error checking... if (pthread_mutexattr_init(&attr) != 0) { nni_free(m, sizeof (*m)); return (NNG_ENOMEM); @@ -87,6 +79,7 @@ nni_mutex_create(nni_mutex_t *mp) } +// XXX: REMOVE THIS FUNCTION void nni_mutex_destroy(nni_mutex_t m) { @@ -98,7 +91,7 @@ nni_mutex_destroy(nni_mutex_t m) void -nni_mutex_enter(nni_mutex_t m) +nni_mutex_enter(nni_mutex *m) { if (pthread_mutex_lock(&m->mx) != 0) { nni_panic("pthread_mutex_lock failed"); @@ -107,7 +100,7 @@ nni_mutex_enter(nni_mutex_t m) void -nni_mutex_exit(nni_mutex_t m) +nni_mutex_exit(nni_mutex *m) { if (pthread_mutex_unlock(&m->mx) != 0) { nni_panic("pthread_mutex_unlock failed"); @@ -116,7 +109,7 @@ nni_mutex_exit(nni_mutex_t m) int -nni_mutex_tryenter(nni_mutex_t m) +nni_mutex_tryenter(nni_mutex *m) { if (pthread_mutex_trylock(&m->mx) != 0) { return (NNG_EBUSY); @@ -125,51 +118,40 @@ nni_mutex_tryenter(nni_mutex_t m) } -static int -nni_cond_attr(pthread_condattr_t **attrpp) +int +nni_cond_init(nni_cond *c, nni_mutex *m) { -#if defined(NNG_USE_GETTIMEOFDAY) || NNG_USE_CLOCKID == CLOCK_REALTIME - *attrpp = NULL; + if (pthread_cond_init(&c->cv, &nni_condattr) != 0) { + // In theory could be EAGAIN, but handle like ENOMEM + nni_free(c, sizeof (*c)); + return (NNG_ENOMEM); + } + c->mx = &m->mx; return (0); +} -#else - /* In order to make this fast, avoid reinitializing attrs. */ - static pthread_condattr_t attr; - static pthread_mutex_t mx = PTHREAD_MUTEX_INITIALIZER; - static int init = 0; - int rv; - // For efficiency's sake, we try to reuse the same attr for the - // life of the library. This avoids many reallocations. Technically - // this means that we will leak the attr on exit(), but this is - // preferable to constantly allocating and reallocating it. - if (init) { - *attrpp = &attr; - return (0); +void +nni_cond_fini(nni_cond *c) +{ + if (pthread_cond_destroy(&c->cv) != 0) { + nni_panic("pthread_cond_destroy failed"); } +} - (void) pthread_mutex_lock(&mx); - while (!init) { - if ((rv = pthread_condattr_init(&attr)) != 0) { - (void) pthread_mutex_unlock(&mx); - return (NNG_ENOMEM); - } - rv = pthread_condattr_setclock(&attr, NNG_USE_CLOCKID); - if (rv != 0) { - nni_panic("condattr_setclock: %s", strerror(rv)); - } - init = 1; - } - (void) pthread_mutex_unlock(&mx); - *attrpp = &attr; - return (0); -#endif +// XXXX: REMOVE THIS FUNCTION +static int +nni_cond_attr(pthread_condattr_t **attrpp) +{ + *attrpp = NULL; + return (0); } +// XXX: REMOVE THIS FUNCTION int -nni_cond_create(nni_cond_t *cvp, nni_mutex_t mx) +nni_cond_create(nni_cond **cvp, nni_mutex *mx) { /* * By preference, we use a CLOCK_MONOTONIC version of condition @@ -196,8 +178,9 @@ nni_cond_create(nni_cond_t *cvp, nni_mutex_t mx) } +// XXX: REMOVE THIS FUNCTION void -nni_cond_destroy(nni_cond_t c) +nni_cond_destroy(nni_cond *c) { if (pthread_cond_destroy(&c->cv) != 0) { nni_panic("pthread_cond_destroy failed"); @@ -207,7 +190,7 @@ nni_cond_destroy(nni_cond_t c) void -nni_cond_signal(nni_cond_t c) +nni_cond_signal(nni_cond *c) { if (pthread_cond_signal(&c->cv) != 0) { nni_panic("pthread_cond_signal failed"); @@ -216,7 +199,7 @@ nni_cond_signal(nni_cond_t c) void -nni_cond_broadcast(nni_cond_t c) +nni_cond_broadcast(nni_cond *c) { if (pthread_cond_broadcast(&c->cv) != 0) { nni_panic("pthread_cond_broadcast failed"); @@ -225,7 +208,7 @@ nni_cond_broadcast(nni_cond_t c) void -nni_cond_wait(nni_cond_t c) +nni_cond_wait(nni_cond *c) { if (pthread_cond_wait(&c->cv, c->mx) != 0) { nni_panic("pthread_cond_wait failed"); @@ -234,7 +217,7 @@ nni_cond_wait(nni_cond_t c) int -nni_cond_timedwait(nni_cond_t c, uint64_t usec) +nni_cond_waituntil(nni_cond *c, uint64_t usec) { struct timespec ts; int rv; @@ -255,4 +238,15 @@ nni_cond_timedwait(nni_cond_t c, uint64_t usec) } +int +nni_cond_timedwait(nni_cond *c, int usec) +{ + if (usec < 0) { + nni_cond_wait(c); + return (0); + } + return (nni_cond_waituntil(c, ((uint64_t) usec) + nni_clock())); +} + + #endif |
