From 2623037482e586788ecb3f349b540042b4dc8c42 Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Wed, 28 Jan 2009 06:14:21 +0000 Subject: [PATCH] local peers are excempt from unchoke slots. #469 --- include/libtorrent/peer_connection.hpp | 10 ++++++++++ src/peer_connection.cpp | 8 +++++++- src/policy.cpp | 1 + src/session_impl.cpp | 9 +++++++-- src/torrent.cpp | 6 ++++-- 5 files changed, 29 insertions(+), 5 deletions(-) diff --git a/include/libtorrent/peer_connection.hpp b/include/libtorrent/peer_connection.hpp index b08e459d1..34c09b1a8 100644 --- a/include/libtorrent/peer_connection.hpp +++ b/include/libtorrent/peer_connection.hpp @@ -331,6 +331,11 @@ namespace libtorrent void ignore_bandwidth_limits(bool i) { m_ignore_bandwidth_limits = i; } + bool ignore_unchoke_slots() const + { return m_ignore_unchoke_slots; } + void ignore_unchoke_slots(bool i) + { m_ignore_unchoke_slots = i; } + bool failed() const { return m_failed; } int desired_queue_size() const { return m_desired_queue_size; } @@ -847,6 +852,11 @@ namespace libtorrent // just send and receive as much as possible. bool m_ignore_bandwidth_limits:1; + // set to true if this peer controls its unchoke + // state individually, regardless of the global + // unchoker + bool m_ignore_unchoke_slots:1; + // this is set to true when a have_all // message is received. This information // is used to fill the bitmask in init() diff --git a/src/peer_connection.cpp b/src/peer_connection.cpp index 23bcf6004..5f5b55b7d 100644 --- a/src/peer_connection.cpp +++ b/src/peer_connection.cpp @@ -125,6 +125,7 @@ namespace libtorrent , m_choked(true) , m_failed(false) , m_ignore_bandwidth_limits(false) + , m_ignore_unchoke_slots(false) , m_have_all(false) , m_disconnecting(false) , m_connecting(true) @@ -235,6 +236,7 @@ namespace libtorrent , m_choked(true) , m_failed(false) , m_ignore_bandwidth_limits(false) + , m_ignore_unchoke_slots(false) , m_have_all(false) , m_disconnecting(false) , m_connecting(false) @@ -1132,6 +1134,7 @@ namespace libtorrent #endif m_peer_interested = true; if (is_disconnecting()) return; + if (ignore_unchoke_slots()) write_unchoke(); t->get_policy().interested(*this); } @@ -1162,7 +1165,7 @@ namespace libtorrent boost::shared_ptr t = m_torrent.lock(); TORRENT_ASSERT(t); - if (!is_choked()) + if (!is_choked() && !ignore_unchoke_slots()) { if (m_peer_info && m_peer_info->optimistically_unchoked) { @@ -1174,6 +1177,7 @@ namespace libtorrent m_ses.m_unchoke_time_scaler = 0; } + if (ignore_unchoke_slots()) write_choke(); t->get_policy().not_interested(*this); if (t->super_seeding() && m_superseed_piece != -1) @@ -2994,6 +2998,8 @@ namespace libtorrent m_ignore_bandwidth_limits = m_ses.settings().ignore_limits_on_local_network && on_local_network(); + m_ignore_unchoke_slots = m_ses.settings().ignore_limits_on_local_network + && on_local_network(); m_statistics.second_tick(tick_interval); diff --git a/src/policy.cpp b/src/policy.cpp index 5e352b6ba..68b96f759 100644 --- a/src/policy.cpp +++ b/src/policy.cpp @@ -882,6 +882,7 @@ namespace libtorrent // can't pay for their downloads anyway. if (c.is_choked() && ses.num_uploads() < ses.max_uploads() + && !c.ignore_unchoke_slots() && (m_torrent->ratio() == 0 || c.share_diff() >= -free_upload_amount || m_torrent->is_finished())) diff --git a/src/session_impl.cpp b/src/session_impl.cpp index e13e630e0..797c9f6be 100644 --- a/src/session_impl.cpp +++ b/src/session_impl.cpp @@ -984,7 +984,7 @@ namespace aux { TORRENT_ASSERT(p->is_disconnecting()); - if (!p->is_choked()) --m_num_unchoked; + if (!p->is_choked() && !p->ignore_unchoke_slots()) --m_num_unchoked; // connection_map::iterator i = std::lower_bound(m_connections.begin(), m_connections.end() // , p, bind(&boost::intrusive_ptr::get, _1) < p); // if (i->get() != p) i == m_connections.end(); @@ -1007,6 +1007,7 @@ namespace aux { void session_impl::unchoke_peer(peer_connection& c) { + TORRENT_ASSERT(!c.ignore_unchoke_slots()); torrent* t = c.associated_torrent().lock().get(); TORRENT_ASSERT(t); if (t->unchoke_peer(c)) @@ -1569,6 +1570,7 @@ namespace aux { && p->is_peer_interested() && t->free_upload_slots() && p->is_choked() + && !p->ignore_unchoke_slots() && t->valid_metadata()) { last_unchoke = pi->last_optimistically_unchoked; @@ -1632,10 +1634,11 @@ namespace aux { || !p->is_peer_interested() || p->is_disconnecting() || p->is_connecting() + || p->ignore_unchoke_slots() || (p->share_diff() < -free_upload_amount && !t->is_seed())) { - if (!p->is_choked() && t) + if (!p->is_choked() && t && !p->ignore_unchoke_slots()) { policy::peer* pi = p->peer_info_struct(); if (pi && pi->optimistically_unchoked) @@ -1694,6 +1697,7 @@ namespace aux { { peer_connection* p = *i; TORRENT_ASSERT(p); + if (p->ignore_unchoke_slots()) continue; torrent* t = p->associated_torrent().lock().get(); TORRENT_ASSERT(t); if (unchoke_set_size > 0) @@ -2758,6 +2762,7 @@ namespace aux { peer_connection* p = i->get(); TORRENT_ASSERT(!p->is_disconnecting()); + if (p->ignore_unchoke_slots()) continue; if (!p->is_choked()) ++unchokes; if (p->peer_info_struct() && p->peer_info_struct()->optimistically_unchoked) diff --git a/src/torrent.cpp b/src/torrent.cpp index bade1c155..423f62ec0 100644 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -2445,6 +2445,7 @@ namespace libtorrent INVARIANT_CHECK; TORRENT_ASSERT(!c.is_choked()); + TORRENT_ASSERT(!c.ignore_unchoke_slots()); TORRENT_ASSERT(m_num_uploads > 0); c.send_choke(); --m_num_uploads; @@ -2455,6 +2456,7 @@ namespace libtorrent INVARIANT_CHECK; TORRENT_ASSERT(c.is_choked()); + TORRENT_ASSERT(!c.ignore_unchoke_slots()); if (m_num_uploads >= m_max_uploads) return false; if (!c.send_unchoke()) return false; ++m_num_uploads; @@ -2507,7 +2509,7 @@ namespace libtorrent } } - if (!p->is_choked()) + if (!p->is_choked() && !p->ignore_unchoke_slots()) { --m_num_uploads; m_ses.m_unchoke_time_scaler = 0; @@ -4090,7 +4092,7 @@ namespace libtorrent for (std::deque::const_iterator i = p.download_queue().begin() , end(p.download_queue().end()); i != end; ++i) ++num_requests[i->block]; - if (!p.is_choked()) ++num_uploads; + if (!p.is_choked() && !p.ignore_unchoke_slots()) ++num_uploads; torrent* associated_torrent = p.associated_torrent().lock().get(); if (associated_torrent != this) TORRENT_ASSERT(false);