Files
dusk/src/thread/thread.c
2025-08-23 10:13:49 -05:00

115 lines
2.8 KiB
C

/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "thread.h"
#include "util/memory.h"
#include "assert/assert.h"
void threadInit(thread_t *thread, const threadcallback_t callback) {
assertNotNull(thread, "Thread cannot be NULL.");
assertNotNull(callback, "Thread callback cannot be NULL.");
memoryZero(thread, sizeof(thread_t));
thread->state = THREAD_STATE_STOPPED;
thread->callback = callback;
#if THREAD_PTHREAD
thread->threadId = 0;
#endif
}
void threadStartRequest(thread_t *thread) {
assertNotNull(thread, "Thread cannot be NULL.");
threadMutexLock(&thread->stateMutex);
thread->state = THREAD_STATE_STARTING;
threadMutexUnlock(&thread->stateMutex);
#if THREAD_PTHREAD
assertTrue(thread->threadId == 0, "Thread id not 0.");
pthread_create(
&thread->threadId,
NULL,
(void * (*)(void *))threadHandler,
thread
);
pthread_detach(thread->threadId);
#endif
}
void threadStopRequest(thread_t *thread) {
assertNotNull(thread, "Thread cannot be NULL.");
threadMutexLock(&thread->stateMutex);
if(thread->state != THREAD_STATE_STOPPED) {
thread->state = THREAD_STATE_STOP_REQUESTED;
}
threadMutexUnlock(&thread->stateMutex);
}
void threadStart(thread_t *thread) {
assertNotNull(thread, "Thread cannot be NULL.");
threadStartRequest(thread);
threadMutexLock(&thread->stateMutex);
threadMutexWaitLock(&thread->stateMutex);
threadMutexUnlock(&thread->stateMutex);
printf("Thread is now running.\n");
}
void threadStop(thread_t *thread) {
assertNotNull(thread, "Thread cannot be NULL.");
threadStopRequest(thread);
threadMutexLock(&thread->stateMutex);
while(thread->state != THREAD_STATE_STOPPED) {
threadMutexWaitLock(&thread->stateMutex);
}
threadMutexUnlock(&thread->stateMutex);
}
bool_t threadShouldStop(thread_t *thread) {
bool_t state;
assertNotNull(thread, "Thread cannot be NULL.");
threadMutexLock(&thread->stateMutex);
switch(thread->state) {
case THREAD_STATE_STOPPED:
case THREAD_STATE_STOP_REQUESTED:
state = true;
break;
default:
state = false;
break;
}
threadMutexUnlock(&thread->stateMutex);
return state;
}
#if THREAD_PTHREAD
void * threadHandler(thread_t *thread) {
assertNotNull(thread, "Thread cannot be NULL.");
threadMutexLock(&thread->stateMutex);
thread->state = THREAD_STATE_RUNNING;
threadMutexSignal(&thread->stateMutex);
threadMutexUnlock(&thread->stateMutex);
// Send to callback.
thread->callback(thread);
threadMutexLock(&thread->stateMutex);
thread->state = THREAD_STATE_STOPPED;
threadMutexSignal(&thread->stateMutex);
threadMutexUnlock(&thread->stateMutex);
thread->threadId = 0;
return NULL;
}
#endif