Made Client::close thread safe

This commit is contained in:
eidheim 2016-11-23 10:31:37 +01:00
commit 76bf8942fd
2 changed files with 26 additions and 5 deletions

View file

@ -9,6 +9,7 @@
#include <unordered_map> #include <unordered_map>
#include <map> #include <map>
#include <random> #include <random>
#include <mutex>
namespace SimpleWeb { namespace SimpleWeb {
template <class socket_type> template <class socket_type>
@ -92,13 +93,15 @@ namespace SimpleWeb {
if(timer) if(timer)
timer->cancel(); timer->cancel();
if(ec) { if(ec) {
socket=nullptr; std::lock_guard<std::mutex> lock(socket_mutex);
throw boost::system::system_error(ec); socket=nullptr;
} throw boost::system::system_error(ec);
}
}); });
} }
} }
else { else {
std::lock_guard<std::mutex> lock(socket_mutex);
socket=nullptr; socket=nullptr;
throw boost::system::system_error(ec); throw boost::system::system_error(ec);
} }
@ -138,6 +141,7 @@ namespace SimpleWeb {
if(timer) if(timer)
timer->cancel(); timer->cancel();
if(ec) { if(ec) {
std::lock_guard<std::mutex> lock(socket_mutex);
socket=nullptr; socket=nullptr;
throw boost::system::system_error(ec); throw boost::system::system_error(ec);
} }
@ -149,6 +153,7 @@ namespace SimpleWeb {
} }
void close() { void close() {
std::lock_guard<std::mutex> lock(socket_mutex);
if(socket) { if(socket) {
boost::system::error_code ec; boost::system::error_code ec;
socket->lowest_layer().shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec); socket->lowest_layer().shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec);
@ -162,6 +167,7 @@ namespace SimpleWeb {
boost::asio::ip::tcp::resolver resolver; boost::asio::ip::tcp::resolver resolver;
std::unique_ptr<socket_type> socket; std::unique_ptr<socket_type> socket;
std::mutex socket_mutex;
std::string host; std::string host;
unsigned short port; unsigned short port;
@ -248,6 +254,7 @@ namespace SimpleWeb {
if(timer) if(timer)
timer->cancel(); timer->cancel();
if(ec) { if(ec) {
std::lock_guard<std::mutex> lock(socket_mutex);
this->socket=nullptr; this->socket=nullptr;
throw boost::system::system_error(ec); throw boost::system::system_error(ec);
} }
@ -259,6 +266,7 @@ namespace SimpleWeb {
} }
} }
else { else {
std::lock_guard<std::mutex> lock(socket_mutex);
socket=nullptr; socket=nullptr;
throw boost::system::system_error(ec); throw boost::system::system_error(ec);
} }
@ -313,6 +321,7 @@ namespace SimpleWeb {
post_process(); post_process();
} }
else { else {
std::lock_guard<std::mutex> lock(socket_mutex);
this->socket=nullptr; this->socket=nullptr;
throw boost::system::system_error(ec); throw boost::system::system_error(ec);
} }
@ -322,6 +331,7 @@ namespace SimpleWeb {
post_process(); post_process();
} }
else { else {
std::lock_guard<std::mutex> lock(socket_mutex);
socket=nullptr; socket=nullptr;
throw boost::system::system_error(ec); throw boost::system::system_error(ec);
} }
@ -347,7 +357,10 @@ namespace SimpleWeb {
resolver.async_resolve(query, [this](const boost::system::error_code &ec, resolver.async_resolve(query, [this](const boost::system::error_code &ec,
boost::asio::ip::tcp::resolver::iterator it){ boost::asio::ip::tcp::resolver::iterator it){
if(!ec) { if(!ec) {
socket=std::unique_ptr<HTTP>(new HTTP(io_service)); {
std::lock_guard<std::mutex> lock(socket_mutex);
socket=std::unique_ptr<HTTP>(new HTTP(io_service));
}
boost::asio::async_connect(*socket, it, [this] boost::asio::async_connect(*socket, it, [this]
(const boost::system::error_code &ec, boost::asio::ip::tcp::resolver::iterator /*it*/){ (const boost::system::error_code &ec, boost::asio::ip::tcp::resolver::iterator /*it*/){
@ -356,12 +369,14 @@ namespace SimpleWeb {
this->socket->set_option(option); this->socket->set_option(option);
} }
else { else {
std::lock_guard<std::mutex> lock(socket_mutex);
this->socket=nullptr; this->socket=nullptr;
throw boost::system::system_error(ec); throw boost::system::system_error(ec);
} }
}); });
} }
else { else {
std::lock_guard<std::mutex> lock(socket_mutex);
socket=nullptr; socket=nullptr;
throw boost::system::system_error(ec); throw boost::system::system_error(ec);
} }

View file

@ -40,7 +40,10 @@ namespace SimpleWeb {
resolver.async_resolve(query, [this] resolver.async_resolve(query, [this]
(const boost::system::error_code &ec, boost::asio::ip::tcp::resolver::iterator it){ (const boost::system::error_code &ec, boost::asio::ip::tcp::resolver::iterator it){
if(!ec) { if(!ec) {
socket=std::unique_ptr<HTTPS>(new HTTPS(io_service, context)); {
std::lock_guard<std::mutex> lock(socket_mutex);
socket=std::unique_ptr<HTTPS>(new HTTPS(io_service, context));
}
boost::asio::async_connect(socket->lowest_layer(), it, [this] boost::asio::async_connect(socket->lowest_layer(), it, [this]
(const boost::system::error_code &ec, boost::asio::ip::tcp::resolver::iterator /*it*/){ (const boost::system::error_code &ec, boost::asio::ip::tcp::resolver::iterator /*it*/){
@ -54,18 +57,21 @@ namespace SimpleWeb {
if(timer) if(timer)
timer->cancel(); timer->cancel();
if(ec) { if(ec) {
std::lock_guard<std::mutex> lock(socket_mutex);
this->socket=nullptr; this->socket=nullptr;
throw boost::system::system_error(ec); throw boost::system::system_error(ec);
} }
}); });
} }
else { else {
std::lock_guard<std::mutex> lock(socket_mutex);
this->socket=nullptr; this->socket=nullptr;
throw boost::system::system_error(ec); throw boost::system::system_error(ec);
} }
}); });
} }
else { else {
std::lock_guard<std::mutex> lock(socket_mutex);
socket=nullptr; socket=nullptr;
throw boost::system::system_error(ec); throw boost::system::system_error(ec);
} }