cancel non-critical DNS lookups when shutting down, to cut down on shutdown delay

This commit is contained in:
Arvid Norberg 2014-12-17 02:44:27 +00:00
parent d9f41bf617
commit ae04b80fe1
9 changed files with 56 additions and 17 deletions

View File

@ -1,3 +1,5 @@
* cancel non-critical DNS lookups when shutting down, to cut down on
shutdown delay.
* greatly simplify the debug logging infrastructure. logs are now delivered * greatly simplify the debug logging infrastructure. logs are now delivered
as alerts, and log level is controlled by the alert mask. as alerts, and log level is controlled by the alert mask.
* removed auto_expand_choker. use rate_based_choker instead * removed auto_expand_choker. use rate_based_choker instead

View File

@ -53,6 +53,8 @@ struct TORRENT_EXTRA_EXPORT resolver : resolver_interface
void async_resolve(std::string const& host, int flags void async_resolve(std::string const& host, int flags
, callback_t const& h); , callback_t const& h);
void abort();
private: private:
void on_lookup(error_code const& ec, tcp::resolver::iterator i void on_lookup(error_code const& ec, tcp::resolver::iterator i
@ -67,8 +69,13 @@ private:
typedef boost::unordered_map<std::string, dns_cache_entry> cache_t; typedef boost::unordered_map<std::string, dns_cache_entry> cache_t;
cache_t m_cache; cache_t m_cache;
io_service& m_ios; io_service& m_ios;
// all lookups in this resolver are aborted on shutdown.
tcp::resolver m_resolver; tcp::resolver m_resolver;
// lookups in this resolver are not aborted on shutdown
tcp::resolver m_critical_resolver;
// max number of cached entries // max number of cached entries
int m_max_size; int m_max_size;

View File

@ -48,14 +48,22 @@ struct resolver_interface
typedef boost::function<void(error_code const&, std::vector<address> const&)> typedef boost::function<void(error_code const&, std::vector<address> const&)>
callback_t; callback_t;
// prefer_cache will always use the cache if we have enum flags_t
// an entry, regardless of how old it is. This is usefull {
// when completing the lookup quickly is more important // this flag will make async_resolve() always use the cache if we have an
// than accuracy // entry, regardless of how old it is. This is usefull when completing the
enum flags_t { prefer_cache = 1 }; // lookup quickly is more important than accuracy
prefer_cache = 1,
// set this flag for lookups that are not critical during shutdown. i.e.
// for looking up tracker names _except_ when stopping a tracker.
abort_on_shutdown = 2
};
virtual void async_resolve(std::string const& host, int flags virtual void async_resolve(std::string const& host, int flags
, callback_t const& h) = 0; , callback_t const& h) = 0;
virtual void abort() = 0;
}; };
} }

View File

@ -231,7 +231,7 @@ namespace libtorrent
, bind_interface() , bind_interface()
, tracker_req().event == tracker_request::stopped , tracker_req().event == tracker_request::stopped
? resolver_interface::prefer_cache ? resolver_interface::prefer_cache
: 0 : resolver_interface::abort_on_shutdown
#if TORRENT_USE_I2P #if TORRENT_USE_I2P
, m_i2p_conn , m_i2p_conn
#endif #endif

View File

@ -39,6 +39,7 @@ namespace libtorrent
resolver::resolver(io_service& ios) resolver::resolver(io_service& ios)
: m_ios(ios) : m_ios(ios)
, m_resolver(ios) , m_resolver(ios)
, m_critical_resolver(ios)
, m_max_size(700) , m_max_size(700)
, m_timeout(seconds(1200)) , m_timeout(seconds(1200))
{} {}
@ -108,8 +109,21 @@ namespace libtorrent
#if defined TORRENT_ASIO_DEBUGGING #if defined TORRENT_ASIO_DEBUGGING
add_outstanding_async("resolver::on_lookup"); add_outstanding_async("resolver::on_lookup");
#endif #endif
m_resolver.async_resolve(q, boost::bind(&resolver::on_lookup, this, _1, _2 if (flags & resolver_interface::abort_on_shutdown)
, h, host)); {
m_resolver.async_resolve(q, boost::bind(&resolver::on_lookup, this, _1, _2
, h, host));
}
else
{
m_critical_resolver.async_resolve(q, boost::bind(&resolver::on_lookup, this, _1, _2
, h, host));
}
}
void resolver::abort()
{
m_resolver.cancel();
} }
} }

View File

