From 786d4e5f2538a4c568852719f21d1a2a8c20d43b Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Wed, 1 Aug 2007 05:22:34 +0000 Subject: [PATCH] added a limit on how many bytes each connection can have pending in the disk write queue --- include/libtorrent/peer_connection.hpp | 8 ++++---- include/libtorrent/session_settings.hpp | 9 +++++++++ src/peer_connection.cpp | 14 +++++++++++++- 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/include/libtorrent/peer_connection.hpp b/include/libtorrent/peer_connection.hpp index d32d250fc..caac2f63c 100755 --- a/include/libtorrent/peer_connection.hpp +++ b/include/libtorrent/peer_connection.hpp @@ -74,10 +74,6 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/socket_type.hpp" #include "libtorrent/intrusive_ptr_base.hpp" -// TODO: each time a block is 'taken over' -// from another peer. That peer must be given -// a chance to become not-interested. - namespace libtorrent { class torrent; @@ -701,6 +697,10 @@ namespace libtorrent // a timestamp when the remote download rate // was last updated ptime m_remote_dl_update; + + // the number of bytes send to the disk-io + // thread that hasn't yet been completely written. + int m_outstanding_writing_bytes; #ifndef NDEBUG public: diff --git a/include/libtorrent/session_settings.hpp b/include/libtorrent/session_settings.hpp index 783492227..1aef3f199 100644 --- a/include/libtorrent/session_settings.hpp +++ b/include/libtorrent/session_settings.hpp @@ -108,6 +108,7 @@ namespace libtorrent , unchoke_interval(20) , num_want(200) , initial_picker_threshold(4) + , max_outstanding_disk_bytes_per_connection(128 * 1024) #ifndef TORRENT_DISABLE_DHT , use_dht_as_fallback(true) #endif @@ -251,6 +252,14 @@ namespace libtorrent // random pieces instead of rarest first. int initial_picker_threshold; + // the maximum number of bytes a connection may have + // pending in the disk write queue before its download + // rate is being throttled. This prevents fast downloads + // to slow medias to allocate more and more memory + // indefinitely. This should be set to at least 32 kB + // to not completely disrupt normal downloads. + int max_outstanding_disk_bytes_per_connection; + #ifndef TORRENT_DISABLE_DHT // while this is true, the dht will note be used unless the // tracker is online diff --git a/src/peer_connection.cpp b/src/peer_connection.cpp index 7dbef4381..3ff3f59f5 100755 --- a/src/peer_connection.cpp +++ b/src/peer_connection.cpp @@ -116,6 +116,7 @@ namespace libtorrent , m_remote_bytes_dled(0) , m_remote_dl_rate(0) , m_remote_dl_update(time_now()) + , m_outstanding_writing_bytes(0) #ifndef NDEBUG , m_in_constructor(true) #endif @@ -189,6 +190,7 @@ namespace libtorrent , m_remote_bytes_dled(0) , m_remote_dl_rate(0) , m_remote_dl_update(time_now()) + , m_outstanding_writing_bytes(0) #ifndef NDEBUG , m_in_constructor(true) #endif @@ -1150,6 +1152,7 @@ namespace libtorrent fs.async_write(p, data, bind(&peer_connection::on_disk_write_complete , self(), _1, _2, p, t)); + m_outstanding_writing_bytes += p.length; picker.mark_as_writing(block_finished, peer_info_struct()); } @@ -1158,6 +1161,13 @@ namespace libtorrent { session_impl::mutex_t::scoped_lock l(m_ses.m_mutex); + m_outstanding_writing_bytes -= p.length; + assert(m_outstanding_writing_bytes >= 0); + + // in case the outstanding bytes just dropped down + // to allow to receive more data + setup_receive(); + if (ret == -1 || !t) { if (!t) @@ -2324,7 +2334,9 @@ namespace libtorrent return (m_bandwidth_limit[download_channel].quota_left() > 0 || m_ignore_bandwidth_limits) - && !m_connecting; + && !m_connecting + && m_outstanding_writing_bytes < + m_ses.settings().max_outstanding_disk_bytes_per_connection; } void peer_connection::connect(int ticket)