You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by as...@apache.org on 2016/05/11 17:25:22 UTC
qpid-proton git commit: PROTON-992: Make cyrus sasl
initialisation/shutdown thread safe
Repository: qpid-proton
Updated Branches:
refs/heads/master 12ebe05a4 -> 1e9e243a3
PROTON-992: Make cyrus sasl initialisation/shutdown thread safe
Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/1e9e243a
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/1e9e243a
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/1e9e243a
Branch: refs/heads/master
Commit: 1e9e243a37acca22b5a77177cc1ab4d06ba4b2ec
Parents: 12ebe05
Author: Andrew Stitcher <as...@apache.org>
Authored: Tue May 3 16:40:21 2016 -0400
Committer: Andrew Stitcher <as...@apache.org>
Committed: Wed May 11 13:51:31 2016 +0100
----------------------------------------------------------------------
proton-c/CMakeLists.txt | 2 +-
proton-c/src/sasl/cyrus_sasl.c | 77 +++++++++++++++++++++++++++++++------
2 files changed, 67 insertions(+), 12 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/1e9e243a/proton-c/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/proton-c/CMakeLists.txt b/proton-c/CMakeLists.txt
index 372e67c..8219256 100644
--- a/proton-c/CMakeLists.txt
+++ b/proton-c/CMakeLists.txt
@@ -105,7 +105,7 @@ endif(PN_WINAPI)
if (SASL_IMPL STREQUAL cyrus)
set(pn_sasl_impl src/sasl/sasl.c src/sasl/cyrus_sasl.c)
include_directories (${CYRUS_SASL_INCLUDE_DIR})
- set(SASL_LIB ${CYRUS_SASL_LIBRARY})
+ set(SASL_LIB ${CYRUS_SASL_LIBRARY} -lpthread)
elseif (SASL_IMPL STREQUAL none)
set(pn_sasl_impl src/sasl/sasl.c src/sasl/none_sasl.c)
endif ()
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/1e9e243a/proton-c/src/sasl/cyrus_sasl.c
----------------------------------------------------------------------
diff --git a/proton-c/src/sasl/cyrus_sasl.c b/proton-c/src/sasl/cyrus_sasl.c
index 4af1f52..b1e2e03 100644
--- a/proton-c/src/sasl/cyrus_sasl.c
+++ b/proton-c/src/sasl/cyrus_sasl.c
@@ -25,6 +25,7 @@
#include "engine/engine-internal.h"
#include <sasl/sasl.h>
+#include <pthread.h>
// If the version of Cyrus SASL is too early for sasl_client_done()/sasl_server_done()
// don't do any global clean up as it's not safe to use just sasl_done() for an
@@ -102,17 +103,72 @@ static const sasl_callback_t pni_user_callbacks[] = {
{SASL_CB_LIST_END, NULL, NULL},
};
+// Machinery to initialise the cyrus library only once even in a multithreaded environment
+// Relies on pthreads.
+static char *pni_cyrus_config_dir = NULL;
+static const char *pni_cyrus_config_name = "proton-server";
+static pthread_mutex_t pni_cyrus_mutex = PTHREAD_MUTEX_INITIALIZER;
+static bool pni_cyrus_client_started = false;
+static bool pni_cyrus_server_started = false;
+
+__attribute__((destructor))
+static void pni_cyrus_finish(void) {
+ pthread_mutex_lock(&pni_cyrus_mutex);
+ if (pni_cyrus_client_started) sasl_client_done();
+ if (pni_cyrus_server_started) sasl_server_done();
+ pthread_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);
+ int result = SASL_OK;
+ if (pni_cyrus_config_dir) {
+ result = sasl_set_path(SASL_PATH_TYPE_CONFIG, pni_cyrus_config_dir);
+ }
+ if (result==SASL_OK) {
+ result = sasl_client_init(NULL);
+ }
+ pni_cyrus_client_started = true;
+ pni_cyrus_client_init_rc = result;
+ pthread_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);
+ int result = SASL_OK;
+ if (pni_cyrus_config_dir) {
+ result = sasl_set_path(SASL_PATH_TYPE_CONFIG, pni_cyrus_config_dir);
+ }
+ if (result==SASL_OK) {
+ result = sasl_server_init(NULL, pni_cyrus_config_name);
+ }
+ 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);
+}
+
bool pni_init_client(pn_transport_t* transport) {
pni_sasl_t *sasl = transport->sasl;
int result;
sasl_conn_t *cyrus_conn = NULL;
do {
if (sasl->config_dir) {
- result = sasl_set_path(SASL_PATH_TYPE_CONFIG, sasl->config_dir);
- if (result!=SASL_OK) break;
+ pni_cyrus_config_dir = sasl->config_dir;
}
- result = sasl_client_init(NULL);
+ pni_cyrus_client_start();
+ result = pni_cyrus_client_init_rc;
if (result!=SASL_OK) break;
const sasl_callback_t *callbacks = sasl->username ? sasl->password ? pni_user_password_callbacks : pni_user_callbacks : NULL;
@@ -246,11 +302,15 @@ bool pni_init_server(pn_transport_t* transport)
sasl_conn_t *cyrus_conn = NULL;
do {
if (sasl->config_dir) {
- result = sasl_set_path(SASL_PATH_TYPE_CONFIG, sasl->config_dir);
- if (result!=SASL_OK) break;
+ pni_cyrus_config_dir = sasl->config_dir;
+ }
+
+ if (sasl->config_name) {
+ pni_cyrus_config_name = sasl->config_name;
}
- result = sasl_server_init(NULL, sasl->config_name ? sasl->config_name : "proton-server");
+ pni_cyrus_server_start();
+ result = pni_cyrus_server_init_rc;
if (result!=SASL_OK) break;
result = sasl_server_new(amqp_service, NULL, NULL, NULL, NULL, NULL, 0, &cyrus_conn);
@@ -456,11 +516,6 @@ void pni_sasl_impl_free(pn_transport_t *transport)
sasl_conn_t *cyrus_conn = (sasl_conn_t*)transport->sasl->impl_context;
sasl_dispose(&cyrus_conn);
transport->sasl->impl_context = cyrus_conn;
- if (transport->sasl->client) {
- sasl_client_done();
- } else {
- sasl_server_done();
- }
}
bool pn_sasl_extended(void)
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org