From: Pekka Riikonen Date: Sun, 8 Jul 2001 07:59:36 +0000 (+0000) Subject: updates. X-Git-Tag: robodoc-323~98 X-Git-Url: http://git.silcnet.org/gitweb/?p=silc.git;a=commitdiff_plain;h=1c2e84130f2ea435bef9dbfe0becbd6b696e8048 updates. --- diff --git a/CHANGES b/CHANGES index 4e515e65..012d0b51 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,8 @@ +Sun Jul 8 11:16:01 EEST 2001 Pekka Riikonen + + * Implemented the SILC Mutex API and SILC Thread API for WIN32 + in lib/silcutil/win32/. + Sun Jul 8 00:18:15 EEST 2001 Pekka Riikonen * Defined SILC Mutex API and SILC Thread API and implemented diff --git a/lib/silcutil/silcmutex.h b/lib/silcutil/silcmutex.h index 89ee8a55..70eed3c3 100644 --- a/lib/silcutil/silcmutex.h +++ b/lib/silcutil/silcmutex.h @@ -104,7 +104,7 @@ void silc_mutex_lock(SilcMutex mutex); * * DESCRIPTION * - * Unlocks the mutex and thus releases it for another threads that + * Unlocks the mutex and thus releases it for another thread that * may be waiting for the lock. * * NOTES diff --git a/lib/silcutil/silcthread.h b/lib/silcutil/silcthread.h index 5d4932d8..8f2f7094 100644 --- a/lib/silcutil/silcthread.h +++ b/lib/silcutil/silcthread.h @@ -23,7 +23,7 @@ * DESCRIPTION * * Interface for SILC Thread implementation. This is platform independent - * implementation of threads for applications needing concurrent execution + * implementation of threads for applications that need concurrent execution * with the application's main thread. The threads created with this * interface executes concurrently with the calling thread. * @@ -122,7 +122,7 @@ void silc_thread_exit(void *exit_value); * * DESCRIPTION * - * Returns a pointer of the current thread. + * Returns a pointer to the current thread. * ***/ SilcThread silc_thread_self(void); diff --git a/lib/silcutil/unix/silcunixmutex.c b/lib/silcutil/unix/silcunixmutex.c index c6b21573..7875eb80 100644 --- a/lib/silcutil/unix/silcunixmutex.c +++ b/lib/silcutil/unix/silcunixmutex.c @@ -32,6 +32,7 @@ SilcMutex silc_mutex_alloc(void) { SilcMutex mutex = silc_calloc(1, sizeof(*mutex)); pthread_mutex_init(&mutex->mutex, NULL); + return mutex; } void silc_mutex_free(SilcMutex mutex) diff --git a/lib/silcutil/unix/silcunixthread.c b/lib/silcutil/unix/silcunixthread.c index 2c205c41..9cd68c3b 100644 --- a/lib/silcutil/unix/silcunixthread.c +++ b/lib/silcutil/unix/silcunixthread.c @@ -65,7 +65,7 @@ SilcThread silc_thread_create(SilcThreadStart start_func, void *context, void silc_thread_exit(void *exit_value) { - pthread_exit(NULL); + pthread_exit(exit_value); } SilcThread silc_thread_self(void) diff --git a/lib/silcutil/win32/Makefile.am b/lib/silcutil/win32/Makefile.am index 70e1d45f..57b8c23a 100644 --- a/lib/silcutil/win32/Makefile.am +++ b/lib/silcutil/win32/Makefile.am @@ -24,6 +24,8 @@ libsilcwin32util_a_SOURCES = \ silcwin32net.c \ silcwin32schedule.c \ silcwin32sockconn.c \ - silcwin32util.c + silcwin32util.c \ + silcwin32mutex.c \ + silcwin32thread.c include $(top_srcdir)/Makefile.defines.in diff --git a/lib/silcutil/win32/silcwin32mutex.c b/lib/silcutil/win32/silcwin32mutex.c new file mode 100644 index 00000000..690c2a20 --- /dev/null +++ b/lib/silcutil/win32/silcwin32mutex.c @@ -0,0 +1,58 @@ +/* + + silcwin32mutex.c + + Author: Pekka Riikonen + + Copyright (C) 2001 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. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + +*/ +/* $Id$ */ + +#include "silcincludes.h" + +#ifdef SILC_THREADS + +/* SILC Mutex structure */ +struct SilcMutexStruct { + HANDLE mutex; +}; + +SilcMutex silc_mutex_alloc(void) +{ + SilcMutex mutex = silc_calloc(1, sizeof(*mutex)); + mutex->mutex = CreateMutex(NULL, FALSE, NULL); + if (!mutex->mutex) { + silc_free(mutex); + return NULL; + } + return mutex; +} + +void silc_mutex_free(SilcMutex mutex) +{ + CloseHandle(mutex->mutex); + silc_free(mutex); +} + +void silc_mutex_lock(SilcMutex mutex) +{ + WaitForSingleObject(mutex->mutex, INFINITE); +} + +void silc_mutex_unlock(SilcMutex mutex) +{ + ReleaseMutex(mutex->mutex); +} + +#endif /* SILC_THREADS */ diff --git a/lib/silcutil/win32/silcwin32thread.c b/lib/silcutil/win32/silcwin32thread.c new file mode 100644 index 00000000..5c32cb3f --- /dev/null +++ b/lib/silcutil/win32/silcwin32thread.c @@ -0,0 +1,131 @@ +/* + + silcwin32thread.c + + Author: Pekka Riikonen + + Copyright (C) 2001 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. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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" + +#ifdef SILC_THREADS + +/* Thread structure for WIN32 */ +typedef struct { + HANDLE thread; + SilcThreadStart start_func; + void *context; + bool waitable; +} *SilcWin32Thread; + +static DWROD 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) +{ + SilcWin32Thread thread = (SilcWin32Thread)context; + + TlsSetValue(silc_thread_tls, context); + thread->start_func(thread->context); + silc_thread_exit(); + + return 0; +} + +SilcThread silc_thread_create(SilcThreadStart start_func, void *context, + bool waitable) +{ + SilcWin32Thread thread; + DWROD id; + + SILC_LOG_DEBUG(("Creating new thread")); + + thread = silc_calloc(1, sizeof(*thread)); + thread->start_func = start_func; + thread->context = context; + thread->waitable = waitable; + thread->thread = _beginthreadex(NULL, 0, silc_thread_win32_start, + thread, 0, &id); + if (!thread->thread) { + SILC_LOG_ERROR(("Could not create new thread")); + silc_free(thread); + return NULL; + } + + return (SilcThread)thread; +} + +void silc_thread_exit(void *exit_value) +{ + 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); + } + + TlsSetValue(silc_thread_tls, NULL); + } + + _endthreadex(0); +} + +SilcThread silc_thread_self(void) +{ + SilcWin32Thread self = TlsGetValue(silc_thread_tls); + + if (!self) { + /* This should only happen for the main thread! */ + HANDLE handle = GetCurrentThread (); + HANDLE process = GetCurrentProcess (); + self = silc_calloc(1, sizeof(*self)); + DuplicateHandle(process, handle, process, + &self->thread, 0, FALSE, + DUPLICATE_SAME_ACCESS); + TlsSetValue(silc_thread_tls, self); + } + + return (SilcThread)self; +} + +bool silc_thread_wait(SilcThread thread, void **exit_value) +{ + SILC_LOG_DEBUG(("Waiting for thread %p", thread)); + + if (!thread->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 (exit_value) + *exit_value = NULL; + + return TRUE; +} + +#endif /* SILC_THREADS */