Files
flexnbd-c/src/server/flexthread.c
2018-02-20 10:05:35 +00:00

74 lines
1.5 KiB
C

#include "flexthread.h"
#include "util.h"
#include <pthread.h>
struct flexthread_mutex *flexthread_mutex_create(void)
{
struct flexthread_mutex *ftm =
xmalloc(sizeof(struct flexthread_mutex));
FATAL_UNLESS(0 == pthread_mutex_init(&ftm->mutex, NULL),
"Mutex initialisation failed");
return ftm;
}
void flexthread_mutex_destroy(struct flexthread_mutex *ftm)
{
NULLCHECK(ftm);
if (flexthread_mutex_held(ftm)) {
flexthread_mutex_unlock(ftm);
} else if ((pthread_t) NULL != ftm->holder) {
/* This "should never happen": if we can try to destroy
* a mutex currently held by another thread, there's a
* logic bug somewhere. I know the test here is racy,
* but there's not a lot we can do about it at this
* point.
*/
fatal("Attempted to destroy a flexthread_mutex"
" held by another thread!");
}
FATAL_UNLESS(0 == pthread_mutex_destroy(&ftm->mutex),
"Mutex destroy failed");
free(ftm);
}
int flexthread_mutex_lock(struct flexthread_mutex *ftm)
{
NULLCHECK(ftm);
int failure = pthread_mutex_lock(&ftm->mutex);
if (0 == failure) {
ftm->holder = pthread_self();
}
return failure;
}
int flexthread_mutex_unlock(struct flexthread_mutex *ftm)
{
NULLCHECK(ftm);
pthread_t orig = ftm->holder;
ftm->holder = (pthread_t) NULL;
int failure = pthread_mutex_unlock(&ftm->mutex);
if (0 != failure) {
ftm->holder = orig;
}
return failure;
}
int flexthread_mutex_held(struct flexthread_mutex *ftm)
{
NULLCHECK(ftm);
return pthread_self() == ftm->holder;
}