From 5574d82eb31c7024beac1a6c5caf3df441afe1ed Mon Sep 17 00:00:00 2001 From: yhirose Date: Fri, 20 Apr 2018 00:17:51 -0400 Subject: [PATCH] Made a temporary fix for OpenSSL thread problem --- httplib.h | 22 ++++++++++++++++++---- test/test.cc | 14 +++++++++----- 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/httplib.h b/httplib.h index c7a5efc..b0cb0ab 100644 --- a/httplib.h +++ b/httplib.h @@ -2029,15 +2029,23 @@ inline std::shared_ptr Client::post(const char* path, const Headers& h #ifdef CPPHTTPLIB_OPENSSL_SUPPORT namespace detail { +// TODO: OpenSSL 1.0.2 occasionally crashes... The upcoming 1.1.0 is going to be thread safe. +static std::mutex ssl_ctx_mutex_; + template inline bool read_and_close_socket_ssl( socket_t sock, bool keep_alive, SSL_CTX* ctx, U SSL_connect_or_accept, V setup, T callback) { - auto ssl = SSL_new(ctx); - if (!ssl) { - return false; + SSL* ssl = nullptr; + { + std::lock_guard guard(ssl_ctx_mutex_); + + ssl = SSL_new(ctx); + if (!ssl) { + return false; + } } auto bio = BIO_new_socket(sock, BIO_NOCLOSE); @@ -2069,8 +2077,14 @@ inline bool read_and_close_socket_ssl( } SSL_shutdown(ssl); - SSL_free(ssl); + + { + std::lock_guard guard(ssl_ctx_mutex_); + SSL_free(ssl); + } + close_socket(sock); + return ret; } diff --git a/test/test.cc b/test/test.cc index 88a0202..009b6e0 100644 --- a/test/test.cc +++ b/test/test.cc @@ -263,7 +263,7 @@ protected: res.set_content("Hello World!", "text/plain"); }) .get("/slow", [&](const Request& /*req*/, Response& res) { - msleep(3000); + msleep(2000); res.set_content("slow", "text/plain"); }) .get("/remote_addr", [&](const Request& req, Response& res) { @@ -368,6 +368,9 @@ protected: virtual void TearDown() { svr_.stop(); + for (auto& t: request_threads_) { + t.join(); + } t_.join(); } @@ -380,6 +383,7 @@ protected: Server svr_; #endif thread t_; + std::vector request_threads_; }; TEST_F(ServerTest, GetMethod200) @@ -736,10 +740,10 @@ TEST_F(ServerTest, GetMethodRemoteAddr) TEST_F(ServerTest, SlowRequest) { - std::thread([=]() { auto res = cli_.get("/slow"); }).detach(); - std::thread([=]() { auto res = cli_.get("/slow"); }).detach(); - std::thread([=]() { auto res = cli_.get("/slow"); }).detach(); - msleep(1000); + request_threads_.push_back(std::thread([=]() { auto res = cli_.get("/slow"); })); + request_threads_.push_back(std::thread([=]() { auto res = cli_.get("/slow"); })); + request_threads_.push_back(std::thread([=]() { auto res = cli_.get("/slow"); })); + msleep(100); } #ifdef CPPHTTPLIB_ZLIB_SUPPORT