X-Git-Url: http://git.silcnet.org/gitweb/?p=silc.git;a=blobdiff_plain;f=lib%2Fsilcutil%2Fwin32%2Fsilcwin32thread.c;h=ca2a211207c9baf3feec507151d2eb5f4d99a63d;hp=e88a09f0c4690bbfdf9f7cddad507ef43d6d79cb;hb=382d15d447b7a95390decfa783836ae4fe255b3d;hpb=a6250a4f153e38648a1ac25d08c00f07865c17eb diff --git a/lib/silcutil/win32/silcwin32thread.c b/lib/silcutil/win32/silcwin32thread.c index e88a09f0..ca2a2112 100644 --- a/lib/silcutil/win32/silcwin32thread.c +++ b/lib/silcutil/win32/silcwin32thread.c @@ -17,8 +17,6 @@ GNU General Public License for more details. */ -/* These routines are based on GLib's WIN32 gthread implementation and - thus credits should go there. */ /* $Id$ */ #include "silcincludes.h" @@ -44,15 +42,16 @@ unsigned __stdcall silc_thread_win32_start(void *context) SilcWin32Thread thread = (SilcWin32Thread)context; TlsSetValue(silc_thread_tls, context); - thread->start_func(thread->context); - silc_thread_exit(NULL); + silc_thread_exit(thread->start_func(thread->context)); return 0; } +#endif SilcThread silc_thread_create(SilcThreadStart start_func, void *context, bool waitable) { +#ifdef SILC_THREADS SilcWin32Thread thread; unsigned id; @@ -62,8 +61,8 @@ SilcThread silc_thread_create(SilcThreadStart start_func, void *context, thread->start_func = start_func; thread->context = context; thread->waitable = waitable; - thread->thread = (HANDLE)_beginthreadex(NULL, 0, silc_thread_win32_start, - (void *)thread, 0, &id); + thread->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)silc_thread_win32_start, (void *)thread, 0, &id); + if (!thread->thread) { SILC_LOG_ERROR(("Could not create new thread")); silc_free(thread); @@ -71,28 +70,35 @@ SilcThread silc_thread_create(SilcThreadStart start_func, void *context, } return (SilcThread)thread; +#else + /* Call thread callback immediately */ + (*start_func)(context); + return NULL; +#endif } void silc_thread_exit(void *exit_value) { +#ifdef SILC_THREADS SilcWin32Thread thread = TlsGetValue(silc_thread_tls); if (thread) { /* If the thread is waitable the memory is freed only in silc_thread_wait by another thread. If not waitable, free it now. */ if (!thread->waitable) { - CloseHandle(thread->thread); + TerminateThread(thread->thread, 0); silc_free(thread); } TlsSetValue(silc_thread_tls, NULL); } - - _endthreadex(0); + ExitThread(0); +#endif } SilcThread silc_thread_self(void) { +#ifdef SILC_THREADS SilcWin32Thread self = TlsGetValue(silc_thread_tls); if (!self) { @@ -107,10 +113,14 @@ SilcThread silc_thread_self(void) } return (SilcThread)self; +#else + return NULL; +#endif } bool silc_thread_wait(SilcThread thread, void **exit_value) { +#ifdef SILC_THREADS SilcWin32Thread self = (SilcWin32Thread)thread; SILC_LOG_DEBUG(("Waiting for thread %p", self)); @@ -120,13 +130,17 @@ bool silc_thread_wait(SilcThread thread, void **exit_value) /* The thread is waitable thus we will free all memory after the WaitForSingleObject returns, the thread is destroyed after that. */ - WaitForSingleObject(self->thread, INFINITE); - CloseHandle(self->thread); + + /* 2 sec timeout, otherwise we would run to infinite loop some cases.. */ + if (WaitForSingleObject(self->thread, 2000) == WAIT_TIMEOUT) + TerminateThread(self->thread, 0); + silc_free(self); if (exit_value) *exit_value = NULL; return TRUE; +#else + return FALSE; +#endif } - -#endif /* SILC_THREADS */