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
as alerts, and log level is controlled by the alert mask.
* 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
, callback_t const& h);
void abort();
private:
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;
cache_t m_cache;
io_service& m_ios;
// all lookups in this resolver are aborted on shutdown.
tcp::resolver m_resolver;
// lookups in this resolver are not aborted on shutdown
tcp::resolver m_critical_resolver;
// max number of cached entries
int m_max_size;

View File

@ -48,14 +48,22 @@ struct resolver_interface
typedef boost::function<void(error_code const&, std::vector<address> const&)>
callback_t;
// prefer_cache will always use the cache if we have
// an entry, regardless of how old it is. This is usefull
// when completing the lookup quickly is more important
// than accuracy
enum flags_t { prefer_cache = 1 };
enum flags_t
{
// this flag will make async_resolve() always use the cache if we have an
// entry, regardless of how old it is. This is usefull when completing the
// 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
, callback_t const& h) = 0;
virtual void abort() = 0;
};
}

View File

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

View File

@ -39,6 +39,7 @@ namespace libtorrent
resolver::resolver(io_service& ios)
: m_ios(ios)
, m_resolver(ios)
, m_critical_resolver(ios)
, m_max_size(700)
, m_timeout(seconds(1200))
{}
@ -108,8 +109,21 @@ namespace libtorrent
#if defined TORRENT_ASIO_DEBUGGING
add_outstanding_async("resolver::on_lookup");
#endif
m_resolver.async_resolve(q, boost::bind(&resolver::on_lookup, this, _1, _2
, h, host));
if (flags & resolver_interface::abort_on_shutdown)
{
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
session_log(" *** ABORT CALLED ***");
#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
m_abort = true;
error_code ec;
@ -5340,7 +5346,7 @@ retry:
#if defined TORRENT_ASIO_DEBUGGING
add_outstanding_async("session_impl::on_dht_router_name_lookup");
#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
, this, _1, _2, node.second));
}

View File

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

View File

@ -773,6 +773,8 @@ void udp_socket::set_proxy_settings(proxy_settings const& ps)
{
m_queue_packets = true;
// 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);
++m_outstanding_ops;
#if TORRENT_USE_ASSERTS

View File

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