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)
|
||||
{
|
||||
c.send_unchoke();
|
||||
torrent* t = c.associated_torrent().lock().get();
|
||||
assert(t);
|
||||
t->unchoke_peer(c);
|
||||
++m_num_unchoked;
|
||||
}
|
||||
|
||||
|
|
|
@ -249,6 +249,13 @@ namespace libtorrent
|
|||
void remove_url_seed(std::string const& 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
|
||||
// since incoming connections don't know what torrent
|
||||
// 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
|
||||
int m_max_uploads;
|
||||
|
||||
// the number of unchoked peers in this torrent
|
||||
int m_num_uploads;
|
||||
|
||||
// the maximum number of connections for this torrent
|
||||
int m_max_connections;
|
||||
|
||||
|
|
|
@ -1046,14 +1046,15 @@ namespace detail
|
|||
peer_connection* p = i->second.get();
|
||||
torrent* t = p->associated_torrent().lock().get();
|
||||
if (!p->peer_info_struct()
|
||||
|| t == 0
|
||||
|| !p->is_peer_interested()
|
||||
|| p->is_disconnecting()
|
||||
|| p->is_connecting()
|
||||
|| (p->share_diff() < -free_upload_amount
|
||||
&& t && !t->is_seed()))
|
||||
&& !t->is_seed()))
|
||||
{
|
||||
if (!i->second->is_choked())
|
||||
i->second->send_choke();
|
||||
if (!i->second->is_choked() && t)
|
||||
t->choke_peer(*i->second);
|
||||
continue;
|
||||
}
|
||||
peers.push_back(i->second.get());
|
||||
|
@ -1082,9 +1083,24 @@ namespace detail
|
|||
{
|
||||
peer_connection* p = *i;
|
||||
assert(p);
|
||||
torrent* t = p->associated_torrent().lock().get();
|
||||
assert(t);
|
||||
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());
|
||||
if (p->peer_info_struct()->optimistically_unchoked)
|
||||
{
|
||||
|
@ -1092,13 +1108,11 @@ namespace detail
|
|||
m_optimistic_unchoke_time_scaler = 0;
|
||||
p->peer_info_struct()->optimistically_unchoked = false;
|
||||
}
|
||||
--unchoke_set_size;
|
||||
++m_num_unchoked;
|
||||
}
|
||||
else
|
||||
{
|
||||
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);
|
||||
policy::peer* pi = p->peer_info_struct();
|
||||
if (!pi) continue;
|
||||
torrent* t = p->associated_torrent().lock().get();
|
||||
if (!t) continue;
|
||||
|
||||
if (pi->optimistically_unchoked)
|
||||
{
|
||||
assert(current_optimistic_unchoke == m_connections.end());
|
||||
current_optimistic_unchoke = i;
|
||||
}
|
||||
|
||||
if (pi->last_optimistically_unchoked < last_unchoke
|
||||
&& !p->is_connecting()
|
||||
&& !p->is_disconnecting()
|
||||
&& p->is_peer_interested())
|
||||
&& p->is_peer_interested()
|
||||
&& t->free_upload_slots()
|
||||
&& p->is_choked())
|
||||
{
|
||||
last_unchoke = pi->last_optimistically_unchoked;
|
||||
optimistic_unchoke_candidate = i;
|
||||
|
@ -1141,11 +1161,16 @@ namespace detail
|
|||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -2090,6 +2115,8 @@ namespace detail
|
|||
#ifndef NDEBUG
|
||||
void session_impl::check_invariant(const char *place)
|
||||
{
|
||||
assert(m_max_connections > 0);
|
||||
assert(m_max_uploads > 0);
|
||||
assert(place);
|
||||
int unchokes = 0;
|
||||
int num_optimistic = 0;
|
||||
|
|
|
@ -200,6 +200,7 @@ namespace libtorrent
|
|||
, m_settings(s)
|
||||
, 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
|
||||
|
@ -208,7 +209,6 @@ namespace libtorrent
|
|||
m_policy.reset(new policy(this));
|
||||
}
|
||||
|
||||
|
||||
torrent::torrent(
|
||||
session_impl& ses
|
||||
, aux::checker_impl& checker
|
||||
|
@ -262,6 +262,9 @@ namespace libtorrent
|
|||
, m_connections_initialized(false)
|
||||
, m_settings(s)
|
||||
, 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
|
||||
m_initial_done = 0;
|
||||
|
@ -1387,6 +1390,27 @@ namespace libtorrent
|
|||
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)
|
||||
{
|
||||
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);
|
||||
p->set_peer_info(0);
|
||||
m_connections.erase(i);
|
||||
|
@ -2358,6 +2385,7 @@ namespace libtorrent
|
|||
// size_type download = m_stat.total_payload_download();
|
||||
// size_type done = boost::get<0>(bytes_done());
|
||||
// assert(download >= done - m_initial_done);
|
||||
int num_uploads = 0;
|
||||
std::map<piece_block, int> num_requests;
|
||||
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()
|
||||
, end(p.download_queue().end()); i != end; ++i)
|
||||
++num_requests[*i];
|
||||
if (!p.is_choked()) ++num_uploads;
|
||||
torrent* associated_torrent = p.associated_torrent().lock().get();
|
||||
if (associated_torrent != this)
|
||||
assert(false);
|
||||
}
|
||||
assert(num_uploads == m_num_uploads);
|
||||
|
||||
if (has_picker())
|
||||
{
|
||||
|
@ -2429,14 +2459,14 @@ namespace libtorrent
|
|||
void torrent::set_max_uploads(int limit)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
void torrent::set_max_connections(int limit)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -2459,7 +2489,7 @@ namespace libtorrent
|
|||
void torrent::set_upload_limit(int limit)
|
||||
{
|
||||
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;
|
||||
m_bandwidth_limit[peer_connection::upload_channel].throttle(limit);
|
||||
}
|
||||
|
@ -2474,7 +2504,7 @@ namespace libtorrent
|
|||
void torrent::set_download_limit(int limit)
|
||||
{
|
||||
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;
|
||||
m_bandwidth_limit[peer_connection::download_channel].throttle(limit);
|
||||
}
|
||||
|
@ -2759,7 +2789,7 @@ namespace libtorrent
|
|||
= m_trackers[m_last_working_tracker].url;
|
||||
}
|
||||
|
||||
st.num_uploads = -1;
|
||||
st.num_uploads = m_num_uploads;
|
||||
st.uploads_limit = m_max_uploads;
|
||||
st.num_connections = int(m_connections.size());
|
||||
st.connections_limit = m_max_connections;
|
||||
|
|
Loading…
Reference in New Issue