#include "Internal.h" #include "Codemap.h" #include #include struct CgeThreadContext { CgeThreadCallback callback; void *data; }; static void *threadRun(void *context) { CgeThreadCallback callback; void *data; callback = ((struct CgeThreadContext *)context)->callback; data = ((struct CgeThreadContext *)context)->data; free(context); callback(data); pthread_exit(0); } static int threadInit(CgeThread *thread, size_t stack, CgeThreadCallback callback, void *data, int *result) { struct CgeThreadContext *context; int code; context = malloc(sizeof(*context)); if (!context) { if (result) *result = CGE_THREAD_EOOM; return 0; } context->callback = callback; context->data = data; if (stack) { pthread_attr_t attributes; if (stack < PTHREAD_STACK_MIN) stack = PTHREAD_STACK_MIN; pthread_attr_init(&attributes); pthread_attr_setstacksize(&attributes, stack); code = errorToErrorCode(pthread_create(&thread->handle, &attributes, threadRun, context)); pthread_attr_destroy(&attributes); } else code = errorToErrorCode(pthread_create(&thread->handle, NULL, threadRun, context)); if (result) *result = code; return code == CGE_THREAD_EOK; } CgeThread *CgeThreadNew(size_t stack, CgeThreadCallback callback, void *data, int *result) { CgeThread *thread; int code = CGE_THREAD_EOOM; thread = malloc(sizeof(CgeThread)); if (thread && threadInit(thread, stack, callback, data, &code)) { free(thread); return NULL; } if (result) *result = code; return thread; } int CgeThreadJoin(CgeThread *thread, int *result) { int code; code = errorToErrorCode(pthread_join(thread->handle, NULL)); free(thread); if (result) *result = code; return code == CGE_THREAD_EOK; } int CgeThreadDetach(CgeThread *thread, int *result) { int code; code = errorToErrorCode(pthread_detach(thread->handle)); free(thread); if (result) *result = code; return code == CGE_THREAD_EOK; } void CgeThreadSleep(uint32_t timeout) { struct timespec ts; int result; ts.tv_sec = timeout / 1000; ts.tv_nsec = (timeout % 1000) * 1000000; do { result = nanosleep(&ts, &ts); } while (result && errno == EINTR); }