fixed per torrent unchoke limit

This commit is contained in:
Arvid Norberg 2007-08-17 07:37:08 +00:00
parent 834873a15e
commit 3d3df51d45
4 changed files with 86 additions and 17 deletions

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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;