From 2d9be885ec75bcf34f221ece73045499274a3605 Mon Sep 17 00:00:00 2001 From: clemahieu Date: Fri, 3 Feb 2017 15:56:23 -0600 Subject: [PATCH] Using io_service passed in to server rather than managing our own. --- src/CMakeLists.txt | 1 - src/asio_io_service_pool.cc | 102 ----------------------- src/asio_io_service_pool.h | 95 --------------------- src/asio_server.cc | 27 ++---- src/asio_server.h | 10 +-- src/asio_server_http2.cc | 11 +-- src/asio_server_http2_impl.cc | 15 +--- src/asio_server_http2_impl.h | 7 +- src/includes/nghttp2/asio_http2_server.h | 13 +-- 9 files changed, 18 insertions(+), 263 deletions(-) delete mode 100644 src/asio_io_service_pool.cc delete mode 100644 src/asio_io_service_pool.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0648f6f5..b1c0fea4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -219,7 +219,6 @@ if(ENABLE_ASIO_LIB) ssl.cc timegm.c asio_common.cc - asio_io_service_pool.cc asio_server_http2.cc asio_server_http2_impl.cc asio_server.cc diff --git a/src/asio_io_service_pool.cc b/src/asio_io_service_pool.cc deleted file mode 100644 index ae4220c2..00000000 --- a/src/asio_io_service_pool.cc +++ /dev/null @@ -1,102 +0,0 @@ -/* - * nghttp2 - HTTP/2 C Library - * - * Copyright (c) 2014 Tatsuhiro Tsujikawa - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -// We wrote this code based on the original code which has the -// following license: -// -// io_service_pool.cpp -// ~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2013 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// -#include "asio_io_service_pool.h" - -namespace nghttp2 { - -namespace asio_http2 { - -io_service_pool::io_service_pool(std::size_t pool_size) : next_io_service_(0) { - if (pool_size == 0) { - throw std::runtime_error("io_service_pool size is 0"); - } - - // Give all the io_services work to do so that their run() functions will not - // exit until they are explicitly stopped. - for (std::size_t i = 0; i < pool_size; ++i) { - auto io_service = std::make_shared(); - auto work = std::make_shared(*io_service); - io_services_.push_back(io_service); - work_.push_back(work); - } -} - -void io_service_pool::run(bool asynchronous) { - // Create a pool of threads to run all of the io_services. - for (std::size_t i = 0; i < io_services_.size(); ++i) { - futures_.push_back(std::async(std::launch::async, - (size_t(boost::asio::io_service::*)(void)) & - boost::asio::io_service::run, - io_services_[i])); - } - - if (!asynchronous) { - join(); - } -} - -void io_service_pool::join() { - // Wait for all threads in the pool to exit. - for (auto &fut : futures_) { - fut.get(); - } -} - -void io_service_pool::stop() { - // Explicitly stop all io_services. - for (auto &iosv : io_services_) { - iosv->stop(); - } -} - -boost::asio::io_service &io_service_pool::get_io_service() { - // Use a round-robin scheme to choose the next io_service to use. - auto &io_service = *io_services_[next_io_service_]; - ++next_io_service_; - if (next_io_service_ == io_services_.size()) { - next_io_service_ = 0; - } - return io_service; -} - -const std::vector> & -io_service_pool::io_services() const { - return io_services_; -} - -} // namespace asio_http2 - -} // namespace nghttp2 diff --git a/src/asio_io_service_pool.h b/src/asio_io_service_pool.h deleted file mode 100644 index c9ce1de4..00000000 --- a/src/asio_io_service_pool.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * nghttp2 - HTTP/2 C Library - * - * Copyright (c) 2014 Tatsuhiro Tsujikawa - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -// We wrote this code based on the original code which has the -// following license: -// -// io_service_pool.hpp -// ~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2013 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef ASIO_IO_SERVICE_POOL_H -#define ASIO_IO_SERVICE_POOL_H - -#include "nghttp2_config.h" - -#include -#include -#include - -#include -#include - -#include - -namespace nghttp2 { - -namespace asio_http2 { - -/// A pool of io_service objects. -class io_service_pool : private boost::noncopyable { -public: - /// Construct the io_service pool. - explicit io_service_pool(std::size_t pool_size); - - /// Run all io_service objects in the pool. - void run(bool asynchronous = false); - - /// Stop all io_service objects in the pool. - void stop(); - - /// Join on all io_service objects in the pool. - void join(); - - /// Get an io_service to use. - boost::asio::io_service &get_io_service(); - - /// Get access to all io_service objects. - const std::vector> & - io_services() const; - -private: - /// The pool of io_services. - std::vector> io_services_; - - /// The work that keeps the io_services running. - std::vector> work_; - - /// The next io_service to use for a connection. - std::size_t next_io_service_; - - /// Futures to all the io_service objects - std::vector> futures_; -}; - -} // namespace asio_http2 - -} // namespace nghttp2 - -#endif // ASIO_IO_SERVICE_POOL_H diff --git a/src/asio_server.cc b/src/asio_server.cc index bd474c1b..a38fd7fc 100644 --- a/src/asio_server.cc +++ b/src/asio_server.cc @@ -44,11 +44,11 @@ namespace nghttp2 { namespace asio_http2 { namespace server { -server::server(std::size_t io_service_pool_size, - const boost::posix_time::time_duration &tls_handshake_timeout, +server::server(boost::asio::io_service &service, + const boost::posix_time::time_duration &tls_handshake_timeout, const boost::posix_time::time_duration &read_timeout) - : io_service_pool_(io_service_pool_size), - tls_handshake_timeout_(tls_handshake_timeout), + : service_(service), + tls_handshake_timeout_(tls_handshake_timeout), read_timeout_(read_timeout) {} boost::system::error_code @@ -70,8 +70,6 @@ server::listen_and_serve(boost::system::error_code &ec, } } - io_service_pool_.run(asynchronous); - return ec; } @@ -81,7 +79,7 @@ boost::system::error_code server::bind_and_listen(boost::system::error_code &ec, int backlog) { // Open the acceptor with the option to reuse the address (i.e. // SO_REUSEADDR). - tcp::resolver resolver(io_service_pool_.get_io_service()); + tcp::resolver resolver(service_); tcp::resolver::query query(address, port); auto it = resolver.resolve(query, ec); if (ec) { @@ -90,7 +88,7 @@ boost::system::error_code server::bind_and_listen(boost::system::error_code &ec, for (; it != tcp::resolver::iterator(); ++it) { tcp::endpoint endpoint = *it; - auto acceptor = tcp::acceptor(io_service_pool_.get_io_service()); + auto acceptor = tcp::acceptor(service_); if (acceptor.open(endpoint.protocol(), ec)) { continue; @@ -126,7 +124,7 @@ void server::start_accept(boost::asio::ssl::context &tls_context, tcp::acceptor &acceptor, serve_mux &mux) { auto new_connection = std::make_shared>( mux, tls_handshake_timeout_, read_timeout_, - io_service_pool_.get_io_service(), tls_context); + service_, tls_context); acceptor.async_accept( new_connection->socket().lowest_layer(), @@ -159,8 +157,7 @@ void server::start_accept(boost::asio::ssl::context &tls_context, void server::start_accept(tcp::acceptor &acceptor, serve_mux &mux) { auto new_connection = std::make_shared>( - mux, tls_handshake_timeout_, read_timeout_, - io_service_pool_.get_io_service()); + mux, tls_handshake_timeout_, read_timeout_, service_); acceptor.async_accept( new_connection->socket(), [this, &acceptor, &mux, new_connection]( @@ -176,19 +173,11 @@ void server::start_accept(tcp::acceptor &acceptor, serve_mux &mux) { } void server::stop() { - io_service_pool_.stop(); for (auto &acceptor : acceptors_) { acceptor.close(); } } -void server::join() { io_service_pool_.join(); } - -const std::vector> & -server::io_services() const { - return io_service_pool_.io_services(); -} - } // namespace server } // namespace asio_http2 } // namespace nghttp2 diff --git a/src/asio_server.h b/src/asio_server.h index ba840348..c2a7ce00 100644 --- a/src/asio_server.h +++ b/src/asio_server.h @@ -44,11 +44,10 @@ #include #include +#include #include -#include "asio_io_service_pool.h" - namespace nghttp2 { namespace asio_http2 { @@ -63,7 +62,7 @@ using ssl_socket = boost::asio::ssl::stream; class server : private boost::noncopyable { public: - explicit server(std::size_t io_service_pool_size, + explicit server(boost::asio::io_service &service, const boost::posix_time::time_duration &tls_handshake_timeout, const boost::posix_time::time_duration &read_timeout); @@ -91,10 +90,7 @@ private: const std::string &address, const std::string &port, int backlog); - - /// The pool of io_service objects used to perform asynchronous - /// operations. - io_service_pool io_service_pool_; + boost::asio::io_service &service_; /// Acceptor used to listen for incoming connections. std::vector acceptors_; diff --git a/src/asio_server_http2.cc b/src/asio_server_http2.cc index 997fd402..f741403c 100644 --- a/src/asio_server_http2.cc +++ b/src/asio_server_http2.cc @@ -36,7 +36,7 @@ namespace asio_http2 { namespace server { -http2::http2() : impl_(make_unique()) {} +http2::http2(boost::asio::io_service &service) : impl_(make_unique(service)) {} http2::~http2() {} @@ -65,8 +65,6 @@ boost::system::error_code http2::listen_and_serve( return impl_->listen_and_serve(ec, &tls_context, address, port, asynchronous); } -void http2::num_threads(size_t num_threads) { impl_->num_threads(num_threads); } - void http2::backlog(int backlog) { impl_->backlog(backlog); } void http2::tls_handshake_timeout(const boost::posix_time::time_duration &t) { @@ -83,13 +81,6 @@ bool http2::handle(std::string pattern, request_cb cb) { void http2::stop() { impl_->stop(); } -void http2::join() { return impl_->join(); } - -const std::vector> & -http2::io_services() const { - return impl_->io_services(); -} - } // namespace server } // namespace asio_http2 diff --git a/src/asio_server_http2_impl.cc b/src/asio_server_http2_impl.cc index da138b7a..e270e53f 100644 --- a/src/asio_server_http2_impl.cc +++ b/src/asio_server_http2_impl.cc @@ -37,8 +37,8 @@ namespace asio_http2 { namespace server { -http2_impl::http2_impl() - : num_threads_(1), +http2_impl::http2_impl(boost::asio::io_service &service) + : service_(service), backlog_(-1), tls_handshake_timeout_(boost::posix_time::seconds(60)), read_timeout_(boost::posix_time::seconds(60)) {} @@ -47,13 +47,11 @@ boost::system::error_code http2_impl::listen_and_serve( boost::system::error_code &ec, boost::asio::ssl::context *tls_context, const std::string &address, const std::string &port, bool asynchronous) { server_.reset( - new server(num_threads_, tls_handshake_timeout_, read_timeout_)); + new server(service_, tls_handshake_timeout_, read_timeout_)); return server_->listen_and_serve(ec, tls_context, address, port, backlog_, mux_, asynchronous); } -void http2_impl::num_threads(size_t num_threads) { num_threads_ = num_threads; } - void http2_impl::backlog(int backlog) { backlog_ = backlog; } void http2_impl::tls_handshake_timeout( @@ -71,13 +69,6 @@ bool http2_impl::handle(std::string pattern, request_cb cb) { void http2_impl::stop() { return server_->stop(); } -void http2_impl::join() { return server_->join(); } - -const std::vector> & -http2_impl::io_services() const { - return server_->io_services(); -} - } // namespace server } // namespace asio_http2 diff --git a/src/asio_server_http2_impl.h b/src/asio_server_http2_impl.h index b55b68c5..18029dc8 100644 --- a/src/asio_server_http2_impl.h +++ b/src/asio_server_http2_impl.h @@ -41,7 +41,7 @@ class server; class http2_impl { public: - http2_impl(); + http2_impl(boost::asio::io_service &service); boost::system::error_code listen_and_serve( boost::system::error_code &ec, boost::asio::ssl::context *tls_context, const std::string &address, const std::string &port, bool asynchronous); @@ -51,13 +51,10 @@ public: void read_timeout(const boost::posix_time::time_duration &t); bool handle(std::string pattern, request_cb cb); void stop(); - void join(); - const std::vector> & - io_services() const; private: std::unique_ptr server_; - std::size_t num_threads_; + boost::asio::io_service &service_; int backlog_; serve_mux mux_; boost::posix_time::time_duration tls_handshake_timeout_; diff --git a/src/includes/nghttp2/asio_http2_server.h b/src/includes/nghttp2/asio_http2_server.h index 5818e301..c0774ef1 100644 --- a/src/includes/nghttp2/asio_http2_server.h +++ b/src/includes/nghttp2/asio_http2_server.h @@ -132,7 +132,7 @@ class http2_impl; class http2 { public: - http2(); + http2(boost::asio::io_service &service); ~http2(); http2(http2 &&other) noexcept; @@ -190,10 +190,6 @@ public: // equivalent .- and ..-free URL. bool handle(std::string pattern, request_cb cb); - // Sets number of native threads to handle incoming HTTP request. - // It defaults to 1. - void num_threads(size_t num_threads); - // Sets the maximum length to which the queue of pending // connections. void backlog(int backlog); @@ -207,13 +203,6 @@ public: // Gracefully stop http2 server void stop(); - // Join on http2 server and wait for it to fully stop - void join(); - - // Get access to the io_service objects. - const std::vector> & - io_services() const; - private: std::unique_ptr impl_; };