From ff3db926fb88f9386a971c58c1db4d28dff6f064 Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Wed, 6 May 2009 07:06:26 +0000 Subject: [PATCH] allocates 10 disk buffers at a time instead of 32. Fixed bug where connection candidates would be too high --- ChangeLog | 2 ++ include/libtorrent/policy.hpp | 10 ++++++++++ src/disk_io_thread.cpp | 2 +- src/policy.cpp | 34 ++++++++++++++++++--------------- src/torrent.cpp | 4 +++- test/test_bandwidth_limiter.cpp | 1 + 6 files changed, 36 insertions(+), 17 deletions(-) diff --git a/ChangeLog b/ChangeLog index 912450918..fbf78cc32 100644 --- a/ChangeLog +++ b/ChangeLog @@ -37,6 +37,8 @@ release 0.14.4 + * connect candidate calculation fix + * tightened up disk cache memory usage * fixed magnet link parser to accept hex-encoded info-hashes release 0.14.3 diff --git a/include/libtorrent/policy.hpp b/include/libtorrent/policy.hpp index 1f5b9edaf..0ba583f80 100644 --- a/include/libtorrent/policy.hpp +++ b/include/libtorrent/policy.hpp @@ -343,6 +343,16 @@ namespace libtorrent // the number of seeds in the peer list int m_num_seeds; + + // this was the state of the torrent the + // last time we recalculated the number of + // connect candidates. Since seeds (or upload + // only) peers are not connect candidates + // when we're finished, the set depends on + // this state. Every time m_torrent->is_finished() + // is different from this state, we need to + // recalculate the connect candidates. + bool m_finished; }; } diff --git a/src/disk_io_thread.cpp b/src/disk_io_thread.cpp index 07e593f6c..fb81da162 100644 --- a/src/disk_io_thread.cpp +++ b/src/disk_io_thread.cpp @@ -52,7 +52,7 @@ namespace libtorrent : m_block_size(block_size) , m_in_use(0) #ifndef TORRENT_DISABLE_POOL_ALLOCATOR - , m_pool(block_size) + , m_pool(block_size, 10) #endif { #if defined TORRENT_DISK_STATS || defined TORRENT_STATS diff --git a/src/policy.cpp b/src/policy.cpp index 7c20ad002..86e096694 100644 --- a/src/policy.cpp +++ b/src/policy.cpp @@ -335,6 +335,7 @@ namespace libtorrent , m_available_free_upload(0) , m_num_connect_candidates(0) , m_num_seeds(0) + , m_finished(false) { TORRENT_ASSERT(t); } // disconnects and removes all peers that are now filtered @@ -380,7 +381,7 @@ namespace libtorrent if (m_torrent->has_picker()) m_torrent->picker().clear_peer((void*)&(*i)); if (i->seed) --m_num_seeds; - if (is_connect_candidate(*i, m_torrent->is_finished())) + if (is_connect_candidate(*i, m_finished)) --m_num_connect_candidates; if (m_round_robin == i) ++m_round_robin; @@ -409,11 +410,10 @@ namespace libtorrent iterator candidate = m_peers.end(); int min_reconnect_time = m_torrent->settings().min_reconnect_time; - bool finished = m_torrent->is_finished(); address external_ip = m_torrent->session().external_address(); // don't bias any particular peers when seeding - if (finished || external_ip == address()) + if (m_finished || external_ip == address()) { // set external_ip to a random value, to // radomize which peers we prefer @@ -460,7 +460,7 @@ namespace libtorrent if (pe.connection == 0 && pe.last_connected != 0 && (!pe.banned || session_time - pe.last_connected > 2 * 60 * 60) - && !is_connect_candidate(pe, finished) + && !is_connect_candidate(pe, m_finished) && m_peers.size() >= m_torrent->settings().max_peerlist_size * 0.9) { erase_peer(m_round_robin++); @@ -469,7 +469,7 @@ namespace libtorrent ++m_round_robin; - if (!is_connect_candidate(pe, finished)) continue; + if (!is_connect_candidate(pe, m_finished)) continue; if (candidate != m_peers.end() && !compare_peer(*candidate, pe, external_ip)) continue; @@ -711,11 +711,11 @@ namespace libtorrent { TORRENT_ASSERT(m_peers.count(p->address()) == 1); } - bool was_conn_cand = is_connect_candidate(*p, m_torrent->is_finished()); + bool was_conn_cand = is_connect_candidate(*p, m_finished); p->port = port; p->source |= src; - if (was_conn_cand != is_connect_candidate(*p, m_torrent->is_finished())) + if (was_conn_cand != is_connect_candidate(*p, m_finished)) { m_num_connect_candidates += was_conn_cand ? -1 : 1; if (m_num_connect_candidates < 0) m_num_connect_candidates = 0; @@ -802,14 +802,14 @@ namespace libtorrent #endif i->inet_as = ses.lookup_as(as); #endif - if (is_connect_candidate(*i, m_torrent->is_finished())) + if (is_connect_candidate(*i, m_finished)) ++m_num_connect_candidates; } else { i = (peer*)&(*iter); - bool was_conn_cand = is_connect_candidate(*i, m_torrent->is_finished()); + bool was_conn_cand = is_connect_candidate(*i, m_finished); i->connectable = true; @@ -852,7 +852,7 @@ namespace libtorrent } #endif - if (was_conn_cand != is_connect_candidate(*i, m_torrent->is_finished())) + if (was_conn_cand != is_connect_candidate(*i, m_finished)) { m_num_connect_candidates += was_conn_cand ? -1 : 1; if (m_num_connect_candidates < 0) m_num_connect_candidates = 0; @@ -994,7 +994,8 @@ namespace libtorrent TORRENT_ASSERT(!p.connection); TORRENT_ASSERT(p.connectable); - TORRENT_ASSERT(is_connect_candidate(p, m_torrent->is_finished())); + TORRENT_ASSERT(m_finished == m_torrent->is_finished()); + TORRENT_ASSERT(is_connect_candidate(p, m_finished)); if (!m_torrent->connect_to_peer(&p)) { // failcount is a 5 bit value @@ -1002,7 +1003,7 @@ namespace libtorrent return false; } TORRENT_ASSERT(p.connection); - TORRENT_ASSERT(!is_connect_candidate(p, m_torrent->is_finished())); + TORRENT_ASSERT(!is_connect_candidate(p, m_finished)); --m_num_connect_candidates; return true; } @@ -1040,7 +1041,7 @@ namespace libtorrent if (p->failcount < 31) ++p->failcount; } - if (is_connect_candidate(*p, m_torrent->is_finished())) + if (is_connect_candidate(*p, m_finished)) ++m_num_connect_candidates; // if the share ratio is 0 (infinite), the @@ -1075,10 +1076,13 @@ namespace libtorrent { m_num_connect_candidates = 0; const bool is_finished = m_torrent->is_finished(); + if (is_finished == m_finished) return; + + m_finished = is_finished; for (const_iterator i = m_peers.begin(); i != m_peers.end(); ++i) { - m_num_connect_candidates += is_connect_candidate(*i, is_finished); + m_num_connect_candidates += is_connect_candidate(*i, m_finished); } } @@ -1305,7 +1309,7 @@ namespace libtorrent #ifndef TORRENT_DISABLE_GEO_IP // don't bias fast peers when seeding - if (!m_torrent->is_finished() && m_torrent->session().has_asnum_db()) + if (!m_finished && m_torrent->session().has_asnum_db()) { int lhs_as = lhs.inet_as ? lhs.inet_as->second : 0; int rhs_as = rhs.inet_as ? rhs.inet_as->second : 0; diff --git a/src/torrent.cpp b/src/torrent.cpp index c0fc823ac..348710a80 100644 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -2337,7 +2337,6 @@ namespace libtorrent // if we used to be finished, but we aren't anymore // we may need to connect to peers again resume_download(); - m_policy.recalculate_connect_candidates(); } } @@ -3873,6 +3872,8 @@ namespace libtorrent std::for_each(seeds.begin(), seeds.end() , bind(&peer_connection::disconnect, _1, "torrent finished, disconnecting seed", 0)); + m_policy.recalculate_connect_candidates(); + TORRENT_ASSERT(m_storage); // we need to keep the object alive during this operation m_storage->async_release_files( @@ -3888,6 +3889,7 @@ namespace libtorrent TORRENT_ASSERT(!is_finished()); set_state(torrent_status::downloading); set_queue_position((std::numeric_limits::max)()); + m_policy.recalculate_connect_candidates(); } // called when torrent is complete (all pieces downloaded) diff --git a/test/test_bandwidth_limiter.cpp b/test/test_bandwidth_limiter.cpp index 2202c99a1..88637cf39 100644 --- a/test/test_bandwidth_limiter.cpp +++ b/test/test_bandwidth_limiter.cpp @@ -41,6 +41,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/intrusive_ptr_base.hpp" #include +#include struct torrent; struct peer_connection;