#include "lib/lock/compat_mutex.h"
#include "lib/cc/compat_compiler.h"
#include "lib/err/torerr.h"
static pthread_mutexattr_t attr_recursive;
static int attr_initialized = 0;
void
tor_locking_init(void)
{
if (!attr_initialized) {
pthread_mutexattr_init(&attr_recursive);
pthread_mutexattr_settype(&attr_recursive, PTHREAD_MUTEX_RECURSIVE);
attr_initialized = 1;
}
}
void
tor_mutex_init(tor_mutex_t *mutex)
{
if (PREDICT_UNLIKELY(!attr_initialized))
tor_locking_init(); const int err = pthread_mutex_init(&mutex->mutex, &attr_recursive);
if (PREDICT_UNLIKELY(err)) {
raw_assert_unreached_msg("Error creating a mutex.");
}
}
void
tor_mutex_init_nonrecursive(tor_mutex_t *mutex)
{
int err;
if (!attr_initialized)
tor_locking_init(); err = pthread_mutex_init(&mutex->mutex, NULL);
if (PREDICT_UNLIKELY(err)) {
raw_assert_unreached_msg("Error creating a mutex.");
}
}
void
tor_mutex_acquire(tor_mutex_t *m)
{
int err;
raw_assert(m);
err = pthread_mutex_lock(&m->mutex);
if (PREDICT_UNLIKELY(err)) {
raw_assert_unreached_msg("Error locking a mutex.");
}
}
void
tor_mutex_release(tor_mutex_t *m)
{
int err;
raw_assert(m);
err = pthread_mutex_unlock(&m->mutex);
if (PREDICT_UNLIKELY(err)) {
raw_assert_unreached_msg("Error unlocking a mutex.");
}
}
void
tor_mutex_uninit(tor_mutex_t *m)
{
int err;
raw_assert(m);
tor_mutex_acquire(m);
tor_mutex_release(m);
err = pthread_mutex_destroy(&m->mutex);
if (PREDICT_UNLIKELY(err)) {
raw_assert_unreached_msg("Error destroying a mutex.");
}
}