From 1b5f0626788ca529564375b2687d4c288dfc2743 Mon Sep 17 00:00:00 2001 From: eidheim <=> Date: Wed, 22 May 2019 11:50:18 +0000 Subject: [PATCH] New asio: removed use of strand, and fixed steady_timer constructor call --- asio_compatibility.hpp | 14 +++------- client_http.hpp | 2 +- server_http.hpp | 58 ++++++++++++++++++++---------------------- 3 files changed, 32 insertions(+), 42 deletions(-) diff --git a/asio_compatibility.hpp b/asio_compatibility.hpp index 759c595..c864900 100644 --- a/asio_compatibility.hpp +++ b/asio_compatibility.hpp @@ -37,8 +37,8 @@ namespace SimpleWeb { return asio::ip::make_address(str); } template - io_context &get_socket_context(socket_type &socket) { - return socket.get_executor().context(); + asio::executor get_socket_executor(socket_type &socket) { + return socket.get_executor(); } template void async_resolve(asio::ip::tcp::resolver &resolver, const std::pair &host_port, handler_type &&handler) { @@ -48,10 +48,6 @@ namespace SimpleWeb { void post(executor_type &executor, handler_type &&handler) { asio::post(executor, handler); } - template - asio::executor_binder::type, executor_type> bind_executor(executor_type &executor, handler_type &&handler) { - return asio::bind_executor(executor, handler); - } #else using io_context = asio::io_service; using resolver_results = asio::ip::tcp::resolver::iterator; @@ -64,7 +60,7 @@ namespace SimpleWeb { return asio::ip::address::from_string(str); } template - io_context &get_socket_context(socket_type &socket) { + io_context &get_socket_executor(socket_type &socket) { return socket.get_io_service(); } template @@ -75,10 +71,6 @@ namespace SimpleWeb { void post(executor_type &executor, handler_type &&handler) { executor.post(handler); } - template - asio::detail::wrapped_handler bind_executor(executor_type &executor, handler_type &&handler) { - return executor.wrap(handler); - } #endif } // namespace SimpleWeb diff --git a/client_http.hpp b/client_http.hpp index bb2205a..fd2471f 100644 --- a/client_http.hpp +++ b/client_http.hpp @@ -99,7 +99,7 @@ namespace SimpleWeb { timer = nullptr; return; } - timer = std::unique_ptr(new asio::steady_timer(get_socket_context(*socket), std::chrono::seconds(seconds))); + timer = std::unique_ptr(new asio::steady_timer(get_socket_executor(*socket), std::chrono::seconds(seconds))); auto self = this->shared_from_this(); timer->async_wait([self](const error_code &ec) { if(!ec) { diff --git a/server_http.hpp b/server_http.hpp index 01d4835..d86e5c7 100644 --- a/server_http.hpp +++ b/server_http.hpp @@ -45,10 +45,10 @@ namespace SimpleWeb { std::shared_ptr session; long timeout_content; - io_context::strand strand; + std::mutex send_queue_mutex; std::list, std::function>> send_queue; - Response(std::shared_ptr session_, long timeout_content) noexcept : std::ostream(nullptr), session(std::move(session_)), timeout_content(timeout_content), strand(get_socket_context(*session->connection->socket)) { + Response(std::shared_ptr session_, long timeout_content) noexcept : std::ostream(nullptr), session(std::move(session_)), timeout_content(timeout_content) { rdbuf(streambuf.get()); } @@ -70,30 +70,30 @@ namespace SimpleWeb { *this << "\r\n"; } + /// send_queue_mutex must be locked here void send_from_queue() { auto self = this->shared_from_this(); - SimpleWeb::post(strand, [self]() { - asio::async_write(*self->session->connection->socket, *self->send_queue.begin()->first, SimpleWeb::bind_executor(self->strand, [self](const error_code &ec, std::size_t /*bytes_transferred*/) { - auto lock = self->session->connection->handler_runner->continue_lock(); - if(!lock) - return; - if(!ec) { - auto it = self->send_queue.begin(); - if(it->second) - it->second(ec); - self->send_queue.erase(it); - if(self->send_queue.size() > 0) - self->send_from_queue(); + asio::async_write(*self->session->connection->socket, *send_queue.begin()->first, [self](const error_code &ec, std::size_t /*bytes_transferred*/) { + auto lock = self->session->connection->handler_runner->continue_lock(); + if(!lock) + return; + std::lock_guard send_queue_lock(self->send_queue_mutex); + if(!ec) { + auto it = self->send_queue.begin(); + if(it->second) + it->second(ec); + self->send_queue.erase(it); + if(self->send_queue.size() > 0) + self->send_from_queue(); + } + else { + // All handlers in the queue is called with ec: + for(auto &pair : self->send_queue) { + if(pair.second) + pair.second(ec); } - else { - // All handlers in the queue is called with ec: - for(auto &pair : self->send_queue) { - if(pair.second) - pair.second(ec); - } - self->send_queue.clear(); - } - })); + self->send_queue.clear(); + } }); } @@ -123,12 +123,10 @@ namespace SimpleWeb { this->streambuf = std::unique_ptr(new asio::streambuf()); rdbuf(this->streambuf.get()); - auto self = this->shared_from_this(); - SimpleWeb::post(strand, [self, streambuf, callback]() { - self->send_queue.emplace_back(streambuf, callback); - if(self->send_queue.size() == 1) - self->send_from_queue(); - }); + std::lock_guard lock(send_queue_mutex); + send_queue.emplace_back(streambuf, callback); + if(send_queue.size() == 1) + send_from_queue(); } /// Write directly to stream buffer using std::ostream::write @@ -278,7 +276,7 @@ namespace SimpleWeb { return; } - timer = std::unique_ptr(new asio::steady_timer(get_socket_context(*socket), std::chrono::seconds(seconds))); + timer = std::unique_ptr(new asio::steady_timer(get_socket_executor(*socket), std::chrono::seconds(seconds))); auto self = this->shared_from_this(); timer->async_wait([self](const error_code &ec) { if(!ec)