fix issue where num_seeds could be greater than num_peers in torrent_status (#1645)

fix issue where num_seeds could be greater than num_peers in torrent_status
This commit is contained in:
Arvid Norberg 2017-02-01 01:39:09 -05:00 committed by GitHub
parent dbd734e7a2
commit 4733670aa1
4 changed files with 59 additions and 16 deletions

View File

@ -1,3 +1,4 @@
* fix issue where num_seeds could be greater than num_peers in torrent_status
* finished non-seed torrents can also be in super-seeding mode * finished non-seed torrents can also be in super-seeding mode
* fix issue related to unloading torrents * fix issue related to unloading torrents
* fixed finished-time calculation * fixed finished-time calculation

View File

@ -1110,12 +1110,26 @@ namespace libtorrent
void inc_refcount(char const* purpose); void inc_refcount(char const* purpose);
int refcount() const { return m_refcount; } int refcount() const { return m_refcount; }
void inc_num_connecting() void inc_num_connecting(torrent_peer* pp)
{ ++m_num_connecting; } {
void dec_num_connecting() ++m_num_connecting;
TORRENT_ASSERT(m_num_connecting <= int(m_connections.size()));
if (pp->seed)
{
++m_num_connecting_seeds;
TORRENT_ASSERT(m_num_connecting_seeds <= int(m_connections.size()));
}
}
void dec_num_connecting(torrent_peer* pp)
{ {
TORRENT_ASSERT(m_num_connecting > 0); TORRENT_ASSERT(m_num_connecting > 0);
--m_num_connecting; --m_num_connecting;
if (pp->seed)
{
TORRENT_ASSERT(m_num_connecting_seeds > 0);
--m_num_connecting_seeds;
}
TORRENT_ASSERT(m_num_connecting <= int(m_connections.size()));
} }
bool is_ssl_torrent() const { return m_ssl_torrent; } bool is_ssl_torrent() const { return m_ssl_torrent; }
@ -1127,7 +1141,7 @@ namespace libtorrent
void set_ssl_cert_buffer(std::string const& certificate void set_ssl_cert_buffer(std::string const& certificate
, std::string const& private_key , std::string const& private_key
, std::string const& dh_params); , std::string const& dh_params);
boost::asio::ssl::context* ssl_ctx() const { return m_ssl_ctx.get(); } boost::asio::ssl::context* ssl_ctx() const { return m_ssl_ctx.get(); }
#endif #endif
int num_time_critical_pieces() const int num_time_critical_pieces() const
@ -1646,6 +1660,10 @@ namespace libtorrent
// counting the peer connections that say true for is_seed() // counting the peer connections that say true for is_seed()
boost::uint16_t m_num_seeds; boost::uint16_t m_num_seeds;
// this is the number of peers that are seeds, and count against
// m_num_seeds, but have not yet been connected
boost::uint16_t m_num_connecting_seeds;
// the timestamp of the last byte uploaded from this torrent specified in // the timestamp of the last byte uploaded from this torrent specified in
// session_time. This is signed because it must be able to represent time // session_time. This is signed because it must be able to represent time
// before the session started. // before the session started.

View File

@ -208,7 +208,6 @@ namespace libtorrent
// if t is NULL, we better not be connecting, since // if t is NULL, we better not be connecting, since
// we can't decrement the connecting counter // we can't decrement the connecting counter
TORRENT_ASSERT(t || !m_connecting); TORRENT_ASSERT(t || !m_connecting);
if (m_connecting && t) t->inc_num_connecting();
m_est_reciprocation_rate = m_settings.get_int(settings_pack::default_est_reciprocation_rate); m_est_reciprocation_rate = m_settings.get_int(settings_pack::default_est_reciprocation_rate);
m_channel_state[upload_channel] = peer_info::bw_idle; m_channel_state[upload_channel] = peer_info::bw_idle;
@ -369,6 +368,8 @@ namespace libtorrent
// if this is an incoming connection, we're done here // if this is an incoming connection, we're done here
if (!m_connecting) return; if (!m_connecting) return;
if (m_connecting && t) t->inc_num_connecting(m_peer_info);
#ifndef TORRENT_DISABLE_LOGGING #ifndef TORRENT_DISABLE_LOGGING
peer_log(peer_log_alert::outgoing, "OPEN", "protocol: %s" peer_log(peer_log_alert::outgoing, "OPEN", "protocol: %s"
, (m_remote.address().is_v4()?"IPv4":"IPv6")); , (m_remote.address().is_v4()?"IPv4":"IPv6"));
@ -820,7 +821,7 @@ namespace libtorrent
if (m_connecting) if (m_connecting)
{ {
m_counters.inc_stats_counter(counters::num_peers_half_open, -1); m_counters.inc_stats_counter(counters::num_peers_half_open, -1);
if (t) t->dec_num_connecting(); if (t) t->dec_num_connecting(m_peer_info);
m_connecting = false; m_connecting = false;
} }
@ -4014,7 +4015,7 @@ namespace libtorrent
if (m_connecting) if (m_connecting)
{ {
m_counters.inc_stats_counter(counters::num_peers_half_open, -1); m_counters.inc_stats_counter(counters::num_peers_half_open, -1);
if (t) t->dec_num_connecting(); if (t) t->dec_num_connecting(m_peer_info);
m_connecting = false; m_connecting = false;
} }
@ -4228,7 +4229,7 @@ namespace libtorrent
if (m_connecting) if (m_connecting)
{ {
m_counters.inc_stats_counter(counters::num_peers_half_open, -1); m_counters.inc_stats_counter(counters::num_peers_half_open, -1);
if (t) t->dec_num_connecting(); if (t) t->dec_num_connecting(m_peer_info);
m_connecting = false; m_connecting = false;
} }
@ -4730,7 +4731,7 @@ namespace libtorrent
if (m_connecting) if (m_connecting)
{ {
m_counters.inc_stats_counter(counters::num_peers_half_open, -1); m_counters.inc_stats_counter(counters::num_peers_half_open, -1);
if (t) t->dec_num_connecting(); if (t) t->dec_num_connecting(m_peer_info);
m_connecting = false; m_connecting = false;
} }
disconnect(errors::torrent_aborted, op_bittorrent); disconnect(errors::torrent_aborted, op_bittorrent);
@ -6330,7 +6331,7 @@ namespace libtorrent
if (m_connecting) if (m_connecting)
{ {
m_counters.inc_stats_counter(counters::num_peers_half_open, -1); m_counters.inc_stats_counter(counters::num_peers_half_open, -1);
if (t) t->dec_num_connecting(); if (t) t->dec_num_connecting(m_peer_info);
m_connecting = false; m_connecting = false;
} }
@ -6358,7 +6359,7 @@ namespace libtorrent
} }
// if there are outgoing interfaces specified, verify this // if there are outgoing interfaces specified, verify this
// peer is correctly bound to on of them // peer is correctly bound to one of them
if (!m_settings.get_str(settings_pack::outgoing_interfaces).empty()) if (!m_settings.get_str(settings_pack::outgoing_interfaces).empty())
{ {
if (!m_ses.verify_bound_address(m_local.address() if (!m_ses.verify_bound_address(m_local.address()

View File

@ -269,6 +269,7 @@ namespace libtorrent
, m_should_be_loaded(true) , m_should_be_loaded(true)
, m_last_download((std::numeric_limits<boost::int16_t>::min)()) , m_last_download((std::numeric_limits<boost::int16_t>::min)())
, m_num_seeds(0) , m_num_seeds(0)
, m_num_connecting_seeds(0)
, m_last_upload((std::numeric_limits<boost::int16_t>::min)()) , m_last_upload((std::numeric_limits<boost::int16_t>::min)())
, m_storage_tick(0) , m_storage_tick(0)
, m_auto_managed(p.flags & add_torrent_params::flag_auto_managed) , m_auto_managed(p.flags & add_torrent_params::flag_auto_managed)
@ -3662,7 +3663,7 @@ namespace libtorrent
return; return;
} }
if (int(m_connections.size()) - m_num_connecting < 10) if (int(m_connections.size() - m_num_connecting) < 10)
{ {
// there are too few peers. Be conservative and don't assume it's // there are too few peers. Be conservative and don't assume it's
// well seeded until we can connect to more peers // well seeded until we can connect to more peers
@ -3673,8 +3674,8 @@ namespace libtorrent
// if there are at least 10 seeds, and there are 10 times more // if there are at least 10 seeds, and there are 10 times more
// seeds than downloaders, enter sequential download mode // seeds than downloaders, enter sequential download mode
// (for performance) // (for performance)
int downloaders = num_downloaders(); int const downloaders = num_downloaders();
int seeds = num_seeds(); int const seeds = num_seeds();
m_auto_sequential = downloaders * 10 <= seeds m_auto_sequential = downloaders * 10 <= seeds
&& seeds > 9; && seeds > 9;
} }
@ -9063,6 +9064,8 @@ namespace libtorrent
int seeds = 0; int seeds = 0;
int num_uploads = 0; int num_uploads = 0;
int num_connecting = 0;
int num_connecting_seeds = 0;
std::map<piece_block, int> num_requests; std::map<piece_block, int> num_requests;
for (const_peer_iterator i = this->begin(); i != this->end(); ++i) for (const_peer_iterator i = this->begin(); i != this->end(); ++i)
{ {
@ -9072,6 +9075,11 @@ namespace libtorrent
#endif #endif
peer_connection const& p = *(*i); peer_connection const& p = *(*i);
if (p.is_connecting()) ++num_connecting;
if (p.is_connecting() && p.peer_info_struct()->seed)
++num_connecting_seeds;
if (p.peer_info_struct() && p.peer_info_struct()->seed) if (p.peer_info_struct() && p.peer_info_struct()->seed)
++seeds; ++seeds;
@ -9094,6 +9102,14 @@ namespace libtorrent
} }
TORRENT_ASSERT(num_uploads == int(m_num_uploads)); TORRENT_ASSERT(num_uploads == int(m_num_uploads));
TORRENT_ASSERT(seeds == int(m_num_seeds)); TORRENT_ASSERT(seeds == int(m_num_seeds));
TORRENT_ASSERT(num_connecting == int(m_num_connecting));
TORRENT_ASSERT(num_connecting_seeds == int(m_num_connecting_seeds));
TORRENT_ASSERT(int(m_num_uploads) <= int(m_connections.size()));
TORRENT_ASSERT(int(m_num_seeds) <= int(m_connections.size()));
TORRENT_ASSERT(int(m_num_connecting) <= int(m_connections.size()));
TORRENT_ASSERT(int(m_num_connecting_seeds) <= int(m_connections.size()));
TORRENT_ASSERT(int(m_num_connecting) + int(m_num_seeds) >= int(m_num_connecting_seeds));
TORRENT_ASSERT(int(m_num_connecting) + int(m_num_seeds) - int(m_num_connecting_seeds) <= int(m_connections.size()));
if (has_picker()) if (has_picker())
{ {
@ -12244,20 +12260,27 @@ namespace libtorrent
m_stats_counters.inc_stats_counter(counters::recv_failed_bytes, b); m_stats_counters.inc_stats_counter(counters::recv_failed_bytes, b);
} }
// the number of connected peers that are seeds
int torrent::num_seeds() const int torrent::num_seeds() const
{ {
TORRENT_ASSERT(is_single_thread()); TORRENT_ASSERT(is_single_thread());
INVARIANT_CHECK; INVARIANT_CHECK;
return m_num_seeds; return int(m_num_seeds) - int(m_num_connecting_seeds);
} }
// the number of connected peers that are not seeds
int torrent::num_downloaders() const int torrent::num_downloaders() const
{ {
TORRENT_ASSERT(is_single_thread()); TORRENT_ASSERT(is_single_thread());
INVARIANT_CHECK; INVARIANT_CHECK;
return (std::max)(0, int(m_connections.size()) - m_num_seeds - m_num_connecting); int const ret = int(m_connections.size())
- m_num_seeds
- m_num_connecting
+ m_num_connecting_seeds;
TORRENT_ASSERT(ret >= 0);
return ret;
} }
void torrent::tracker_request_error(tracker_request const& r void torrent::tracker_request_error(tracker_request const& r