Fixed thread creation to use _beginthreadex and to handle Tls
authorPekka Riikonen <priikone@silcnet.org>
Sat, 12 May 2007 06:42:00 +0000 (06:42 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Sat, 12 May 2007 06:42:00 +0000 (06:42 +0000)
correctly.  Fixes various odd crashes.

lib/silcutil/win32/silcwin32thread.c

index 9b7e4bba0b0d5cd950d5800e4dbbe0d6af863028..15b1ca83d98424a86cb41ec949a4c1a5abd0c1c1 100644 (file)
@@ -42,7 +42,10 @@ unsigned __stdcall silc_thread_win32_start(void *context)
 {
   SilcWin32Thread thread = (SilcWin32Thread)context;
 
-  TlsSetValue(silc_thread_tls, context);
+  silc_thread_tls = TlsAlloc();
+  if (silc_thread_tls != TLS_OUT_OF_INDEXES)
+    TlsSetValue(silc_thread_tls, context);
+
   silc_thread_exit(thread->start_func(thread->context));
 
   return 0;
@@ -63,8 +66,8 @@ SilcThread silc_thread_create(SilcThreadStart start_func, void *context,
   thread->context = context;
   thread->waitable = waitable;
   thread->thread =
-    CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)silc_thread_win32_start,
-                (void *)thread, 0, &id);
+    _beginthreadex(NULL, 0, (LPTHREAD_START_ROUTINE)silc_thread_win32_start,
+                  (void *)thread, 0, &id);
 
   if (!thread->thread) {
     SILC_LOG_ERROR(("Could not create new thread"));
@@ -88,14 +91,12 @@ void silc_thread_exit(void *exit_value)
   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) {
-      TerminateThread(thread->thread, 0);
+    if (!thread->waitable)
       silc_free(thread);
-    }
-
-    TlsSetValue(silc_thread_tls, NULL);
   }
-  ExitThread(0);
+
+  TlsFree(silc_thread_tls);
+  _endthreadex(0);
 #endif
 }
 
@@ -105,7 +106,7 @@ SilcThread silc_thread_self(void)
   SilcWin32Thread self = TlsGetValue(silc_thread_tls);
 
   if (!self) {
-    /* This should only happen for the main thread! */
+    /* This should only happen for the main thread. */
     HANDLE handle = GetCurrentThread ();
     HANDLE process = GetCurrentProcess ();
     self = silc_calloc(1, sizeof(*self));
@@ -133,10 +134,9 @@ SilcBool 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. */
-  if (WaitForSingleObject(self->thread, 2500) == WAIT_TIMEOUT)
-    TerminateThread(self->thread, 0);
+  WaitForSingleObject(self->thread, INFINITE);
+  CloseHandle(self->thread);
 
-  silc_free(self);
   if (exit_value)
     *exit_value = NULL;