fixed choke-unchoke problem in policy

This commit is contained in:
Arvid Norberg 2005-08-18 20:38:03 +00:00
parent df4466cb86
commit 356df1bd32
4 changed files with 91 additions and 44 deletions

View File

@ -28,7 +28,7 @@ project torrent
<variant>release:<define>NDEBUG
<define>BOOST_ALL_NO_LIB
<define>_FILE_OFFSET_BITS=64
<library>/boost/thread//boost_thread/<link>shared
<library>/boost/thread//boost_thread/<link>static
<library>/boost/filesystem//boost_filesystem/<link>static
<library>/boost/date_time//boost_date_time/<link>static
<link>static

View File

@ -273,12 +273,13 @@ namespace libtorrent
resource_request m_ul_bandwidth_quota;
resource_request m_dl_bandwidth_quota;
private:
#ifndef NDEBUG
void check_invariant() const;
boost::posix_time::ptime m_last_choke;
#endif
private:
bool dispatch_message(int received);
// if we don't have all metadata

View File

@ -50,6 +50,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/piece_picker.hpp"
#include "libtorrent/socket.hpp"
#include "libtorrent/size_type.hpp"
#include "libtorrent/invariant_check.hpp"
namespace libtorrent
{
@ -170,12 +171,14 @@ namespace libtorrent
private:
bool unchoke_one_peer();
void choke_one_peer();
peer* find_choke_candidate();
peer* find_unchoke_candidate();
// the seed prefix means that the
// function is used while seeding.
bool seed_unchoke_one_peer();
void seed_choke_one_peer();
peer* find_seed_choke_candidate();
peer* find_seed_unchoke_candidate();

View File

@ -426,6 +426,10 @@ namespace libtorrent
&& m_torrent->ratio() != 0) continue;
if (c->statistics().download_rate() < max_down_speed) continue;
// if (i->last_optimistically_unchoked > min_time) continue;
#ifndef NDEBUG
using namespace boost::posix_time;
assert(second_clock::universal_time() - c->m_last_choke > seconds(9));
#endif
min_time = i->last_optimistically_unchoked;
max_down_speed = c->statistics().download_rate();
@ -443,8 +447,7 @@ namespace libtorrent
= second_clock::universal_time();
for (std::vector<peer>::iterator i = m_peers.begin();
i != m_peers.end();
++i)
i != m_peers.end(); ++i)
{
peer_connection* c = i->connection;
if(c == 0)
@ -508,6 +511,7 @@ namespace libtorrent
{
INVARIANT_CHECK;
assert(m_num_unchoked > 0);
// first choice candidate.
// it is a candidate we owe nothing to and which has been unchoked
// the longest.
@ -585,6 +589,8 @@ namespace libtorrent
bool policy::seed_unchoke_one_peer()
{
INVARIANT_CHECK;
peer* p = find_seed_unchoke_candidate();
if (p != 0)
{
@ -597,6 +603,19 @@ namespace libtorrent
return p != 0;
}
void policy::seed_choke_one_peer()
{
INVARIANT_CHECK;
peer* p = find_seed_choke_candidate();
if (p != 0)
{
assert(!p->connection->is_choked());
p->connection->send_choke();
--m_num_unchoked;
}
}
void policy::pulse()
{
INVARIANT_CHECK;
@ -705,26 +724,35 @@ namespace libtorrent
// ------------------------
if (m_torrent->is_seed())
{
if (num_connected_peers > m_torrent->m_uploads_quota.given)
if (m_num_unchoked > m_torrent->m_uploads_quota.given)
{
// this means there are some peers that
// are choked. To have the choked peers
// rotate, unchoke one peer here
// and let the next condiional block
// make sure another peer is choked.
do
{
peer* p = find_seed_choke_candidate();
--m_num_unchoked;
assert(p != 0);
if (p == 0) break;
assert(!p->connection->is_choked());
p->connection->send_choke();
} while (m_num_unchoked > m_torrent->m_uploads_quota.given);
}
else
{
// optimistic unchoke. trade the 'worst'
// unchoked peer with one of the choked
// TODO: This rotation should happen
// far less frequent than this!
seed_unchoke_one_peer();
}
while (m_num_unchoked > m_torrent->m_uploads_quota.given)
{
peer* p = find_seed_choke_candidate();
assert(p != 0);
assert(!p->connection->is_choked());
p->connection->send_choke();
--m_num_unchoked;
assert(m_num_unchoked <= m_torrent->num_peers());
peer* p = find_seed_unchoke_candidate();
if (p)
{
assert(p->connection->is_choked());
seed_choke_one_peer();
p->connection->send_unchoke();
++m_num_unchoked;
}
}
// make sure we have enough
@ -770,26 +798,33 @@ namespace libtorrent
// make sure we don't have too many
// unchoked peers
while (m_num_unchoked > m_torrent->m_uploads_quota.given)
if (m_num_unchoked > m_torrent->m_uploads_quota.given)
{
peer* p = find_choke_candidate();
if (!p) break;
assert(p);
assert(!p->connection->is_choked());
p->connection->send_choke();
--m_num_unchoked;
do
{
peer* p = find_choke_candidate();
if (!p) break;
assert(p);
assert(!p->connection->is_choked());
p->connection->send_choke();
--m_num_unchoked;
} while (m_num_unchoked > m_torrent->m_uploads_quota.given);
}
// optimistic unchoke. trade the 'worst'
// unchoked peer with one of the choked
assert(m_num_unchoked <= m_torrent->num_peers());
peer* p = find_choke_candidate();
if (p)
else
{
assert(!p->connection->is_choked());
p->connection->send_choke();
--m_num_unchoked;
unchoke_one_peer();
// optimistic unchoke. trade the 'worst'
// unchoked peer with one of the choked
// TODO: This rotation should happen
// far less frequent than this!
assert(m_num_unchoked <= m_torrent->num_peers());
peer* p = find_unchoke_candidate();
if (p)
{
assert(p->connection->is_choked());
choke_one_peer();
p->connection->send_unchoke();
++m_num_unchoked;
}
}
}
@ -958,8 +993,7 @@ namespace libtorrent
{
// have all peers update their interested-flag
for (std::vector<peer>::iterator i = m_peers.begin();
i != m_peers.end();
++i)
i != m_peers.end(); ++i)
{
if (i->connection == 0) continue;
// if we're not interested, we will not become interested
@ -1067,6 +1101,17 @@ namespace libtorrent
return true;
}
void policy::choke_one_peer()
{
peer* p = find_choke_candidate();
if (p == 0) return;
assert(p->connection);
assert(!p->connection->is_disconnecting());
assert(!p->connection->is_choked());
p->connection->send_choke();
--m_num_unchoked;
}
bool policy::connect_one_peer()
{
if(m_torrent->num_peers() >= m_torrent->m_connections_quota.given)
@ -1113,8 +1158,6 @@ namespace libtorrent
// this is called whenever a peer connection is closed
void policy::connection_closed(const peer_connection& c)
{
INVARIANT_CHECK;
bool unchoked = false;
std::vector<peer>::iterator i = std::find_if(
@ -1181,7 +1224,6 @@ namespace libtorrent
void policy::check_invariant() const
{
if (m_torrent->is_aborted()) return;
// assert(m_torrent->m_uploads_quota.given >= 2);
int actual_unchoked = 0;
for (std::vector<peer>::const_iterator i = m_peers.begin();
i != m_peers.end(); ++i)
@ -1234,3 +1276,4 @@ namespace libtorrent
}
}
}