115 lines
2.8 KiB
C
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 |