From 0c001d5c7fd4c6c5d9ceeb55ba5fac1780b441af Mon Sep 17 00:00:00 2001 From: David Robillard Date: Thu, 18 Aug 2022 16:57:17 -0400 Subject: Fix or remove non-portable features in thread API Thread function return values are inconsistent between nearly every threading API out there. So, just ignore them entirely, and provide a typedef and sentinel value so user code can be portable. --- include/zix/thread.h | 57 +++++++++++++++++++++++++++++++++++----------------- 1 file changed, 39 insertions(+), 18 deletions(-) (limited to 'include/zix') diff --git a/include/zix/thread.h b/include/zix/thread.h index c80add0..29dee44 100644 --- a/include/zix/thread.h +++ b/include/zix/thread.h @@ -26,11 +26,34 @@ extern "C" { */ #ifdef _WIN32 +# define ZIX_THREAD_RESULT 0 +# define ZIX_THREAD_FUNC __attribute__((stdcall)) + typedef HANDLE ZixThread; +typedef DWORD ZixThreadResult; + #else +# define ZIX_THREAD_RESULT NULL +# define ZIX_THREAD_FUNC + typedef pthread_t ZixThread; +typedef void* ZixThreadResult; #endif +/** + A thread function. + + For portability reasons, the return type varies between platforms, and the + return value is ignored. Thread functions should always return + #ZIX_THREAD_RESULT. This allows thread functions to be used directly by the + system without any wrapper overhead. + + "Returning" a result, and communicating with the parent thread in general, + can be done through the pointer argument. +*/ +typedef ZIX_THREAD_FUNC +ZixThreadResult (*ZixThreadFunc)(void*); + /** Initialize `thread` to a new thread. @@ -38,35 +61,33 @@ typedef pthread_t ZixThread; as the only parameter. */ static inline ZixStatus -zix_thread_create(ZixThread* thread, - size_t stack_size, - void* (*function)(void*), - void* arg); +zix_thread_create(ZixThread* thread, + size_t stack_size, + ZixThreadFunc function, + void* arg); /// Join `thread` (block until `thread` exits) static inline ZixStatus -zix_thread_join(ZixThread thread, void** retval); +zix_thread_join(ZixThread thread); #ifdef _WIN32 static inline ZixStatus -zix_thread_create(ZixThread* thread, - size_t stack_size, - void* (*function)(void*), - void* arg) +zix_thread_create(ZixThread* thread, + size_t stack_size, + ZixThreadFunc function, + void* arg) { - *thread = CreateThread( - NULL, stack_size, (LPTHREAD_START_ROUTINE)function, arg, 0, NULL); + *thread = CreateThread(NULL, stack_size, function, arg, 0, NULL); return *thread ? ZIX_STATUS_SUCCESS : ZIX_STATUS_ERROR; } static inline ZixStatus -zix_thread_join(ZixThread thread, void** retval) +zix_thread_join(ZixThread thread) { - (void)retval; - - return WaitForSingleObject(thread, INFINITE) ? ZIX_STATUS_SUCCESS - : ZIX_STATUS_ERROR; + return (WaitForSingleObject(thread, INFINITE) == WAIT_OBJECT_0) + ? ZIX_STATUS_SUCCESS + : ZIX_STATUS_ERROR; } #else /* !defined(_WIN32) */ @@ -88,9 +109,9 @@ zix_thread_create(ZixThread* thread, } static inline ZixStatus -zix_thread_join(ZixThread thread, void** retval) +zix_thread_join(ZixThread thread) { - return pthread_join(thread, retval) ? ZIX_STATUS_ERROR : ZIX_STATUS_SUCCESS; + return pthread_join(thread, NULL) ? ZIX_STATUS_ERROR : ZIX_STATUS_SUCCESS; } #endif -- cgit v1.2.1