diff options
Diffstat (limited to 'src/mutex.c')
-rw-r--r-- | src/mutex.c | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/src/mutex.c b/src/mutex.c new file mode 100644 index 0000000..12a4f4a --- /dev/null +++ b/src/mutex.c @@ -0,0 +1,97 @@ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <pthread.h> +#include <errno.h> + +#include "macro.h" +#include "malloc.h" +#include "mutex.h" + +struct sa_mutex { + pthread_mutex_t mutex; +}; + +struct sa_cond { + pthread_cond_t cond; +}; + +sa_mutex_t* sa_mutex_new(int recursive) { + sa_mutex_t *m; + pthread_mutexattr_t attr; + + pthread_mutexattr_init(&attr); + + if (recursive) + sa_assert_success(pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE)); + + if (!(m = sa_new(sa_mutex_t, 1))) + return NULL; + + sa_assert_success(pthread_mutex_init(&m->mutex, &attr)); + return m; +} + +void sa_mutex_free(sa_mutex_t *m) { + sa_assert(m); + + sa_assert_success(pthread_mutex_destroy(&m->mutex)); + sa_free(m); +} + +void sa_mutex_lock(sa_mutex_t *m) { + sa_assert(m); + + sa_assert_success(pthread_mutex_lock(&m->mutex)); +} + +int sa_mutex_try_lock(sa_mutex_t *m) { + int e; + sa_assert(m); + + if ((e = pthread_mutex_trylock(&m->mutex)) == 0) + return 1; + + sa_assert(e == EBUSY); + return 0; +} + +void sa_mutex_unlock(sa_mutex_t *m) { + sa_assert(m); + + sa_assert_success(pthread_mutex_unlock(&m->mutex)); +} + +sa_cond_t *sa_cond_new(void) { + sa_cond_t *c; + + if (!(c = sa_new(sa_cond_t, 1))) + return NULL; + + sa_assert_success(pthread_cond_init(&c->cond, NULL)); + return c; +} + +void sa_cond_free(sa_cond_t *c) { + sa_assert(c); + + sa_assert_success(pthread_cond_destroy(&c->cond)); + sa_free(c); +} + +void sa_cond_signal(sa_cond_t *c, int broadcast) { + sa_assert(c); + + if (broadcast) + sa_assert_success(pthread_cond_broadcast(&c->cond)); + else + sa_assert_success(pthread_cond_signal(&c->cond)); +} + +int sa_cond_wait(sa_cond_t *c, sa_mutex_t *m) { + sa_assert(c); + sa_assert(m); + + return pthread_cond_wait(&c->cond, &m->mutex); +} |