X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=lib%2Fsilcutil%2Fwin32%2Fsilcwin32thread.c;h=c31e70931381d2f68cecb669bb040f462b102839;hb=40f8443d8d3a6577336ee66d18e04d9ac4d956bb;hp=5c32cb3fdcde0bfafbc201ae8d53d793c021e3b1;hpb=1c2e84130f2ea435bef9dbfe0becbd6b696e8048;p=silc.git diff --git a/lib/silcutil/win32/silcwin32thread.c b/lib/silcutil/win32/silcwin32thread.c index 5c32cb3f..c31e7093 100644 --- a/lib/silcutil/win32/silcwin32thread.c +++ b/lib/silcutil/win32/silcwin32thread.c @@ -4,12 +4,11 @@ Author: Pekka Riikonen - Copyright (C) 2001 Pekka Riikonen + Copyright (C) 2001 - 2005 Pekka Riikonen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -17,11 +16,9 @@ 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" +#include "silc.h" #ifdef SILC_THREADS @@ -30,31 +27,32 @@ typedef struct { HANDLE thread; SilcThreadStart start_func; void *context; - bool waitable; + SilcBool waitable; } *SilcWin32Thread; -static DWROD silc_thread_tls; +static DWORD silc_thread_tls; /* Actual routine that is called by WIN32 when the thread is created. We will call the start_func from here. When this returns the thread is destroyed. */ -int __stdcall silc_thread_win32_start(void *context) +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(); + silc_thread_exit(thread->start_func(thread->context)); return 0; } +#endif SilcThread silc_thread_create(SilcThreadStart start_func, void *context, - bool waitable) + SilcBool waitable) { +#ifdef SILC_THREADS SilcWin32Thread thread; - DWROD id; + unsigned id; SILC_LOG_DEBUG(("Creating new thread")); @@ -62,8 +60,10 @@ SilcThread silc_thread_create(SilcThreadStart start_func, void *context, thread->start_func = start_func; thread->context = context; thread->waitable = waitable; - thread->thread = _beginthreadex(NULL, 0, silc_thread_win32_start, - 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,29 +71,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); - silc_free(thread); - } + if (!thread->waitable) { + 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) { @@ -108,24 +114,32 @@ SilcThread silc_thread_self(void) } return (SilcThread)self; + #else + return NULL; +#endif } -bool silc_thread_wait(SilcThread thread, void **exit_value) +SilcBool silc_thread_wait(SilcThread thread, void **exit_value) { - SILC_LOG_DEBUG(("Waiting for thread %p", thread)); +#ifdef SILC_THREADS + SilcWin32Thread self = (SilcWin32Thread)thread; + + SILC_LOG_DEBUG(("Waiting for thread %p", self)); - if (!thread->waitable) + if (!self->waitable) return FALSE; /* The thread is waitable thus we will free all memory after the WaitForSingleObject returns, the thread is destroyed after that. */ - WaitForSingleObject(thread->thread, INFINITE); - CloseHandle(thread->thread); - silc_free(thread); + if (WaitForSingleObject(self->thread, 2500) == WAIT_TIMEOUT) + TerminateThread(self->thread, 0); + + silc_free(self); if (exit_value) *exit_value = NULL; return TRUE; +#else + return FALSE; +#endif } - -#endif /* SILC_THREADS */