diff --git a/include/libtorrent/kademlia/traversal_algorithm.hpp b/include/libtorrent/kademlia/traversal_algorithm.hpp index d04828619..a541083e0 100644 --- a/include/libtorrent/kademlia/traversal_algorithm.hpp +++ b/include/libtorrent/kademlia/traversal_algorithm.hpp @@ -117,10 +117,10 @@ protected: std::vector m_results; node_id const m_target; boost::uint16_t m_ref_count; - boost::uint16_t m_invoke_count; - boost::uint16_t m_branch_factor; - boost::uint16_t m_responses; - boost::uint16_t m_timeouts; + boost::int16_t m_invoke_count; + boost::int16_t m_branch_factor; + boost::int16_t m_responses; + boost::int16_t m_timeouts; // the IP addresses of the nodes in m_results std::set m_peer4_prefixes; diff --git a/src/kademlia/get_item.cpp b/src/kademlia/get_item.cpp index 61c9bd3c4..aef3a6df1 100644 --- a/src/kademlia/get_item.cpp +++ b/src/kademlia/get_item.cpp @@ -141,11 +141,7 @@ observer_ptr get_item::new_observer(void* ptr bool get_item::invoke(observer_ptr o) { - if (m_done) - { - m_invoke_count = -1; - return false; - } + if (m_done) return false; entry e; e["y"] = "q"; diff --git a/src/kademlia/get_peers.cpp b/src/kademlia/get_peers.cpp index 05a72375d..6645f197f 100644 --- a/src/kademlia/get_peers.cpp +++ b/src/kademlia/get_peers.cpp @@ -134,11 +134,7 @@ char const* get_peers::name() const { return "get_peers"; } bool get_peers::invoke(observer_ptr o) { - if (m_done) - { - m_invoke_count = -1; - return false; - } + if (m_done) return false; entry e; e["y"] = "q"; diff --git a/src/kademlia/put_data.cpp b/src/kademlia/put_data.cpp index 393e3406a..85e321246 100644 --- a/src/kademlia/put_data.cpp +++ b/src/kademlia/put_data.cpp @@ -88,11 +88,7 @@ void put_data::done() bool put_data::invoke(observer_ptr o) { - if (m_done) - { - m_invoke_count = -1; - return false; - } + if (m_done) return false; // TODO: what if o is not an isntance of put_data_observer? This need to be // redesigned for better type saftey. diff --git a/src/kademlia/traversal_algorithm.cpp b/src/kademlia/traversal_algorithm.cpp index d7d380adb..6188966b8 100644 --- a/src/kademlia/traversal_algorithm.cpp +++ b/src/kademlia/traversal_algorithm.cpp @@ -319,6 +319,8 @@ void traversal_algorithm::failed(observer_ptr o, int flags) if (m_results.empty()) return; + bool decrement_branch_factor = false; + TORRENT_ASSERT(o->flags & observer::flag_queried); if (flags & short_timeout) { @@ -329,7 +331,10 @@ void traversal_algorithm::failed(observer_ptr o, int flags) // around for some more, but open up the slot // by increasing the branch factor if ((o->flags & observer::flag_short_timeout) == 0) + { + TORRENT_ASSERT(m_branch_factor < (std::numeric_limits::max)()); ++m_branch_factor; + } o->flags |= observer::flag_short_timeout; #ifndef TORRENT_DISABLE_LOGGING if (get_node().observer()) @@ -350,8 +355,7 @@ void traversal_algorithm::failed(observer_ptr o, int flags) o->flags |= observer::flag_failed; // if this flag is set, it means we increased the // branch factor for it, and we should restore it - if (o->flags & observer::flag_short_timeout) - --m_branch_factor; + decrement_branch_factor = (o->flags & observer::flag_short_timeout) != 0; #ifndef TORRENT_DISABLE_LOGGING if (get_node().observer()) @@ -372,12 +376,18 @@ void traversal_algorithm::failed(observer_ptr o, int flags) --m_invoke_count; } - if (flags & prevent_request) + // this is another reason to decrement the branch factor, to prevent another + // request from filling this slot. Only ever decrement once per response though + decrement_branch_factor |= (flags & prevent_request); + + if (decrement_branch_factor) { + TORRENT_ASSERT(m_branch_factor > 0); --m_branch_factor; if (m_branch_factor <= 0) m_branch_factor = 1; } - bool is_done = add_requests(); + + bool const is_done = add_requests(); if (is_done) done(); } @@ -499,7 +509,7 @@ bool traversal_algorithm::add_requests() o->flags |= observer::flag_queried; if (invoke(*i)) { - TORRENT_ASSERT(m_invoke_count < (std::numeric_limits::max)()); + TORRENT_ASSERT(m_invoke_count < (std::numeric_limits::max)()); ++m_invoke_count; ++outstanding; }