forked from premiere/premiere-libtorrent
merged swarm startup optimization from libtorrent_aio
This commit is contained in:
parent
37f3a70da0
commit
f3ec86169e
|
@ -245,6 +245,12 @@ namespace libtorrent
|
|||
|
||||
void open_listen_port(int flags, error_code& ec);
|
||||
|
||||
// prioritize this torrent to be allocated some connection
|
||||
// attempts, because this torrent needs more peers.
|
||||
// this is typically done when a torrent starts out and
|
||||
// need the initial push to connect peers
|
||||
void prioritize_connections(boost::weak_ptr<torrent> t);
|
||||
|
||||
// if we are listening on an IPv6 interface
|
||||
// this will return one of the IPv6 addresses on this
|
||||
// machine, otherwise just an empty endpoint
|
||||
|
@ -294,6 +300,11 @@ namespace libtorrent
|
|||
void stop_dht();
|
||||
void start_dht(entry const& startup_state);
|
||||
|
||||
// this is called for torrents when they are started
|
||||
// it will prioritize them for announcing to
|
||||
// the DHT, to get the initial peers quickly
|
||||
void prioritize_dht(boost::weak_ptr<torrent> t);
|
||||
|
||||
#ifndef TORRENT_NO_DEPRECATE
|
||||
entry dht_state() const;
|
||||
#endif
|
||||
|
@ -556,6 +567,8 @@ namespace libtorrent
|
|||
|
||||
void update_connections_limit();
|
||||
void update_unchoke_limit();
|
||||
void trigger_auto_manage();
|
||||
void on_trigger_auto_manage();
|
||||
void update_rate_settings();
|
||||
|
||||
void update_disk_thread_settings();
|
||||
|
@ -960,6 +973,9 @@ namespace libtorrent
|
|||
std::deque<boost::weak_ptr<torrent> > m_dht_torrents;
|
||||
#endif
|
||||
|
||||
// torrents prioritized to get connection attempts
|
||||
std::deque<std::pair<boost::weak_ptr<torrent>, int> > m_prio_torrents;
|
||||
|
||||
// this announce timer is used
|
||||
// by Local service discovery
|
||||
deadline_timer m_lsd_announce_timer;
|
||||
|
@ -1189,6 +1205,20 @@ namespace libtorrent
|
|||
size_type m_total_failed_bytes;
|
||||
size_type m_total_redundant_bytes;
|
||||
|
||||
// this is set to true when a torrent auto-manage
|
||||
// event is triggered, and reset whenever the message
|
||||
// is delivered and the auto-manage is executed.
|
||||
// there should never be more than a single pending auto-manage
|
||||
// message in-flight at any given time.
|
||||
bool m_pending_auto_manage;
|
||||
|
||||
// this is also set to true when triggering an auto-manage
|
||||
// of the torrents. However, if the normal auto-manage
|
||||
// timer comes along and executes the auto-management,
|
||||
// this is set to false, which means the triggered event
|
||||
// no longer needs to execute the auto-management.
|
||||
bool m_need_auto_manage;
|
||||
|
||||
// redundant bytes per category
|
||||
size_type m_redundant_bytes[7];
|
||||
|
||||
|
|
|
@ -462,6 +462,10 @@ namespace libtorrent
|
|||
// base64 encoding).
|
||||
std::string tracker_login() const;
|
||||
|
||||
// if we need a connect boost, connect some peers
|
||||
// immediately
|
||||
void do_connect_boost();
|
||||
|
||||
// returns the absolute time when the next tracker
|
||||
// announce will take place.
|
||||
ptime next_announce() const;
|
||||
|
|
|
@ -670,6 +670,8 @@ namespace aux {
|
|||
#endif
|
||||
, m_total_failed_bytes(0)
|
||||
, m_total_redundant_bytes(0)
|
||||
, m_pending_auto_manage(false)
|
||||
, m_need_auto_manage(false)
|
||||
#if (defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS) && defined BOOST_HAS_PTHREADS
|
||||
, m_network_thread(0)
|
||||
#endif
|
||||
|
@ -1307,6 +1309,23 @@ namespace aux {
|
|||
m_thread.reset(new thread(boost::bind(&session_impl::main_thread, this)));
|
||||
}
|
||||
|
||||
void session_impl::trigger_auto_manage()
|
||||
{
|
||||
if (m_pending_auto_manage) return;
|
||||
|
||||
m_pending_auto_manage = true;
|
||||
m_need_auto_manage = true;
|
||||
m_io_service.post(boost::bind(&session_impl::on_trigger_auto_manage, this));
|
||||
}
|
||||
|
||||
void session_impl::on_trigger_auto_manage()
|
||||
{
|
||||
assert(m_pending_auto_manage);
|
||||
m_pending_auto_manage = false;
|
||||
if (!m_need_auto_manage) return;
|
||||
recalculate_auto_managed_torrents();
|
||||
}
|
||||
|
||||
void session_impl::update_dht_announce_interval()
|
||||
{
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
|
@ -1665,15 +1684,6 @@ namespace aux {
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
void session_impl::add_dht_node(udp::endpoint n)
|
||||
{
|
||||
TORRENT_ASSERT(is_network_thread());
|
||||
|
||||
if (m_dht) m_dht->add_node(n);
|
||||
}
|
||||
#endif
|
||||
|
||||
feed_handle session_impl::add_feed(feed_settings const& sett)
|
||||
{
|
||||
TORRENT_ASSERT(is_network_thread());
|
||||
|
@ -3972,8 +3982,37 @@ retry:
|
|||
m_next_rss_update = min_update;
|
||||
}
|
||||
|
||||
void session_impl::prioritize_connections(boost::weak_ptr<torrent> t)
|
||||
{
|
||||
m_prio_torrents.push_back(std::make_pair(t, 10));
|
||||
}
|
||||
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
|
||||
void session_impl::add_dht_node(udp::endpoint n)
|
||||
{
|
||||
TORRENT_ASSERT(is_network_thread());
|
||||
|
||||
if (m_dht) m_dht->add_node(n);
|
||||
}
|
||||
|
||||
void session_impl::prioritize_dht(boost::weak_ptr<torrent> t)
|
||||
{
|
||||
m_dht_torrents.push_back(t);
|
||||
// trigger a DHT announce right away if we just
|
||||
// added a new torrent and there's no back-log
|
||||
if (m_dht_torrents.size() == 1)
|
||||
{
|
||||
#if defined TORRENT_ASIO_DEBUGGING
|
||||
add_outstanding_async("session_impl::on_dht_announce");
|
||||
#endif
|
||||
error_code ec;
|
||||
m_dht_announce_timer.expires_from_now(seconds(0), ec);
|
||||
m_dht_announce_timer.async_wait(
|
||||
bind(&session_impl::on_dht_announce, this, _1));
|
||||
}
|
||||
}
|
||||
|
||||
void session_impl::on_dht_announce(error_code const& e)
|
||||
{
|
||||
#if defined TORRENT_ASIO_DEBUGGING
|
||||
|
@ -3990,6 +4029,15 @@ retry:
|
|||
// announce to DHT every 15 minutes
|
||||
int delay = (std::max)(m_settings.dht_announce_interval
|
||||
/ (std::max)(int(m_torrents.size()), 1), 1);
|
||||
|
||||
if (!m_dht_torrents.empty())
|
||||
{
|
||||
// we have prioritized torrents that need
|
||||
// an initial DHT announce. Don't wait too long
|
||||
// until we announce those.
|
||||
delay = (std::min)(4, delay);
|
||||
}
|
||||
|
||||
error_code ec;
|
||||
m_dht_announce_timer.expires_from_now(seconds(delay), ec);
|
||||
m_dht_announce_timer.async_wait(
|
||||
|
@ -4125,6 +4173,8 @@ retry:
|
|||
{
|
||||
INVARIANT_CHECK;
|
||||
|
||||
m_need_auto_manage = false;
|
||||
|
||||
// these vectors are filled with auto managed torrents
|
||||
std::vector<torrent*> downloaders;
|
||||
downloaders.reserve(m_torrents.size());
|
||||
|
@ -5003,7 +5053,7 @@ retry:
|
|||
// a boat load of torrents, we postpone the recalculation until
|
||||
// we're done adding them all (since it's kind of an expensive operation)
|
||||
if (params.flags & add_torrent_params::flag_auto_managed)
|
||||
m_auto_manage_time_scaler = 2;
|
||||
trigger_auto_manage();
|
||||
|
||||
return torrent_handle(torrent_ptr);
|
||||
}
|
||||
|
|
|
@ -2104,6 +2104,9 @@ namespace libtorrent
|
|||
#endif
|
||||
pause();
|
||||
set_error(j.error, j.error_file);
|
||||
// recalculate auto-managed torrents sooner
|
||||
// in order to start checking the next torrent
|
||||
m_ses.trigger_auto_manage();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2250,6 +2253,8 @@ namespace libtorrent
|
|||
std::for_each(peers.begin(), peers.end(), boost::bind(
|
||||
&policy::add_peer, boost::ref(m_policy), _1, peer_id(0)
|
||||
, peer_info::dht, 0));
|
||||
|
||||
do_connect_boost();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -2689,31 +2694,37 @@ namespace libtorrent
|
|||
}
|
||||
}
|
||||
|
||||
if (m_need_connect_boost)
|
||||
{
|
||||
m_need_connect_boost = false;
|
||||
// this is the first tracker response for this torrent
|
||||
// instead of waiting one second for session_impl::on_tick()
|
||||
// to be called, connect to a few peers immediately
|
||||
int conns = (std::min)((std::min)((std::min)(m_ses.m_settings.torrent_connect_boost
|
||||
, m_ses.m_settings.connections_limit - m_ses.num_connections())
|
||||
, m_ses.m_half_open.free_slots())
|
||||
, m_ses.m_boost_connections - m_ses.m_settings.connection_speed);
|
||||
|
||||
while (want_more_peers() && conns > 0)
|
||||
{
|
||||
if (!m_policy.connect_one_peer(m_ses.session_time())) break;
|
||||
// increase m_ses.m_boost_connections for each connection
|
||||
// attempt. This will be deducted from the connect speed
|
||||
// the next time session_impl::on_tick() is triggered
|
||||
--conns;
|
||||
++m_ses.m_boost_connections;
|
||||
}
|
||||
}
|
||||
do_connect_boost();
|
||||
|
||||
state_updated();
|
||||
}
|
||||
|
||||
void torrent::do_connect_boost()
|
||||
{
|
||||
if (!m_need_connect_boost) return;
|
||||
|
||||
m_need_connect_boost = false;
|
||||
// this is the first tracker response for this torrent
|
||||
// instead of waiting one second for session_impl::on_tick()
|
||||
// to be called, connect to a few peers immediately
|
||||
int conns = (std::min)((std::min)((std::min)(m_ses.m_settings.torrent_connect_boost
|
||||
, m_ses.m_settings.connections_limit - m_ses.num_connections())
|
||||
, m_ses.m_half_open.free_slots())
|
||||
, m_ses.m_boost_connections - m_ses.m_settings.connection_speed);
|
||||
|
||||
while (want_more_peers() && conns > 0)
|
||||
{
|
||||
if (!m_policy.connect_one_peer(m_ses.session_time())) break;
|
||||
// increase m_ses.m_boost_connections for each connection
|
||||
// attempt. This will be deducted from the connect speed
|
||||
// the next time session_impl::on_tick() is triggered
|
||||
--conns;
|
||||
++m_ses.m_boost_connections;
|
||||
}
|
||||
|
||||
if (want_more_peers()) m_ses.prioritize_connections(shared_from_this());
|
||||
}
|
||||
|
||||
ptime torrent::next_announce() const
|
||||
{
|
||||
return m_waiting_tracker?m_tracker_timer.expires_at():min_time();
|
||||
|
@ -6184,7 +6195,7 @@ namespace libtorrent
|
|||
// under a different limit with the auto-manager. Make sure we
|
||||
// update auto-manage torrents in that case
|
||||
if (m_auto_managed)
|
||||
m_ses.m_auto_manage_time_scaler = 2;
|
||||
m_ses.trigger_auto_manage();
|
||||
}
|
||||
|
||||
// this is called when we were finished, but some files were
|
||||
|
@ -6303,7 +6314,7 @@ namespace libtorrent
|
|||
{
|
||||
// if this is an auto managed torrent, force a recalculation
|
||||
// of which torrents to have active
|
||||
m_ses.m_auto_manage_time_scaler = 2;
|
||||
m_ses.trigger_auto_manage();
|
||||
}
|
||||
|
||||
if (!is_seed())
|
||||
|
@ -6313,7 +6324,7 @@ namespace libtorrent
|
|||
|
||||
// if we just finished checking and we're not a seed, we are
|
||||
// likely to be unpaused
|
||||
m_ses.m_auto_manage_time_scaler = 2;
|
||||
m_ses.trigger_auto_manage();
|
||||
|
||||
if (is_finished() && m_state != torrent_status::finished)
|
||||
finished();
|
||||
|
@ -6858,7 +6869,7 @@ namespace libtorrent
|
|||
TORRENT_ASSERT(m_ses.is_network_thread());
|
||||
if (!m_error) return;
|
||||
bool checking_files = should_check_files();
|
||||
m_ses.m_auto_manage_time_scaler = 2;
|
||||
m_ses.trigger_auto_manage();
|
||||
m_error = error_code();
|
||||
m_error_file.clear();
|
||||
|
||||
|
@ -6923,7 +6934,7 @@ namespace libtorrent
|
|||
|
||||
// recalculate which torrents should be
|
||||
// paused
|
||||
m_ses.m_auto_manage_time_scaler = 2;
|
||||
m_ses.trigger_auto_manage();
|
||||
|
||||
if (!checking_files && should_check_files())
|
||||
{
|
||||
|
@ -7199,7 +7210,7 @@ namespace libtorrent
|
|||
|
||||
// if this torrent was just paused
|
||||
// we might have to resume some other auto-managed torrent
|
||||
m_ses.m_auto_manage_time_scaler = 2;
|
||||
m_ses.trigger_auto_manage();
|
||||
}
|
||||
|
||||
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_ERROR_LOGGING || defined TORRENT_LOGGING
|
||||
|
|
Loading…
Reference in New Issue