fixed per torrent unchoke limit
This commit is contained in:
parent
834873a15e
commit
3d3df51d45
|
@ -282,7 +282,9 @@ namespace libtorrent
|
||||||
|
|
||||||
void unchoke_peer(peer_connection& c)
|
void unchoke_peer(peer_connection& c)
|
||||||
{
|
{
|
||||||
c.send_unchoke();
|
torrent* t = c.associated_torrent().lock().get();
|
||||||
|
assert(t);
|
||||||
|
t->unchoke_peer(c);
|
||||||
++m_num_unchoked;
|
++m_num_unchoked;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -249,6 +249,13 @@ namespace libtorrent
|
||||||
void remove_url_seed(std::string const& url)
|
void remove_url_seed(std::string const& url)
|
||||||
{ m_web_seeds.erase(url); }
|
{ m_web_seeds.erase(url); }
|
||||||
|
|
||||||
|
|
||||||
|
bool free_upload_slots() const
|
||||||
|
{ return m_num_uploads < m_max_uploads; }
|
||||||
|
|
||||||
|
void choke_peer(peer_connection& c);
|
||||||
|
bool unchoke_peer(peer_connection& c);
|
||||||
|
|
||||||
// used by peer_connection to attach itself to a torrent
|
// used by peer_connection to attach itself to a torrent
|
||||||
// since incoming connections don't know what torrent
|
// since incoming connections don't know what torrent
|
||||||
// they're a part of until they have received an info_hash.
|
// they're a part of until they have received an info_hash.
|
||||||
|
@ -770,6 +777,9 @@ namespace libtorrent
|
||||||
// the maximum number of uploads for this torrent
|
// the maximum number of uploads for this torrent
|
||||||
int m_max_uploads;
|
int m_max_uploads;
|
||||||
|
|
||||||
|
// the number of unchoked peers in this torrent
|
||||||
|
int m_num_uploads;
|
||||||
|
|
||||||
// the maximum number of connections for this torrent
|
// the maximum number of connections for this torrent
|
||||||
int m_max_connections;
|
int m_max_connections;
|
||||||
|
|
||||||
|
|
|
@ -1046,14 +1046,15 @@ namespace detail
|
||||||
peer_connection* p = i->second.get();
|
peer_connection* p = i->second.get();
|
||||||
torrent* t = p->associated_torrent().lock().get();
|
torrent* t = p->associated_torrent().lock().get();
|
||||||
if (!p->peer_info_struct()
|
if (!p->peer_info_struct()
|
||||||
|
|| t == 0
|
||||||
|| !p->is_peer_interested()
|
|| !p->is_peer_interested()
|
||||||
|| p->is_disconnecting()
|
|| p->is_disconnecting()
|
||||||
|| p->is_connecting()
|
|| p->is_connecting()
|
||||||
|| (p->share_diff() < -free_upload_amount
|
|| (p->share_diff() < -free_upload_amount
|
||||||
&& t && !t->is_seed()))
|
&& !t->is_seed()))
|
||||||
{
|
{
|
||||||
if (!i->second->is_choked())
|
if (!i->second->is_choked() && t)
|
||||||
i->second->send_choke();
|
t->choke_peer(*i->second);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
peers.push_back(i->second.get());
|
peers.push_back(i->second.get());
|
||||||
|
@ -1082,9 +1083,24 @@ namespace detail
|
||||||
{
|
{
|
||||||
peer_connection* p = *i;
|
peer_connection* p = *i;
|
||||||
assert(p);
|
assert(p);
|
||||||
|
torrent* t = p->associated_torrent().lock().get();
|
||||||
|
assert(t);
|
||||||
if (unchoke_set_size > 0)
|
if (unchoke_set_size > 0)
|
||||||
{
|
{
|
||||||
if (p->is_choked()) p->send_unchoke();
|
if (p->is_choked())
|
||||||
|
{
|
||||||
|
if (t->unchoke_peer(*p))
|
||||||
|
{
|
||||||
|
--unchoke_set_size;
|
||||||
|
++m_num_unchoked;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
--unchoke_set_size;
|
||||||
|
++m_num_unchoked;
|
||||||
|
}
|
||||||
|
|
||||||
assert(p->peer_info_struct());
|
assert(p->peer_info_struct());
|
||||||
if (p->peer_info_struct()->optimistically_unchoked)
|
if (p->peer_info_struct()->optimistically_unchoked)
|
||||||
{
|
{
|
||||||
|
@ -1092,13 +1108,11 @@ namespace detail
|
||||||
m_optimistic_unchoke_time_scaler = 0;
|
m_optimistic_unchoke_time_scaler = 0;
|
||||||
p->peer_info_struct()->optimistically_unchoked = false;
|
p->peer_info_struct()->optimistically_unchoked = false;
|
||||||
}
|
}
|
||||||
--unchoke_set_size;
|
|
||||||
++m_num_unchoked;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!p->is_choked() && !p->peer_info_struct()->optimistically_unchoked)
|
if (!p->is_choked() && !p->peer_info_struct()->optimistically_unchoked)
|
||||||
p->send_choke();
|
t->choke_peer(*p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1121,15 +1135,21 @@ namespace detail
|
||||||
assert(p);
|
assert(p);
|
||||||
policy::peer* pi = p->peer_info_struct();
|
policy::peer* pi = p->peer_info_struct();
|
||||||
if (!pi) continue;
|
if (!pi) continue;
|
||||||
|
torrent* t = p->associated_torrent().lock().get();
|
||||||
|
if (!t) continue;
|
||||||
|
|
||||||
if (pi->optimistically_unchoked)
|
if (pi->optimistically_unchoked)
|
||||||
{
|
{
|
||||||
assert(current_optimistic_unchoke == m_connections.end());
|
assert(current_optimistic_unchoke == m_connections.end());
|
||||||
current_optimistic_unchoke = i;
|
current_optimistic_unchoke = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pi->last_optimistically_unchoked < last_unchoke
|
if (pi->last_optimistically_unchoked < last_unchoke
|
||||||
&& !p->is_connecting()
|
&& !p->is_connecting()
|
||||||
&& !p->is_disconnecting()
|
&& !p->is_disconnecting()
|
||||||
&& p->is_peer_interested())
|
&& p->is_peer_interested()
|
||||||
|
&& t->free_upload_slots()
|
||||||
|
&& p->is_choked())
|
||||||
{
|
{
|
||||||
last_unchoke = pi->last_optimistically_unchoked;
|
last_unchoke = pi->last_optimistically_unchoked;
|
||||||
optimistic_unchoke_candidate = i;
|
optimistic_unchoke_candidate = i;
|
||||||
|
@ -1141,11 +1161,16 @@ namespace detail
|
||||||
{
|
{
|
||||||
if (current_optimistic_unchoke != m_connections.end())
|
if (current_optimistic_unchoke != m_connections.end())
|
||||||
{
|
{
|
||||||
current_optimistic_unchoke->second->send_choke();
|
torrent* t = current_optimistic_unchoke->second->associated_torrent().lock().get();
|
||||||
|
assert(t);
|
||||||
|
t->choke_peer(*current_optimistic_unchoke->second);
|
||||||
current_optimistic_unchoke->second->peer_info_struct()->optimistically_unchoked = false;
|
current_optimistic_unchoke->second->peer_info_struct()->optimistically_unchoked = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
optimistic_unchoke_candidate->second->send_unchoke();
|
torrent* t = optimistic_unchoke_candidate->second->associated_torrent().lock().get();
|
||||||
|
assert(t);
|
||||||
|
bool ret = t->unchoke_peer(*optimistic_unchoke_candidate->second);
|
||||||
|
assert(ret);
|
||||||
optimistic_unchoke_candidate->second->peer_info_struct()->optimistically_unchoked = true;
|
optimistic_unchoke_candidate->second->peer_info_struct()->optimistically_unchoked = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2090,6 +2115,8 @@ namespace detail
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
void session_impl::check_invariant(const char *place)
|
void session_impl::check_invariant(const char *place)
|
||||||
{
|
{
|
||||||
|
assert(m_max_connections > 0);
|
||||||
|
assert(m_max_uploads > 0);
|
||||||
assert(place);
|
assert(place);
|
||||||
int unchokes = 0;
|
int unchokes = 0;
|
||||||
int num_optimistic = 0;
|
int num_optimistic = 0;
|
||||||
|
|
|
@ -200,6 +200,7 @@ namespace libtorrent
|
||||||
, m_settings(s)
|
, m_settings(s)
|
||||||
, m_storage_constructor(sc)
|
, m_storage_constructor(sc)
|
||||||
, m_max_uploads(std::numeric_limits<int>::max())
|
, m_max_uploads(std::numeric_limits<int>::max())
|
||||||
|
, m_num_uploads(0)
|
||||||
, m_max_connections(std::numeric_limits<int>::max())
|
, m_max_connections(std::numeric_limits<int>::max())
|
||||||
{
|
{
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
|
@ -208,7 +209,6 @@ namespace libtorrent
|
||||||
m_policy.reset(new policy(this));
|
m_policy.reset(new policy(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
torrent::torrent(
|
torrent::torrent(
|
||||||
session_impl& ses
|
session_impl& ses
|
||||||
, aux::checker_impl& checker
|
, aux::checker_impl& checker
|
||||||
|
@ -262,6 +262,9 @@ namespace libtorrent
|
||||||
, m_connections_initialized(false)
|
, m_connections_initialized(false)
|
||||||
, m_settings(s)
|
, m_settings(s)
|
||||||
, m_storage_constructor(sc)
|
, m_storage_constructor(sc)
|
||||||
|
, m_max_uploads(std::numeric_limits<int>::max())
|
||||||
|
, m_num_uploads(0)
|
||||||
|
, m_max_connections(std::numeric_limits<int>::max())
|
||||||
{
|
{
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
m_initial_done = 0;
|
m_initial_done = 0;
|
||||||
|
@ -1387,6 +1390,27 @@ namespace libtorrent
|
||||||
return req;
|
return req;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void torrent::choke_peer(peer_connection& c)
|
||||||
|
{
|
||||||
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
|
assert(!c.is_choked());
|
||||||
|
assert(m_num_uploads > 0);
|
||||||
|
c.send_choke();
|
||||||
|
--m_num_uploads;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool torrent::unchoke_peer(peer_connection& c)
|
||||||
|
{
|
||||||
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
|
assert(c.is_choked());
|
||||||
|
if (m_num_uploads >= m_max_uploads) return false;
|
||||||
|
c.send_unchoke();
|
||||||
|
++m_num_uploads;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void torrent::cancel_block(piece_block block)
|
void torrent::cancel_block(piece_block block)
|
||||||
{
|
{
|
||||||
for (peer_iterator i = m_connections.begin()
|
for (peer_iterator i = m_connections.begin()
|
||||||
|
@ -1437,6 +1461,9 @@ namespace libtorrent
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!p->is_choked())
|
||||||
|
--m_num_uploads;
|
||||||
|
|
||||||
m_policy->connection_closed(*p);
|
m_policy->connection_closed(*p);
|
||||||
p->set_peer_info(0);
|
p->set_peer_info(0);
|
||||||
m_connections.erase(i);
|
m_connections.erase(i);
|
||||||
|
@ -2358,6 +2385,7 @@ namespace libtorrent
|
||||||
// size_type download = m_stat.total_payload_download();
|
// size_type download = m_stat.total_payload_download();
|
||||||
// size_type done = boost::get<0>(bytes_done());
|
// size_type done = boost::get<0>(bytes_done());
|
||||||
// assert(download >= done - m_initial_done);
|
// assert(download >= done - m_initial_done);
|
||||||
|
int num_uploads = 0;
|
||||||
std::map<piece_block, int> num_requests;
|
std::map<piece_block, int> num_requests;
|
||||||
for (const_peer_iterator i = begin(); i != end(); ++i)
|
for (const_peer_iterator i = begin(); i != end(); ++i)
|
||||||
{
|
{
|
||||||
|
@ -2368,10 +2396,12 @@ namespace libtorrent
|
||||||
for (std::deque<piece_block>::const_iterator i = p.download_queue().begin()
|
for (std::deque<piece_block>::const_iterator i = p.download_queue().begin()
|
||||||
, end(p.download_queue().end()); i != end; ++i)
|
, end(p.download_queue().end()); i != end; ++i)
|
||||||
++num_requests[*i];
|
++num_requests[*i];
|
||||||
|
if (!p.is_choked()) ++num_uploads;
|
||||||
torrent* associated_torrent = p.associated_torrent().lock().get();
|
torrent* associated_torrent = p.associated_torrent().lock().get();
|
||||||
if (associated_torrent != this)
|
if (associated_torrent != this)
|
||||||
assert(false);
|
assert(false);
|
||||||
}
|
}
|
||||||
|
assert(num_uploads == m_num_uploads);
|
||||||
|
|
||||||
if (has_picker())
|
if (has_picker())
|
||||||
{
|
{
|
||||||
|
@ -2429,14 +2459,14 @@ namespace libtorrent
|
||||||
void torrent::set_max_uploads(int limit)
|
void torrent::set_max_uploads(int limit)
|
||||||
{
|
{
|
||||||
assert(limit >= -1);
|
assert(limit >= -1);
|
||||||
if (limit < 0) limit = std::numeric_limits<int>::max();
|
if (limit <= 0) limit = std::numeric_limits<int>::max();
|
||||||
m_max_uploads = limit;
|
m_max_uploads = limit;
|
||||||
}
|
}
|
||||||
|
|
||||||
void torrent::set_max_connections(int limit)
|
void torrent::set_max_connections(int limit)
|
||||||
{
|
{
|
||||||
assert(limit >= -1);
|
assert(limit >= -1);
|
||||||
if (limit < -1) limit = std::numeric_limits<int>::max();
|
if (limit <= 0) limit = std::numeric_limits<int>::max();
|
||||||
m_max_connections = limit;
|
m_max_connections = limit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2459,7 +2489,7 @@ namespace libtorrent
|
||||||
void torrent::set_upload_limit(int limit)
|
void torrent::set_upload_limit(int limit)
|
||||||
{
|
{
|
||||||
assert(limit >= -1);
|
assert(limit >= -1);
|
||||||
if (limit == -1) limit = std::numeric_limits<int>::max();
|
if (limit <= 0) limit = std::numeric_limits<int>::max();
|
||||||
if (limit < num_peers() * 10) limit = num_peers() * 10;
|
if (limit < num_peers() * 10) limit = num_peers() * 10;
|
||||||
m_bandwidth_limit[peer_connection::upload_channel].throttle(limit);
|
m_bandwidth_limit[peer_connection::upload_channel].throttle(limit);
|
||||||
}
|
}
|
||||||
|
@ -2474,7 +2504,7 @@ namespace libtorrent
|
||||||
void torrent::set_download_limit(int limit)
|
void torrent::set_download_limit(int limit)
|
||||||
{
|
{
|
||||||
assert(limit >= -1);
|
assert(limit >= -1);
|
||||||
if (limit == -1) limit = std::numeric_limits<int>::max();
|
if (limit <= 0) limit = std::numeric_limits<int>::max();
|
||||||
if (limit < num_peers() * 10) limit = num_peers() * 10;
|
if (limit < num_peers() * 10) limit = num_peers() * 10;
|
||||||
m_bandwidth_limit[peer_connection::download_channel].throttle(limit);
|
m_bandwidth_limit[peer_connection::download_channel].throttle(limit);
|
||||||
}
|
}
|
||||||
|
@ -2759,7 +2789,7 @@ namespace libtorrent
|
||||||
= m_trackers[m_last_working_tracker].url;
|
= m_trackers[m_last_working_tracker].url;
|
||||||
}
|
}
|
||||||
|
|
||||||
st.num_uploads = -1;
|
st.num_uploads = m_num_uploads;
|
||||||
st.uploads_limit = m_max_uploads;
|
st.uploads_limit = m_max_uploads;
|
||||||
st.num_connections = int(m_connections.size());
|
st.num_connections = int(m_connections.size());
|
||||||
st.connections_limit = m_max_connections;
|
st.connections_limit = m_max_connections;
|
||||||
|
|
Loading…
Reference in New Issue