message: Add OpenSSL locking functions
  The OpenSSL docs for CRYPTO_set_locking_callback seem to describe what I
  observe: "Multi-threaded applications will crash at random if it is not
  set".
diff: @@ -23,6 +23,9 @@ CAF_PUSH_WARNINGS
  #include <openssl/ssl.h>
  CAF_POP_WARNINGS
  +#include <vector>
  +#include <mutex>
  +
  #include "caf/expected.hpp"
  #include "caf/actor_system.hpp"
  #include "caf/scoped_actor.hpp"
  @@ -35,11 +38,53 @@ CAF_POP_WARNINGS
  #include "caf/openssl/middleman_actor.hpp"
  +struct CRYPTO_dynlock_value {
  + std::mutex mtx;
  +};
  +
  namespace caf {
  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() {
  - // 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() {
  @@ -69,6 +114,17 @@ void manager::init(actor_system_config&) {
  if (system().config().openssl_key.size() == 0)
  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 {
  