From 1c31213aef50832135146b52d327f2adbf49b7ad Mon Sep 17 00:00:00 2001 From: Amir Pakdel Date: Thu, 9 Feb 2017 23:34:19 -0500 Subject: [PATCH] More graceful stop of nghttp2::asio_http2::server::http2 Explicit io_service::stop() will prevent running streams from finishing their task. That means if there are already reposnes that we have called end(std::string) on them and they have not finished sending back their data, they will be closed with a NGHTTP2_INTERNAL_ERROR Instead, we can stop accepting connections and destroy all io_service::work objects to signals end of work. --- src/asio_io_service_pool.cc | 7 ++++++- src/asio_io_service_pool.h | 3 +++ src/asio_server.cc | 12 +++++++++++- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/asio_io_service_pool.cc b/src/asio_io_service_pool.cc index ae4220c2..01483664 100644 --- a/src/asio_io_service_pool.cc +++ b/src/asio_io_service_pool.cc @@ -75,13 +75,18 @@ void io_service_pool::join() { } } -void io_service_pool::stop() { +void io_service_pool::force_stop() { // Explicitly stop all io_services. for (auto &iosv : io_services_) { iosv->stop(); } } +void io_service_pool::stop() { + // Destroy all work objects to signals end of work + work_.clear(); +} + 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_]; diff --git a/src/asio_io_service_pool.h b/src/asio_io_service_pool.h index c9ce1de4..9c115338 100644 --- a/src/asio_io_service_pool.h +++ b/src/asio_io_service_pool.h @@ -62,6 +62,9 @@ public: void run(bool asynchronous = false); /// Stop all io_service objects in the pool. + void force_stop(); + + /// Destroy all work objects to signals end of work void stop(); /// Join on all io_service objects in the pool. diff --git a/src/asio_server.cc b/src/asio_server.cc index 7f361ca9..c4a74360 100644 --- a/src/asio_server.cc +++ b/src/asio_server.cc @@ -124,6 +124,11 @@ boost::system::error_code server::bind_and_listen(boost::system::error_code &ec, void server::start_accept(boost::asio::ssl::context &tls_context, tcp::acceptor &acceptor, serve_mux &mux) { + + if (!acceptor.is_open()) { + return; + } + auto new_connection = std::make_shared>( mux, tls_handshake_timeout_, read_timeout_, io_service_pool_.get_io_service(), tls_context); @@ -158,6 +163,11 @@ void server::start_accept(boost::asio::ssl::context &tls_context, } void server::start_accept(tcp::acceptor &acceptor, serve_mux &mux) { + + if (!acceptor.is_open()) { + return; + } + auto new_connection = std::make_shared>( mux, tls_handshake_timeout_, read_timeout_, io_service_pool_.get_io_service()); @@ -177,10 +187,10 @@ void server::start_accept(tcp::acceptor &acceptor, serve_mux &mux) { } void server::stop() { - io_service_pool_.stop(); for (auto &acceptor : acceptors_) { acceptor.close(); } + io_service_pool_.stop(); } void server::join() { io_service_pool_.join(); }