# Adjust number of pieces requested from peer if we're # uploading too slowly but downloading very fast so it exhausts the # queue before we finish sending a piece and can request more. See ticket #1302 - libtorrent.rakshasa.no Index: libtorrent/src/protocol/peer_connection_base.cc =================================================================== --- libtorrent/src/protocol/peer_connection_base.cc (revision 1060) +++ libtorrent/src/protocol/peer_connection_base.cc (working copy) @@ -783,8 +783,11 @@ if (download_queue()->queued_empty()) m_downStall = 0; - uint32_t pipeSize = download_queue()->calculate_pipe_size(m_peerChunks.download_throttle()->rate()->rate()); + uint32_t upRate = (!m_upChoke.choked() && !m_peerChunks.upload_queue()->empty()) ? + m_peerChunks.upload_throttle()->rate()->rate() : 0; + uint32_t pipeSize = download_queue()->calculate_pipe_size(m_peerChunks.download_throttle()->rate()->rate(), upRate); + // Don't start requesting if we can't do it in large enough chunks. if (download_queue()->queued_size() >= (pipeSize + 10) / 2) return false; Index: libtorrent/src/protocol/request_list.cc =================================================================== --- libtorrent/src/protocol/request_list.cc (revision 1060) +++ libtorrent/src/protocol/request_list.cc (working copy) @@ -263,22 +263,30 @@ } uint32_t -RequestList::calculate_pipe_size(uint32_t rate) { +RequestList::calculate_pipe_size(uint32_t downRate, uint32_t upRate) { + // Compute how many pieces we will receive while transmitting one. + // Since we can't request during that time, make sure the pipe is + // big enough so it doesn't run dry. + if (upRate) + upRate = downRate / upRate; + // Change into KB. - rate /= 1024; + downRate /= 1024; if (!m_delegator->get_aggressive()) { - if (rate < 20) - return rate + 2; + if (downRate < 20) + downRate = downRate + 2; else - return rate / 5 + 18; + downRate = downRate / 5 + 18; } else { - if (rate < 10) - return rate / 5 + 1; + if (downRate < 10) + downRate = downRate / 5 + 1; else - return rate / 10 + 2; + downRate = downRate / 10 + 2; } + + return std::max(downRate, 1 + upRate); } } Index: libtorrent/src/protocol/request_list.h =================================================================== --- libtorrent/src/protocol/request_list.h (revision 1060) +++ libtorrent/src/protocol/request_list.h (working copy) @@ -87,7 +87,7 @@ bool canceled_empty() const { return m_canceled.empty(); } size_t canceled_size() const { return m_queued.size(); } - uint32_t calculate_pipe_size(uint32_t rate); + uint32_t calculate_pipe_size(uint32_t downRate, uint32_t upRate); void set_delegator(Delegator* d) { m_delegator = d; } void set_peer_chunks(PeerChunks* b) { m_peerChunks = b; }