#include "flexthread.h" #include "util.h" #include 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; }