#include "thread/Blocker.h" #include #include #include #include #ifndef BLOCKER_COUNT_MAX #define BLOCKER_COUNT_MAX 8 #endif typedef struct PtBlocker { pthread_mutex_t mutex; pthread_cond_t cond; } PtBlocker; // TODO: dynamic list? static PtBlocker* blockers[BLOCKER_COUNT_MAX] = {NULL}; BlockerHandle createBlocker(void) { BlockerHandle id = 0; while (blockers[id] != NULL && id < BLOCKER_COUNT_MAX) { ++id; } if (id == BLOCKER_COUNT_MAX) { return -1; } blockers[id] = calloc(1, sizeof(PtBlocker)); return id; } void lockBlocker(BlockerHandle id) { pthread_mutex_lock(&blockers[id]->mutex); pthread_cond_wait(&blockers[id]->cond, &blockers[id]->mutex); pthread_mutex_unlock(&blockers[id]->mutex); } enum PTB_TIMEOUT_STATUS lockBlockerTimed(BlockerHandle id, uint32_t timeoutMs) { enum PTB_TIMEOUT_STATUS status = PTB_TIMEOUT; int waitResult = 0; struct timespec timeout; clock_gettime(CLOCK_REALTIME, &timeout); timeout.tv_sec += timeoutMs / 1000; timeout.tv_nsec += (timeoutMs % 1000) * 1000000; pthread_mutex_lock(&blockers[id]->mutex); waitResult = pthread_cond_timedwait(&blockers[id]->cond, &blockers[id]->mutex, &timeout); if (waitResult == 0) { status = PTB_NO_TIMEOUT; } pthread_mutex_unlock(&blockers[id]->mutex); return status; } void notifyBlocker(BlockerHandle id) { pthread_mutex_lock(&blockers[id]->mutex); pthread_cond_signal(&blockers[id]->cond); pthread_mutex_unlock(&blockers[id]->mutex); } void freeBlocker(BlockerHandle* id) { if (*id == -1) { return; } pthread_mutex_destroy(&blockers[*id]->mutex); pthread_cond_destroy(&blockers[*id]->cond); free(blockers[*id]); blockers[*id] = NULL; *id = -1; }