@ -979,6 +979,12 @@ namespace aux {
#if defined TORRENT_LOGGING #if defined TORRENT_LOGGING
session_log(" *** ABORT CALLED ***"); session_log(" *** ABORT CALLED ***");
#endif #endif
// this will cancel requests that are not critical for shutting down
// cleanly. i.e. essentially tracker hostname lookups that we're not
// about to send event=stopped to
m_host_resolver.abort();
// abort the main thread // abort the main thread
m_abort = true; m_abort = true;
error_code ec; error_code ec;
@ -5340,7 +5346,7 @@ retry:
#if defined TORRENT_ASIO_DEBUGGING #if defined TORRENT_ASIO_DEBUGGING
add_outstanding_async("session_impl::on_dht_router_name_lookup"); add_outstanding_async("session_impl::on_dht_router_name_lookup");
#endif #endif
m_host_resolver.async_resolve(node.first, 0 m_host_resolver.async_resolve(node.first, resolver_interface::abort_on_shutdown
, boost::bind(&session_impl::on_dht_router_name_lookup , boost::bind(&session_impl::on_dht_router_name_lookup
, this, _1, _2, node.second)); , this, _1, _2, node.second));
} }

View File

@ -3236,7 +3236,7 @@ namespace libtorrent
#if defined TORRENT_ASIO_DEBUGGING #if defined TORRENT_ASIO_DEBUGGING
add_outstanding_async("torrent::on_peer_name_lookup"); add_outstanding_async("torrent::on_peer_name_lookup");
#endif #endif
m_ses.async_resolve(i->hostname, 0 m_ses.async_resolve(i->hostname, resolver_interface::abort_on_shutdown
, boost::bind(&torrent::on_peer_name_lookup , boost::bind(&torrent::on_peer_name_lookup
, shared_from_this(), _1, _2, i->port)); , shared_from_this(), _1, _2, i->port));
} }
@ -5990,7 +5990,7 @@ namespace libtorrent
// use proxy // use proxy
web->resolving = true; web->resolving = true;
m_ses.async_resolve(ps.hostname, 0 m_ses.async_resolve(ps.hostname, resolver_interface::abort_on_shutdown
, boost::bind(&torrent::on_proxy_name_lookup, shared_from_this() , boost::bind(&torrent::on_proxy_name_lookup, shared_from_this()
, _1, _2, web, ps.port)); , _1, _2, web, ps.port));
} }
@ -6007,8 +6007,8 @@ namespace libtorrent
#endif #endif
web->resolving = true; web->resolving = true;
m_ses.async_resolve(hostname, 0, boost::bind( m_ses.async_resolve(hostname, resolver_interface::abort_on_shutdown
&torrent::on_name_lookup, shared_from_this(), _1, _2 , boost::bind(&torrent::on_name_lookup, shared_from_this(), _1, _2
, port, web, tcp::endpoint())); , port, web, tcp::endpoint()));
} }
} }
@ -6091,8 +6091,8 @@ namespace libtorrent
} }
web->resolving = true; web->resolving = true;
m_ses.async_resolve(hostname, 0, boost::bind( m_ses.async_resolve(hostname, resolver_interface::abort_on_shutdown
&torrent::on_name_lookup, shared_from_this(), _1, _2 , boost::bind(&torrent::on_name_lookup, shared_from_this(), _1, _2
, port, web, a)); , port, web, a));
} }
@ -6368,7 +6368,7 @@ namespace libtorrent
return; return;
} }
m_resolving_country = true; m_resolving_country = true;
m_ses.async_resolve(hostname, 0 m_ses.async_resolve(hostname, resolver_interface::abort_on_shutdown
, boost::bind(&torrent::on_country_lookup, shared_from_this(), _1, _2, p)); , boost::bind(&torrent::on_country_lookup, shared_from_this(), _1, _2, p));
} }

View File

@ -773,6 +773,8 @@ void udp_socket::set_proxy_settings(proxy_settings const& ps)
{ {
m_queue_packets = true; m_queue_packets = true;
// connect to socks5 server and open up the UDP tunnel // connect to socks5 server and open up the UDP tunnel
// TODO: use the system resolver_interface here
tcp::resolver::query q(ps.hostname, to_string(ps.port).elems); tcp::resolver::query q(ps.hostname, to_string(ps.port).elems);
++m_outstanding_ops; ++m_outstanding_ops;
#if TORRENT_USE_ASSERTS #if TORRENT_USE_ASSERTS

View File

@ -120,7 +120,7 @@ namespace libtorrent
m_man.host_resolver().async_resolve(hostname m_man.host_resolver().async_resolve(hostname
, tracker_req().event == tracker_request::stopped , tracker_req().event == tracker_request::stopped
? resolver_interface::prefer_cache ? resolver_interface::prefer_cache
: 0 : resolver_interface::abort_on_shutdown
, boost::bind(&udp_tracker_connection::name_lookup , boost::bind(&udp_tracker_connection::name_lookup
, shared_from_this(), _1, _2, port)); , shared_from_this(), _1, _2, port));