Unverified Commit b8c209b0 authored by Dominik Charousset's avatar Dominik Charousset Committed by GitHub

Merge pull request #700

Add OpenSSL locking functions
parents 6c4b69e0 8881fae7
...@@ -23,6 +23,9 @@ CAF_PUSH_WARNINGS ...@@ -23,6 +23,9 @@ CAF_PUSH_WARNINGS
#include <openssl/ssl.h> #include <openssl/ssl.h>
CAF_POP_WARNINGS CAF_POP_WARNINGS
#include <vector>
#include <mutex>
#include "caf/expected.hpp" #include "caf/expected.hpp"
#include "caf/actor_system.hpp" #include "caf/actor_system.hpp"
#include "caf/scoped_actor.hpp" #include "caf/scoped_actor.hpp"
...@@ -35,11 +38,53 @@ CAF_POP_WARNINGS ...@@ -35,11 +38,53 @@ CAF_POP_WARNINGS
#include "caf/openssl/middleman_actor.hpp" #include "caf/openssl/middleman_actor.hpp"
struct CRYPTO_dynlock_value {
std::mutex mtx;
};
namespace caf { namespace caf {
namespace openssl { namespace openssl {
static int init_count = 0;
static std::mutex init_mutex;
static std::vector<std::mutex> mutexes;
static void locking_function(int mode, int n,
const char* /* file */, int /* line */) {
if (mode & CRYPTO_LOCK)
mutexes[n].lock();
else
mutexes[n].unlock();
}
static CRYPTO_dynlock_value* dynlock_create(const char* /* file */,
int /* line */) {
return new CRYPTO_dynlock_value{};
}
static void dynlock_lock(int mode, CRYPTO_dynlock_value* dynlock,
const char* /* file */, int /* line */) {
if (mode & CRYPTO_LOCK)
dynlock->mtx.lock();
else
dynlock->mtx.unlock();
}
static void dynlock_destroy(CRYPTO_dynlock_value* dynlock,
const char* /* file */, int /* line */) {
delete dynlock;
}
manager::~manager() { manager::~manager() {
// nop std::lock_guard<std::mutex> lock{init_mutex};
--init_count;
if (init_count == 0) {
CRYPTO_set_locking_callback(nullptr);
CRYPTO_set_dynlock_create_callback(nullptr);
CRYPTO_set_dynlock_lock_callback(nullptr);
CRYPTO_set_dynlock_destroy_callback(nullptr);
mutexes = std::vector<std::mutex>(0);
}
} }
void manager::start() { void manager::start() {
...@@ -69,6 +114,17 @@ void manager::init(actor_system_config&) { ...@@ -69,6 +114,17 @@ void manager::init(actor_system_config&) {
if (system().config().openssl_key.size() == 0) if (system().config().openssl_key.size() == 0)
CAF_RAISE_ERROR("No private key configured for SSL endpoint"); CAF_RAISE_ERROR("No private key configured for SSL endpoint");
} }
std::lock_guard<std::mutex> lock{init_mutex};
++init_count;
if (init_count == 1) {
mutexes = std::vector<std::mutex>(CRYPTO_num_locks());
CRYPTO_set_locking_callback(locking_function);
CRYPTO_set_dynlock_create_callback(dynlock_create);
CRYPTO_set_dynlock_lock_callback(dynlock_lock);
CRYPTO_set_dynlock_destroy_callback(dynlock_destroy);
// OpenSSL's default thread ID callback should work, so don't set our own.
}
} }
actor_system::module::id_t manager::id() const { actor_system::module::id_t manager::id() const {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment