diff --git a/src/choker.cpp b/src/choker.cpp index da1e9a8c8..56127f6fb 100644 --- a/src/choker.cpp +++ b/src/choker.cpp @@ -335,7 +335,7 @@ namespace libtorrent // TODO: optimize this using partial_sort or something. We don't need // to sort the entire list - + // TODO: make the comparison function a free function and move it // into this cpp file std::sort(peers.begin(), peers.end() @@ -365,7 +365,7 @@ namespace libtorrent // secondary by total upload. The reason for this is, if all torrents are // being seeded, the download rate will be 0, and the peers we have sent // the least to should be unchoked - + // we use partial sort here, because we only care about the top // upload_slots peers. diff --git a/src/session_impl.cpp b/src/session_impl.cpp index b5c83781f..ffa807dc1 100644 --- a/src/session_impl.cpp +++ b/src/session_impl.cpp @@ -3912,7 +3912,10 @@ retry: if (p->ignore_unchoke_slots() || t == 0 || pi == 0 || pi->web_seed || t->is_paused()) + { + p->reset_choke_counters(); continue; + } if (!p->is_peer_interested() || p->is_disconnecting() @@ -3920,7 +3923,11 @@ retry: { // this peer is not unchokable. So, if it's unchoked // already, make sure to choke it. - if (p->is_choked()) continue; + if (p->is_choked()) + { + p->reset_choke_counters(); + continue; + } if (pi && pi->optimistically_unchoked) { m_stats_counters.inc_stats_counter(counters::num_peers_up_unchoked_optimistic, -1); @@ -3931,6 +3938,7 @@ retry: // immediately instead of waiting for the next tick } t->choke_peer(*p); + p->reset_choke_counters(); continue; } @@ -3958,6 +3966,16 @@ retry: m_stats_counters.set_value(counters::num_unchoke_slots , allowed_upload_slots); +#ifndef TORRENT_DISABLE_LOGGING + session_log("RECALCULATE UNCHOKE SLOTS: [ peers: %d " + "eligible-peers: %d" + " max_upload_rate: %d" + " allowed-slots: %d ]", int(m_connections.size()) + , int(peers.size()) + , max_upload_rate + , allowed_upload_slots); +#endif + int num_opt_unchoke = m_settings.get_int(settings_pack::num_optimistic_unchoke_slots); if (num_opt_unchoke == 0) num_opt_unchoke = (std::max)(1, allowed_upload_slots / 5); @@ -3974,7 +3992,6 @@ retry: TORRENT_ASSERT(!p->ignore_unchoke_slots()); // this will update the m_uploaded_at_last_unchoke - // TODO: this should be called for all peers! p->reset_choke_counters(); torrent* t = p->associated_torrent().lock().get(); diff --git a/test/test_auto_unchoke.cpp b/test/test_auto_unchoke.cpp index 3134b04c7..0077f195f 100644 --- a/test/test_auto_unchoke.cpp +++ b/test/test_auto_unchoke.cpp @@ -60,6 +60,10 @@ void test_swarm() float rate_limit = 50000; settings_pack pack; + // run the choker once per second, to make it more likely to actually trigger + // during the test. + pack.set_int(settings_pack::unchoke_interval, 1); + pack.set_int(settings_pack::alert_mask, alert::all_categories); pack.set_bool(settings_pack::allow_multiple_connections_per_ip, true); pack.set_int(settings_pack::choking_algorithm, settings_pack::rate_based_choker);