diff --git a/src/system.h b/src/system.h index e377524..98b1d85 100644 --- a/src/system.h +++ b/src/system.h @@ -34,6 +34,7 @@ #ifndef WINSOCK #define WINSOCK #endif +#define WINTHREAD_SUPPORT 1 #endif #if defined(__CYGWIN__) || defined(__MINGW32__) diff --git a/src/uhub.h b/src/uhub.h index ad29c3a..4ba9672 100644 --- a/src/uhub.h +++ b/src/uhub.h @@ -68,6 +68,7 @@ extern "C" { #include "util/memory.h" #include "util/misc.h" #include "util/tiger.h" +#include "util/threads.h" #include "adc/sid.h" #include "adc/message.h" diff --git a/src/util/threads.c b/src/util/threads.c new file mode 100644 index 0000000..814037f --- /dev/null +++ b/src/util/threads.c @@ -0,0 +1,141 @@ +/* + * uhub - A tiny ADC p2p connection hub + * Copyright (C) 2007-2012, Jan Vidar Krey + * + * 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 3 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. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "uhub.h" + +#ifdef POSIX_THREAD_SUPPORT +void uhub_mutex_init(uhub_mutex_t* mutex) +{ + pthread_mutex_init(mutex, NULL); +} + +void uhub_mutex_destroy(uhub_mutex_t* mutex) +{ + pthread_mutex_destroy(mutex); +} + +void uhub_mutex_lock(uhub_mutex_t* mutex) +{ + pthread_mutex_lock(mutex); +} + +void uhub_mutex_unlock(uhub_mutex_t* mutex) +{ + pthread_mutex_unlock(mutex); +} + +int uhub_mutex_trylock(uhub_mutex_t* mutex) +{ + int ret = pthread_mutex_trylock(mutex); + return (ret == 0); +} + +uhub_thread_t* uhub_thread_create(uhub_thread_start start, void* arg) +{ + uhub_thread_t* thread = (uhub_thread_t*) hub_malloc_zero(sizeof(uhub_thread_t)); + int ret = pthread_create(thread, NULL, start, arg); + if (ret == 0) + return thread; + hub_free(thread); + return NULL; +} + +void uhub_thread_cancel(uhub_thread_t* thread) +{ + pthread_cancel(thread); +} + +void* uhub_thread_join(uhub_thread_t* thread) +{ + void* ret = NULL; + pthread_join(thread, &ret); + hub_free(thread); + return ret; +} + + +#endif /* POSIX_THREAD_SUPPORT */ + +#ifdef WINTHREAD_SUPPORT + +struct winthread_data +{ + uhub_thread_t* handle; + uhub_thread_start start; + void* arg; +}; + +static DWORD WINAPI uhub_winthread_start(void* ptr) +{ + struct winthread_data* data = (struct winthread_data*) ptr; + DWORD ret = (DWORD) data->start(data->arg); + return ret; +} + +void uhub_mutex_init(uhub_mutex_t* mutex) +{ + InitializeCriticalSection(mutex); +} + +void uhub_mutex_destroy(uhub_mutex_t* mutex) +{ + DeleteCriticalSection(mutex); +} + +void uhub_mutex_lock(uhub_mutex_t* mutex) +{ + EnterCriticalSection(mutex); +} + +void uhub_mutex_unlock(uhub_mutex_t* mutex) +{ + LeaveCriticalSection(mutex); +} + +int uhub_mutex_trylock(uhub_mutex_t* mutex) +{ + return TryEnterCriticalSection(mutex); +} + +uhub_thread_t* uhub_thread_create(uhub_thread_start start, void* arg) +{ + struct winthread_data* thread = (struct winthread_data*) hub_malloc_zero(sizeof(struct winthread_data)); + thread->start = start; + thread->arg = arg; + thread->handle = CreateThread(NULL, 0, uhub_winthread_start, thread, 0, 0); + return thread; +} + +void uhub_thread_cancel(uhub_thread_t* thread) +{ + TerminateThread(thread->handle, 0); +} + +void* uhub_thread_join(uhub_thread_t* thread) +{ + void* ret = NULL; + DWORD exitCode; + WaitForSingleObject(thread->handle, INFINITE); + GetExitCodeThread(thread->handle, &exitCode); + ret = &exitCode; + CloseHandle(thread->handle); + hub_free(thread); + return ret; +} +#endif /* WINTHREAD_SUPPORT */ diff --git a/src/util/threads.h b/src/util/threads.h new file mode 100644 index 0000000..20d2186 --- /dev/null +++ b/src/util/threads.h @@ -0,0 +1,49 @@ +/* + * uhub - A tiny ADC p2p connection hub + * Copyright (C) 2007-2012, Jan Vidar Krey + * + * 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 3 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. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#ifndef HAVE_UHUB_UTIL_THREADS_H +#define HAVE_UHUB_UTIL_THREADS_H + +typedef void*(*uhub_thread_start)(void*) ; + +#ifdef POSIX_THREADS_SUPPORT +typedef pthread_t uhub_thread_t; +typedef pthread_mutex_t uhub_mutex_t; +#endif + +#ifdef WINTHREAD_SUPPORT +struct winthread_data; +typedef struct winthread_data uhub_thread_t; +typedef CRITICAL_SECTION uhub_mutex_t; +#endif + +// Mutexes +extern void uhub_mutex_init(uhub_mutex_t* mutex); +extern void uhub_mutex_destroy(uhub_mutex_t* mutex); +extern void uhub_mutex_lock(uhub_mutex_t* mutex); +extern void uhub_mutex_unlock(uhub_mutex_t* mutex); +extern int uhub_mutex_trylock(uhub_mutex_t* mutex); + +// Threads +uhub_thread_t* uhub_thread_create(uhub_thread_start start, void* arg); +void uhub_thread_cancel(uhub_thread_t* thread); +void* uhub_thread_join(uhub_thread_t* thread); + +#endif /* HAVE_UHUB_UTIL_THREADS_H */ +