From a1f0075d62d14021b46e0f813ddee89f0646466f Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Mon, 8 Jan 2018 03:03:50 -0800 Subject: [PATCH] ircd::net: Improve the timeout callback related. --- include/ircd/net/socket.h | 6 ++--- ircd/net.cc | 54 ++++++++++++++++++++++----------------- 2 files changed, 34 insertions(+), 26 deletions(-) diff --git a/include/ircd/net/socket.h b/include/ircd/net/socket.h index 0d1c7712a..e6b577f3d 100644 --- a/include/ircd/net/socket.h +++ b/include/ircd/net/socket.h @@ -48,8 +48,8 @@ struct ircd::net::socket using wait_type = ip::tcp::socket::wait_type; using message_flags = asio::socket_base::message_flags; using handshake_type = asio::ssl::stream::handshake_type; - using ec_handler = std::function; - using eptr_handler = std::function; + using ec_handler = std::function; + using eptr_handler = std::function; struct stat { @@ -69,7 +69,7 @@ struct ircd::net::socket void handle_disconnect(std::shared_ptr, eptr_handler, const error_code &) noexcept; void handle_handshake(std::weak_ptr, eptr_handler, const error_code &) noexcept; void handle_connect(std::weak_ptr, const open_opts, eptr_handler, const error_code &) noexcept; - void handle_timeout(std::weak_ptr, const error_code &) noexcept; + void handle_timeout(std::weak_ptr, ec_handler, const error_code &) noexcept; void handle(std::weak_ptr, ec_handler, const error_code &) noexcept; public: diff --git a/ircd/net.cc b/ircd/net.cc index 82dfd03de..46fc330f4 100644 --- a/ircd/net.cc +++ b/ircd/net.cc @@ -1384,48 +1384,56 @@ catch(const std::exception &e) void ircd::net::socket::handle_timeout(const std::weak_ptr wp, + ec_handler callback, const error_code &ec) noexcept try { using namespace boost::system::errc; - if(!wp.expired()) switch(ec.value()) + switch(ec.value()) { // A 'success' for this handler means there was a timeout on the socket - case success: + case success: if(likely(!wp.expired())) { assert(timedout == false); timedout = true; sd.cancel(); break; } + else break; // A cancelation means there was no timeout. - case operation_canceled: + case operation_canceled: if(likely(!wp.expired())) { assert(ec.category() == boost::system::system_category()); assert(timedout == false); timedout = false; break; } + else break; // All other errors are unexpected, logged and ignored here. default: - throw boost::system::system_error(ec); + { + log.critical("socket(%p): handle_timeout: unexpected: %s\n", + (const void *)this, + string(ec)); + assert(0); + break; + } } -} -catch(const boost::system::system_error &e) -{ - log.critical("socket(%p): handle_timeout: unexpected: %s\n", - (const void *)this, - e.what()); - assert(0); + + if(callback) + call_user(callback, ec); } catch(const std::exception &e) { - log.error("socket(%p): handle timeout: %s", - (const void *)this, - e.what()); + log.critical("socket(%p): handle timeout: %s", + (const void *)this, + e.what()); + assert(0); + if(callback) + call_user(callback, ec); } void @@ -1746,31 +1754,31 @@ noexcept boost::system::error_code ec; timer.cancel(ec); assert(!ec); - return duration_cast(ret); } void ircd::net::socket::set_timeout(const milliseconds &t) { - cancel_timeout(); - if(t < milliseconds(0)) - return; - - timer.expires_from_now(t); - timer.async_wait(std::bind(&socket::handle_timeout, this, weak_from(*this), ph::_1)); + set_timeout(t, nullptr); } void ircd::net::socket::set_timeout(const milliseconds &t, - ec_handler h) + ec_handler callback) { cancel_timeout(); + timedout = false; if(t < milliseconds(0)) return; + auto handler + { + std::bind(&socket::handle_timeout, this, weak_from(*this), std::move(callback), ph::_1) + }; + timer.expires_from_now(t); - timer.async_wait(std::move(h)); + timer.async_wait(std::move(handler)); } bool