From 62cb49534558f562ec8792eec74ce892b3e3529c Mon Sep 17 00:00:00 2001 From: Alan Antonuk Date: Tue, 29 May 2012 17:30:23 -0400 Subject: Adding pthread shim for Win32 ENABLE_THREAD_SAFETY --- librabbitmq/CMakeLists.txt | 5 +++++ librabbitmq/amqp-openssl.c | 23 ++++++++++++++++++++++- librabbitmq/win32/threads.c | 37 +++++++++++++++++++++++++++++++++++++ librabbitmq/win32/threads.h | 14 ++++++++++++++ 4 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 librabbitmq/win32/threads.c create mode 100644 librabbitmq/win32/threads.h diff --git a/librabbitmq/CMakeLists.txt b/librabbitmq/CMakeLists.txt index 0fb8026..49c37b9 100644 --- a/librabbitmq/CMakeLists.txt +++ b/librabbitmq/CMakeLists.txt @@ -100,6 +100,11 @@ if (ENABLE_SSL_SUPPORT) if (ENABLE_THREAD_SAFETY) add_definitions(-DENABLE_THREAD_SAFETY) + if (WIN32) + set(AMQP_SSL_SRCS ${AMQP_SSL_SRCS} win32/threads.h win32/threads.c) + else() + set(AMQP_SSL_SRCS ${AMQP_SSL_SRCS} unix/threads.h) + endif() endif() endif() diff --git a/librabbitmq/amqp-openssl.c b/librabbitmq/amqp-openssl.c index 965f6e1..35f908c 100644 --- a/librabbitmq/amqp-openssl.c +++ b/librabbitmq/amqp-openssl.c @@ -45,7 +45,12 @@ static amqp_boolean_t openssl_initialized = 0; static unsigned long amqp_ssl_threadid_callback(void); static void amqp_ssl_locking_callback(int mode, int n, const char *file, int line); +#ifdef _WIN32 +static long win32_create_mutex = 0; +static pthread_mutex_t openssl_init_mutex = NULL; +#else static pthread_mutex_t openssl_init_mutex = PTHREAD_MUTEX_INITIALIZER; +#endif static pthread_mutex_t *amqp_openssl_lockarray = NULL; #endif /* ENABLE_THREAD_SAFETY */ @@ -323,6 +328,22 @@ amqp_ssl_locking_callback(int mode, int n, const char *file, int line) static int initialize_openssl() { +#ifdef _WIN32 + /* No such thing as PTHREAD_INITIALIZE_MUTEX macro on Win32, so we use this */ + if (NULL == openssl_init_mutex) + { + while (InterlockedExchange(&win32_create_mutex, 1) == 1) + /* Loop, someone else is holding this lock */ ; + + if (NULL == openssl_init_mutex) + { + if (pthread_mutex_init(&openssl_init_mutex, NULL)) + return -1; + } + InterlockedExchange(&win32_create_mutex, 0); + } +#endif /* _WIN32 */ + #ifdef ENABLE_THREAD_SAFETY if (pthread_mutex_lock(&openssl_init_mutex)) return -1; @@ -339,7 +360,7 @@ initialize_openssl() pthread_mutex_unlock(&openssl_init_mutex); return -1; } - for (int i = 0; i < CRYPTO_num_locks(); ++i) + for (i = 0; i < CRYPTO_num_locks(); ++i) { if (pthread_mutex_init(&amqp_openssl_lockarray[i], NULL)) { diff --git a/librabbitmq/win32/threads.c b/librabbitmq/win32/threads.c new file mode 100644 index 0000000..cf2e9ee --- /dev/null +++ b/librabbitmq/win32/threads.c @@ -0,0 +1,37 @@ +#include "threads.h" + +DWORD +pthread_self(void) +{ + return GetCurrentThreadId(); +} + +int +pthread_mutex_init(pthread_mutex_t *mutex, void *attr) +{ + *mutex = malloc(sizeof(CRITICAL_SECTION)); + if (!*mutex) + return 1; + InitializeCriticalSection(*mutex); + return 0; +} + +int +pthread_mutex_lock(pthread_mutex_t *mutex) +{ + if (!*mutex) + return 1; + + EnterCriticalSection(*mutex); + return 0; +} + +int +pthread_mutex_unlock(pthread_mutex_t *mutex) +{ + if (!*mutex) + return 1; + + LeaveCriticalSection(*mutex); + return 0; +} diff --git a/librabbitmq/win32/threads.h b/librabbitmq/win32/threads.h new file mode 100644 index 0000000..7cf6ca5 --- /dev/null +++ b/librabbitmq/win32/threads.h @@ -0,0 +1,14 @@ +#ifndef AMQP_THREAD_H +#define AMQP_THREAD_H + +#include + +typedef CRITICAL_SECTION *pthread_mutex_t; +typedef int pthread_once_t; + +DWORD pthread_self(void); + +int pthread_mutex_init(pthread_mutex_t *, void *attr); +int pthread_mutex_lock(pthread_mutex_t *); +int pthread_mutex_unlock(pthread_mutex_t *); +#endif /* AMQP_THREAD_H */ -- cgit v1.2.1