From aef9be46839e802b5a9e7c833794536cdbae7ee3 Mon Sep 17 00:00:00 2001 From: Jan Osusky Date: Mon, 27 Apr 2020 14:50:52 +0200 Subject: [PATCH 1/2] Fix build of SASL related code on Windows The code that uses Cyrus SASL library failed to build on Windows because of "pthead.h" include. There is for sure a nicer way how to make locking in a platform independent way. I have tried to keep the pthread code for Unix and have added a corresponding code for Windows. --- c/src/sasl/cyrus_sasl.c | 110 +++++++++++++++++++++++++++++++++------- 1 file changed, 93 insertions(+), 17 deletions(-) diff --git a/c/src/sasl/cyrus_sasl.c b/c/src/sasl/cyrus_sasl.c index d98f3a3551..8c943d6bd9 100644 --- a/c/src/sasl/cyrus_sasl.c +++ b/c/src/sasl/cyrus_sasl.c @@ -32,7 +32,6 @@ #include #include #include -#include #ifndef CYRUS_SASL_MAX_BUFFSIZE # define CYRUS_SASL_MAX_BUFFSIZE (32768) /* bytes */ @@ -163,12 +162,96 @@ static const sasl_callback_t pni_user_callbacks[] = { {SASL_CB_LIST_END, NULL, NULL}, }; +static void pni_cyrus_client_start(void); +static void pni_cyrus_server_start(void); +static void pni_cyrus_client_once(void); +static void pni_cyrus_server_once(void); +static void pni_cyrus_finish(void); + +#ifdef _WIN32 + #ifndef _WIN32_WINNT + #define _WIN32_WINNT 0x0600 + #endif + #if _WIN32_WINNT < 0x0600 + #error "Proton requires Windows API support for 7 or later." + #endif + #define WIN32_LEAN_AND_MEAN + #include + #include + + typedef CRITICAL_SECTION pni_mutex_t; + static inline void pni_mutex_init(pni_mutex_t *m) { InitializeCriticalSection(m); } + static inline void pni_mutex_lock(pni_mutex_t *m) { EnterCriticalSection(m); } + static inline void pni_mutex_unlock(pni_mutex_t *m) { LeaveCriticalSection(m); } + static pni_mutex_t pni_cyrus_mutex; + + // not sure if we realy need to do any explicitly cleanup at program exit + INIT_ONCE at_exit_cleanup_once_flag = INIT_ONCE_STATIC_INIT; + static BOOL CALLBACK AtExitHandlerFnc(PINIT_ONCE, PVOID, PVOID*) + { + atexit(pni_cyrus_finish); + return TRUE; + } + + static inline void set_at_exit_handler(void) { + void* dummy; + InitOnceExecuteOnce(&at_exit_cleanup_once_flag, &AtExitHandlerFnc, NULL, &dummy); + } + + // helper wraper for client initializetion + static BOOL CALLBACK InitClientFnc(PINIT_ONCE, PVOID, PVOID*) + { + pni_cyrus_client_once(); + return TRUE; + } + + INIT_ONCE pni_cyrus_client_init = INIT_ONCE_STATIC_INIT; + static inline void pni_cyrus_client_start(void) { + void* dummy; + InitOnceExecuteOnce(&pni_cyrus_client_init, &InitClientFnc, NULL, &dummy); + set_at_exit_handler(); + } + + // helper wraper for server + static BOOL CALLBACK InitServerFnc(PINIT_ONCE, PVOID, PVOID*) + { + pni_cyrus_server_once(); + return TRUE; + } + + INIT_ONCE pni_cyrus_server_init = INIT_ONCE_STATIC_INIT; + static inline void pni_cyrus_server_start(void) { + void* dummy; + InitOnceExecuteOnce(&pni_cyrus_server_init, &InitServerFnc, NULL, &dummy); + set_at_exit_handler(); + } + +#else /* POSIX */ + + #include + + typedef pthread_mutex_t pni_mutex_t; + static inline int pni_mutex_init(pni_mutex_t *m) { return pthread_mutex_init(m, NULL); } + static inline int pni_mutex_lock(pni_mutex_t *m) { return pthread_mutex_lock(m); } + static inline int pni_mutex_unlock(pni_mutex_t *m) { return pthread_mutex_unlock(m); } + static pni_mutex_t pni_cyrus_mutex = PTHREAD_MUTEX_INITIALIZER; + + static pthread_once_t pni_cyrus_client_init = PTHREAD_ONCE_INIT; + static inline void pni_cyrus_client_start(void) { + pthread_once(&pni_cyrus_client_init, pni_cyrus_client_once); + } + + static pthread_once_t pni_cyrus_server_init = PTHREAD_ONCE_INIT; + static inline void pni_cyrus_server_start(void) { + pthread_once(&pni_cyrus_server_init, &pni_cyrus_server_once); + } + +#endif // Machinery to initialise the cyrus library only once even in a multithreaded environment // Relies on pthreads. static const char default_config_name[] = "proton-server"; static char *pni_cyrus_config_dir = NULL; static char *pni_cyrus_config_name = NULL; -static pthread_mutex_t pni_cyrus_mutex = PTHREAD_MUTEX_INITIALIZER; static bool pni_cyrus_client_started = false; static bool pni_cyrus_server_started = false; @@ -191,19 +274,21 @@ void pn_sasl_config_path(pn_sasl_t *sasl0, const char *dir) } } +#ifndef _WIN32 __attribute__((destructor)) +#endif static void pni_cyrus_finish(void) { - pthread_mutex_lock(&pni_cyrus_mutex); + pni_mutex_lock(&pni_cyrus_mutex); if (pni_cyrus_client_started) sasl_client_done(); if (pni_cyrus_server_started) sasl_server_done(); free(pni_cyrus_config_dir); free(pni_cyrus_config_name); - pthread_mutex_unlock(&pni_cyrus_mutex); + pni_mutex_unlock(&pni_cyrus_mutex); } static int pni_cyrus_client_init_rc = SASL_OK; static void pni_cyrus_client_once(void) { - pthread_mutex_lock(&pni_cyrus_mutex); + pni_mutex_lock(&pni_cyrus_mutex); int result = SASL_OK; if (pni_cyrus_config_dir) { result = sasl_set_path(SASL_PATH_TYPE_CONFIG, pni_cyrus_config_dir); @@ -218,12 +303,12 @@ static void pni_cyrus_client_once(void) { } pni_cyrus_client_started = true; pni_cyrus_client_init_rc = result; - pthread_mutex_unlock(&pni_cyrus_mutex); + pni_mutex_unlock(&pni_cyrus_mutex); } static int pni_cyrus_server_init_rc = SASL_OK; static void pni_cyrus_server_once(void) { - pthread_mutex_lock(&pni_cyrus_mutex); + pni_mutex_lock(&pni_cyrus_mutex); int result = SASL_OK; if (pni_cyrus_config_dir) { result = sasl_set_path(SASL_PATH_TYPE_CONFIG, pni_cyrus_config_dir); @@ -238,16 +323,7 @@ static void pni_cyrus_server_once(void) { } pni_cyrus_server_started = true; pni_cyrus_server_init_rc = result; - pthread_mutex_unlock(&pni_cyrus_mutex); -} - -static pthread_once_t pni_cyrus_client_init = PTHREAD_ONCE_INIT; -static void pni_cyrus_client_start(void) { - pthread_once(&pni_cyrus_client_init, pni_cyrus_client_once); -} -static pthread_once_t pni_cyrus_server_init = PTHREAD_ONCE_INIT; -static void pni_cyrus_server_start(void) { - pthread_once(&pni_cyrus_server_init, pni_cyrus_server_once); + pni_mutex_unlock(&pni_cyrus_mutex); } void cyrus_sasl_prepare(pn_transport_t* transport) From 122355ab5eeed05c7fe1169653387afb1c9fdd95 Mon Sep 17 00:00:00 2001 From: Jan Osusky Date: Mon, 27 Apr 2020 16:09:28 +0200 Subject: [PATCH 2/2] Remove unused functions --- c/src/sasl/cyrus_sasl.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/c/src/sasl/cyrus_sasl.c b/c/src/sasl/cyrus_sasl.c index 8c943d6bd9..5c85ce3cc3 100644 --- a/c/src/sasl/cyrus_sasl.c +++ b/c/src/sasl/cyrus_sasl.c @@ -180,7 +180,6 @@ static void pni_cyrus_finish(void); #include typedef CRITICAL_SECTION pni_mutex_t; - static inline void pni_mutex_init(pni_mutex_t *m) { InitializeCriticalSection(m); } static inline void pni_mutex_lock(pni_mutex_t *m) { EnterCriticalSection(m); } static inline void pni_mutex_unlock(pni_mutex_t *m) { LeaveCriticalSection(m); } static pni_mutex_t pni_cyrus_mutex; @@ -231,7 +230,6 @@ static void pni_cyrus_finish(void); #include typedef pthread_mutex_t pni_mutex_t; - static inline int pni_mutex_init(pni_mutex_t *m) { return pthread_mutex_init(m, NULL); } static inline int pni_mutex_lock(pni_mutex_t *m) { return pthread_mutex_lock(m); } static inline int pni_mutex_unlock(pni_mutex_t *m) { return pthread_mutex_unlock(m); } static pni_mutex_t pni_cyrus_mutex = PTHREAD_MUTEX_INITIALIZER;