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
* fix issue related to unloading torrents
* fixed finished-time calculation

View File

@ -1110,12 +1110,26 @@ namespace libtorrent
void inc_refcount(char const* purpose);
int refcount() const { return m_refcount; }
void inc_num_connecting()
{ ++m_num_connecting; }
void dec_num_connecting()
void inc_num_connecting(torrent_peer* pp)
{
++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);
--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; }
@ -1127,7 +1141,7 @@ namespace libtorrent
void set_ssl_cert_buffer(std::string const& certificate
, std::string const& private_key
, 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
int num_time_critical_pieces() const
@ -1646,6 +1660,10 @@ namespace libtorrent
// counting the peer connections that say true for is_seed()
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
// session_time. This is signed because it must be able to represent time
// before the session started.

View File

@ -208,7 +208,6 @@ namespace libtorrent
// if t is NULL, we better not be connecting, since
// we can't decrement the connecting counter
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_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 (!m_connecting) return;
if (m_connecting && t) t->inc_num_connecting(m_peer_info);
#ifndef TORRENT_DISABLE_LOGGING
peer_log(peer_log_alert::outgoing, "OPEN", "protocol: %s"
, (m_remote.address().is_v4()?"IPv4":"IPv6"));
@ -820,7 +821,7 @@ namespace libtorrent
if (m_connecting)
{
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;
}
@ -4014,7 +4015,7 @@ namespace libtorrent
if (m_connecting)
{
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;
}
@ -4228,7 +4229,7 @@ namespace libtorrent
if (m_connecting)
{
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;
}
@ -4730,7 +4731,7 @@ namespace libtorrent
if (m_connecting)
{
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;
}
disconnect(errors::torrent_aborted, op_bittorrent);
@ -6330,7 +6331,7 @@ namespace libtorrent
if (m_connecting)
{
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;
}
@ -6358,7 +6359,7 @@ namespace libtorrent
}
// 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_ses.verify_bound_address(m_local.address()

View File

@ -269,6 +269,7 @@ namespace libtorrent
, m_should_be_loaded(true)
, m_last_download((std::numeric_limits<boost::int16_t>::min)())
, m_num_seeds(0)
, m_num_connecting_seeds(0)
, m_last_upload((std::numeric_limits<boost::int16_t>::min)())
, m_storage_tick(0)
, m_auto_managed(p.flags & add_torrent_params::flag_auto_managed)
@ -3662,7 +3663,7 @@ namespace libtorrent
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
// 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
// seeds than downloaders, enter sequential download mode
// (for performance)
int downloaders = num_downloaders();
int seeds = num_seeds();
int const downloaders = num_downloaders();
int const seeds = num_seeds();
m_auto_sequential = downloaders * 10 <= seeds
&& seeds > 9;
}
@ -9063,6 +9064,8 @@ namespace libtorrent
int seeds = 0;
int num_uploads = 0;
int num_connecting = 0;
int num_connecting_seeds = 0;
std::map<piece_block, int> num_requests;
for (const_peer_iterator i = this->begin(); i != this->end(); ++i)
{
@ -9072,6 +9075,11 @@ namespace libtorrent
#endif
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)
++seeds;
@ -9094,6 +9102,14 @@ namespace libtorrent
}
TORRENT_ASSERT(num_uploads == int(m_num_uploads));
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())
{
@ -12244,20 +12260,27 @@ namespace libtorrent
m_stats_counters.inc_stats_counter(counters::recv_failed_bytes, b);
}
// the number of connected peers that are seeds
int torrent::num_seeds() const
{
TORRENT_ASSERT(is_single_thread());
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
{
TORRENT_ASSERT(is_single_thread());
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