diff --git a/docs/manual.rst b/docs/manual.rst index a5e4209bb..717a174eb 100644 --- a/docs/manual.rst +++ b/docs/manual.rst @@ -2810,6 +2810,8 @@ that will be sent to the tracker. The user-agent is a good way to identify your int active_downloads; int active_seeds; + int active_limit; + bool dont_count_slow_torrents; int auto_manage_interval; float share_ratio_limit; float seed_time_ratio_limit; @@ -3036,6 +3038,14 @@ torrents active. Torrents that are not auto managed are also counted against the limits. If there are non-auto managed torrents that use up all the slots, no auto managed torrent will be activated. +if ``dont_count_slow_torrents`` is true, torrents without any payload transfers are +not subject to the ``active_seeds`` and ``active_downloads`` limits. This is intended +to make it more likely to utilize all available bandwidth, and avoid having torrents +that don't transfer anything block the active slots. + +``active_limit`` is a hard limit on the number of active seeds. This applies even to +slow torrents. + ``auto_manage_interval`` is the number of seconds between the torrent queue is updated, and rotated. diff --git a/include/libtorrent/session_settings.hpp b/include/libtorrent/session_settings.hpp index c54e8a386..8306fc101 100644 --- a/include/libtorrent/session_settings.hpp +++ b/include/libtorrent/session_settings.hpp @@ -126,7 +126,8 @@ namespace libtorrent , peer_tos(0) , active_downloads(8) , active_seeds(5) - , dont_count_inactive_torrents(true) + , active_limit(15) + , dont_count_slow_torrents(true) , auto_manage_interval(30) , share_ratio_limit(2.f) , seed_time_ratio_limit(7.f) @@ -363,11 +364,12 @@ namespace libtorrent // some slots free up. int active_downloads; int active_seeds; + int active_limit; // if this is true, torrents that don't have any significant // transfers are not counted as active when determining which // auto managed torrents to pause and resume - bool dont_count_inactive_torrents; + bool dont_count_slow_torrents; // the number of seconds in between recalculating which // torrents to activate and which ones to queue diff --git a/src/session_impl.cpp b/src/session_impl.cpp index b3612ada7..09da8857c 100755 --- a/src/session_impl.cpp +++ b/src/session_impl.cpp @@ -1295,6 +1295,16 @@ namespace aux { } } + namespace + { + bool is_active(torrent* t, session_settings const& s) + { + return !(s.dont_count_slow_torrents + && t->statistics().upload_payload_rate() == 0.f + && t->statistics().download_payload_rate() == 0.f); + } + } + void session_impl::recalculate_auto_managed_torrents() { // these vectors are filled with auto managed torrents @@ -1307,6 +1317,7 @@ namespace aux { // of each kind we're allowed to have active int num_downloaders = settings().active_downloads; int num_seeds = settings().active_seeds; + int hard_limit = settings().active_limit; if (num_downloaders == -1) num_downloaders = (std::numeric_limits::max)(); @@ -1329,11 +1340,15 @@ namespace aux { } else if (!t->is_paused()) { - // this is not an auto managed torrent, - // if it's running, decrease the respective - // counters. - --num_downloaders; - --num_seeds; + --hard_limit; + if (is_active(t, settings())) + { + // this is not an auto managed torrent, + // if it's running and active, decrease the + // counters. + --num_downloaders; + --num_seeds; + } } } @@ -1357,14 +1372,15 @@ namespace aux { , end(downloaders.end()); i != end; ++i) { torrent* t = *i; - if (!t->is_paused() - && settings().dont_count_inactive_torrents - && t->statistics().upload_payload_rate() == 0.f - && t->statistics().download_payload_rate() == 0.f) - continue; - - if (num_downloaders > 0) + if (!t->is_paused() && !is_active(t, settings()) && hard_limit > 0) { + --hard_limit; + continue; + } + + if (num_downloaders > 0 && hard_limit > 0) + { + --hard_limit; if (t->state() != torrent_status::queued_for_checking && t->state() != torrent_status::checking_files) { @@ -1383,14 +1399,15 @@ namespace aux { , end(seeds.end()); i != end; ++i) { torrent* t = *i; - if (!t->is_paused() - && settings().dont_count_inactive_torrents - && t->statistics().upload_payload_rate() == 0.f - && t->statistics().download_payload_rate() == 0.f) - continue; - - if (num_seeds > 0) + if (!t->is_paused() && !is_active(t, settings()) && hard_limit > 0) { + --hard_limit; + continue; + } + + if (num_seeds > 0 && hard_limit > 0) + { + --hard_limit; --num_downloaders; --num_seeds; if (t->is_paused()) t->resume();