From 33e5b4291036bbdad075f4a549491af72d8a0618 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 17 Jun 2014 09:09:12 +0200 Subject: [PATCH 1/2] rpc: Ignore and log errors during cancel Cancelling the RPC acceptors can sometimes result in an error about a bad file descriptor. As this is the shutdown sequence we need to continue nevertheless, ignore these errors, log a warning and proceed. Fixes #4352. --- src/rpcserver.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index d4ceb7f995..2f7f5cc2ad 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -700,11 +700,20 @@ void StopRPCThreads() // First, cancel all timers and acceptors // This is not done automatically by ->stop(), and in some cases the destructor of // asio::io_service can hang if this is skipped. + boost::system::error_code ec; BOOST_FOREACH(const boost::shared_ptr &acceptor, rpc_acceptors) - acceptor->cancel(); + { + acceptor->cancel(ec); + if (ec) + LogPrintf("%s: Warning: %s when cancelling acceptor", __func__, ec.message()); + } rpc_acceptors.clear(); BOOST_FOREACH(const PAIRTYPE(std::string, boost::shared_ptr) &timer, deadlineTimers) - timer.second->cancel(); + { + timer.second->cancel(ec); + if (ec) + LogPrintf("%s: Warning: %s when cancelling timer", __func__, ec.message()); + } deadlineTimers.clear(); rpc_io_service->stop(); From 6afa49329de860c080cdfd9b1c65afe313a43860 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 19 Jun 2014 08:19:07 +0200 Subject: [PATCH 2/2] rpc: Add acceptors only when listening succeeded --- src/rpcserver.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index 2f7f5cc2ad..56b5f2de0b 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -642,7 +642,6 @@ void StartRPCThreads() LogPrintf("Binding RPC on address %s port %i (IPv4+IPv6 bind any: %i)\n", bindAddress.to_string(), endpoint.port(), bBindAny); boost::system::error_code v6_only_error; boost::shared_ptr acceptor(new ip::tcp::acceptor(*rpc_io_service)); - rpc_acceptors.push_back(acceptor); try { acceptor->open(endpoint.protocol()); @@ -658,6 +657,7 @@ void StartRPCThreads() RPCListen(acceptor, *rpc_ssl_context, fUseSSL); fListening = true; + rpc_acceptors.push_back(acceptor); // If dual IPv6/IPv4 bind succesful, skip binding to IPv4 separately if(bBindAny && bindAddress == asio::ip::address_v6::any() && !v6_only_error) break;