diff --git a/engine/client/sys_linux.c b/engine/client/sys_linux.c index 6e87b8eb2..5c2a54c8e 100644 --- a/engine/client/sys_linux.c +++ b/engine/client/sys_linux.c @@ -590,17 +590,34 @@ void Sys_SaveClipboard(char *text) { /* Thread creation calls */ typedef void *(*pfunction_t)(void *); -qboolean Sys_CreateThread(int (*func)(void *), void *args, int stacksize) +void *Sys_CreateThread(int (*func)(void *), void *args, int stacksize) { - pthread_t thread; + pthread_t *thread; pthread_attr_t attr; - + + thread = (pthread_t *)malloc(sizeof(pthread_t)); + if (!thread) + return NULL; + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); if (stacksize < PTHREAD_STACK_MIN) stacksize = PTHREAD_STACK_MIN; pthread_attr_setstacksize(&attr, stacksize); + if (pthread_create(thread, &attr, (pfunction_t)func, args)) + { + free(thread); + thread = NULL; + } + pthread_attr_destroy(&attr); - return !pthread_create(&thread, &attr, (pfunction_t)func, args); + return (void *)thread; +} + +void Sys_WaitOnThread(void *thread) +{ + pthread_join((pthread_t *)thread, NULL); + free(thread); } /* Mutex calls */ diff --git a/engine/client/sys_morphos.c b/engine/client/sys_morphos.c index fb23b4637..879b4d1d7 100755 --- a/engine/client/sys_morphos.c +++ b/engine/client/sys_morphos.c @@ -437,7 +437,8 @@ void Sys_LowFPPrecision (void) #ifdef MULTITHREAD /* Everything here is stubbed because I don't know MorphOS */ /* Thread creation calls */ -qboolean Sys_CreateThread(int (*func)(void *), void *args, int stacksize) { return FALSE; } +void *Sys_CreateThread(int (*func)(void *), void *args, int stacksize) { return NULL; } +void Sys_WaitOnThread(void *thread) {} /* Mutex calls */ void *Sys_CreateMutex() { return NULL; } qboolean Sys_TryLockMutex(void *mutex) { return FALSE; } diff --git a/engine/client/sys_sdl.c b/engine/client/sys_sdl.c index 09cdba907..7fd9b0f44 100644 --- a/engine/client/sys_sdl.c +++ b/engine/client/sys_sdl.c @@ -352,12 +352,18 @@ void Sys_SaveClipboard(char *text) #ifdef MULTITHREAD /* Thread creation calls */ -qboolean Sys_CreateThread(int (*func)(void *), void *args, int stacksize) +void *Sys_CreateThread(int (*func)(void *), void *args, int stacksize) { // SDL threads do not support setting thread stack size - return SDL_CreateThread(func, args) != NULL; + return (void *)SDL_CreateThread(func, args); } +void Sys_WaitOnThread(void *thread) +{ + SDL_WaitThread((SDL_Thread *)thread, NULL); +} + + /* Mutex calls */ // SDL mutexes don't have try-locks for mutexes in the spec so we stick with 1-value semaphores void *Sys_CreateMutex() diff --git a/engine/client/sys_win.c b/engine/client/sys_win.c index 9d89fbeb5..704e5d025 100644 --- a/engine/client/sys_win.c +++ b/engine/client/sys_win.c @@ -33,7 +33,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define DDActive 0 #endif - +#ifdef MULTITHREAD +#include +#endif @@ -1367,25 +1369,43 @@ DWORD WINAPI threadwrapper(void *args) tw.args = ((threadwrap_t *)args)->args; free(args); - tw.func(tw.args); + tw.func(tw.args); +#ifndef WIN32CRTDLL + _endthreadex(0); +#endif return 0; } -qboolean Sys_CreateThread(int (*func)(void *), void *args, int stacksize) +void *Sys_CreateThread(int (*func)(void *), void *args, int stacksize) { threadwrap_t *tw = (threadwrap_t *)malloc(sizeof(threadwrap_t)); + HANDLE handle; + + if (!tw) + return NULL; stacksize += 128; // wrapper overhead, also prevent default stack size tw->func = func; tw->args = args; - if (!CreateThread(NULL, stacksize, &threadwrapper, (void *)tw, 0, NULL)) +#ifdef WIN32CRTDLL + handle = (HANDLE)CreateThread(NULL, stacksize, &threadwrapper, (void *)tw, 0, NULL); +#else + handle = (HANDLE)_beginthreadex(NULL, stacksize, &threadwrapper, (void *)tw, 0, NULL); +#endif + if (!handle) { free(tw); - return FALSE; + return NULL; } - return TRUE; + return (void *)handle; +} + +void Sys_WaitOnThread(void *thread) +{ + WaitForSingleObject((HANDLE)thread, INFINITE); + CloseHandle((HANDLE)thread); } /* Mutex calls */ diff --git a/engine/server/sv_sys_unix.c b/engine/server/sv_sys_unix.c index bd8f3dcf8..5e4ffac84 100644 --- a/engine/server/sv_sys_unix.c +++ b/engine/server/sv_sys_unix.c @@ -866,17 +866,34 @@ void Sys_ServerActivity(void) /* Thread creation calls */ typedef void *(*pfunction_t)(void *); -qboolean Sys_CreateThread(int (*func)(void *), void *args, int stacksize) +void *Sys_CreateThread(int (*func)(void *), void *args, int stacksize) { - pthread_t thread; + pthread_t *thread; pthread_attr_t attr; - + + thread = (pthread_t *)malloc(sizeof(pthread_t)); + if (!thread) + return NULL; + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); if (stacksize < PTHREAD_STACK_MIN) stacksize = PTHREAD_STACK_MIN; pthread_attr_setstacksize(&attr, stacksize); + if (pthread_create(thread, &attr, (pfunction_t)func, args)) + { + free(thread); + thread = NULL; + } + pthread_attr_destroy(&attr); - return !pthread_create(&thread, &attr, (pfunction_t)func, args); + return (void *)thread; +} + +void Sys_WaitOnThread(void *thread) +{ + pthread_join((pthread_t *)thread, NULL); + free(thread); } /* Mutex calls */ diff --git a/engine/server/sv_sys_win.c b/engine/server/sv_sys_win.c index 1eb943bbd..cd2dc0e29 100644 --- a/engine/server/sv_sys_win.c +++ b/engine/server/sv_sys_win.c @@ -26,6 +26,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include #include +#ifdef MULTITHREAD +#include +#endif + #ifndef MINIMAL //#define USESERVICE #endif @@ -1230,25 +1234,43 @@ DWORD WINAPI threadwrapper(void *args) tw.args = ((threadwrap_t *)args)->args; free(args); - tw->func(tw->args); + tw.func(tw.args); +#ifndef WIN32CRTDLL + _endthreadex(0); +#endif return 0; } -qboolean Sys_CreateThread(int (*func)(void *), void *args, int stacksize) +void *Sys_CreateThread(int (*func)(void *), void *args, int stacksize) { threadwrap_t *tw = (threadwrap_t *)malloc(sizeof(threadwrap_t)); + HANDLE handle; + + if (!tw) + return NULL; stacksize += 128; // wrapper overhead, also prevent default stack size tw->func = func; tw->args = args; - if (!CreateThread(NULL, stacksize, &threadwrapper, (void *)tw, 0, NULL)) +#ifdef WIN32CRTDLL + handle = (HANDLE)CreateThread(NULL, stacksize, &threadwrapper, (void *)tw, 0, NULL); +#else + handle = (HANDLE)_beginthreadex(NULL, stacksize, &threadwrapper, (void *)tw, 0, NULL); +#endif + if (!handle) { free(tw); - return FALSE; + return NULL; } - return TRUE; + return (void *)handle; +} + +void Sys_WaitOnThread(void *thread) +{ + WaitForSingleObject((HANDLE)thread, INFINITE); + CloseHandle((HANDLE)thread); } /* Mutex calls */