added a limit on how many bytes each connection can have pending in the disk write queue

This commit is contained in:
Arvid Norberg 2007-08-01 05:22:34 +00:00
parent 054fa03d9d
commit 786d4e5f25
3 changed files with 26 additions and 5 deletions

View File

@ -74,10 +74,6 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/socket_type.hpp" #include "libtorrent/socket_type.hpp"
#include "libtorrent/intrusive_ptr_base.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 namespace libtorrent
{ {
class torrent; class torrent;
@ -702,6 +698,10 @@ namespace libtorrent
// was last updated // was last updated
ptime m_remote_dl_update; 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 #ifndef NDEBUG
public: public:
bool m_in_constructor; bool m_in_constructor;

View File

@ -108,6 +108,7 @@ namespace libtorrent
, unchoke_interval(20) , unchoke_interval(20)
, num_want(200) , num_want(200)
, initial_picker_threshold(4) , initial_picker_threshold(4)
, max_outstanding_disk_bytes_per_connection(128 * 1024)
#ifndef TORRENT_DISABLE_DHT #ifndef TORRENT_DISABLE_DHT
, use_dht_as_fallback(true) , use_dht_as_fallback(true)
#endif #endif
@ -251,6 +252,14 @@ namespace libtorrent
// random pieces instead of rarest first. // random pieces instead of rarest first.
int initial_picker_threshold; 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 #ifndef TORRENT_DISABLE_DHT
// while this is true, the dht will note be used unless the // while this is true, the dht will note be used unless the
// tracker is online // tracker is online

View File

@ -116,6 +116,7 @@ namespace libtorrent
, m_remote_bytes_dled(0) , m_remote_bytes_dled(0)
, m_remote_dl_rate(0) , m_remote_dl_rate(0)
, m_remote_dl_update(time_now()) , m_remote_dl_update(time_now())
, m_outstanding_writing_bytes(0)
#ifndef NDEBUG #ifndef NDEBUG
, m_in_constructor(true) , m_in_constructor(true)
#endif #endif
@ -189,6 +190,7 @@ namespace libtorrent
, m_remote_bytes_dled(0) , m_remote_bytes_dled(0)
, m_remote_dl_rate(0) , m_remote_dl_rate(0)
, m_remote_dl_update(time_now()) , m_remote_dl_update(time_now())
, m_outstanding_writing_bytes(0)
#ifndef NDEBUG #ifndef NDEBUG
, m_in_constructor(true) , m_in_constructor(true)
#endif #endif
@ -1150,6 +1152,7 @@ namespace libtorrent
fs.async_write(p, data, bind(&peer_connection::on_disk_write_complete fs.async_write(p, data, bind(&peer_connection::on_disk_write_complete
, self(), _1, _2, p, t)); , self(), _1, _2, p, t));
m_outstanding_writing_bytes += p.length;
picker.mark_as_writing(block_finished, peer_info_struct()); 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); 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 (ret == -1 || !t)
{ {
if (!t) if (!t)
@ -2324,7 +2334,9 @@ namespace libtorrent
return (m_bandwidth_limit[download_channel].quota_left() > 0 return (m_bandwidth_limit[download_channel].quota_left() > 0
|| m_ignore_bandwidth_limits) || 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) void peer_connection::connect(int ticket)