rate limiter overflow fix (for very high limits)

This commit is contained in:
Arvid Norberg 2014-01-13 06:49:47 +00:00
parent 86b68e65e4
commit d7be4659c8
7 changed files with 24 additions and 11 deletions

View File

@ -1,3 +1,4 @@
* rate limiter overflow fix (for very high limits)
* non-auto-managed torrents no longer count against the torrent limits * non-auto-managed torrents no longer count against the torrent limits
* handle DHT error responses correctly * handle DHT error responses correctly
* allow force_announce to only affect a single tracker * allow force_announce to only affect a single tracker

10
Jamfile
View File

@ -244,6 +244,14 @@ rule building ( properties * )
result += <define>TORRENT_EXPORT_EXTRA ; result += <define>TORRENT_EXPORT_EXTRA ;
} }
if ( <variant>debug in $(properties)
&& ( <toolset>clang in $(properties)
|| <toolset>gcc in $(properties)
|| <toolset>darwin in $(properties) ) )
{
result += <cflags>-ftrapv ;
}
if ( <variant>debug in $(properties) if ( <variant>debug in $(properties)
|| <asserts>on in $(properties) ) || <asserts>on in $(properties) )
{ {
@ -645,8 +653,6 @@ local usage-requirements =
<toolset>gcc:<cflags>-fno-strict-aliasing <toolset>gcc:<cflags>-fno-strict-aliasing
<toolset>gcc:<cflags>-Wno-missing-braces <toolset>gcc:<cflags>-Wno-missing-braces
# assert on integer overflow # assert on integer overflow
<toolset>gcc,<variant>debug:<cflags>-ftrapv
<toolset>darwin,<variant>debug:<cflags>-ftrapv
<toolset>clang:<cflags>-Wno-invalid-offsetof <toolset>clang:<cflags>-Wno-invalid-offsetof
<toolset>clang-darwin:<cflags>-Wno-invalid-offsetof <toolset>clang-darwin:<cflags>-Wno-invalid-offsetof
<boost>system:<cxxflags>$(CXXFLAGS) <boost>system:<cxxflags>$(CXXFLAGS)

View File

@ -96,7 +96,7 @@ private:
typedef std::vector<bw_request> queue_t; typedef std::vector<bw_request> queue_t;
queue_t m_queue; queue_t m_queue;
// the number of bytes all the requests in queue are for // the number of bytes all the requests in queue are for
int m_queued_bytes; boost::int64_t m_queued_bytes;
// this is the channel within the consumers // this is the channel within the consumers
// that bandwidth is assigned to (upload or download) // that bandwidth is assigned to (upload or download)

View File

@ -47,7 +47,7 @@ namespace libtorrent
{ {
TORRENT_ASSERT(limit >= 0); TORRENT_ASSERT(limit >= 0);
// if the throttle is more than this, we might overflow // if the throttle is more than this, we might overflow
TORRENT_ASSERT(limit < INT_MAX / 31); TORRENT_ASSERT(limit < INT_MAX);
m_limit = limit; m_limit = limit;
} }

View File

@ -123,7 +123,7 @@ namespace libtorrent
#if defined TORRENT_DEBUG && !defined TORRENT_DISABLE_INVARIANT_CHECKS #if defined TORRENT_DEBUG && !defined TORRENT_DISABLE_INVARIANT_CHECKS
void bandwidth_manager::check_invariant() const void bandwidth_manager::check_invariant() const
{ {
int queued = 0; boost::int64_t queued = 0;
for (queue_t::const_iterator i = m_queue.begin() for (queue_t::const_iterator i = m_queue.begin()
, end(m_queue.end()); i != end; ++i) , end(m_queue.end()); i != end; ++i)
{ {

View File

@ -4676,8 +4676,9 @@ namespace libtorrent
// we can only have one outstanding bandwidth request at a time // we can only have one outstanding bandwidth request at a time
if (m_channel_state[upload_channel] & peer_info::bw_limit) return 0; if (m_channel_state[upload_channel] & peer_info::bw_limit) return 0;
int bytes = (std::max)(m_send_buffer.size(), m_statistics.upload_rate() * 2 int bytes = (std::max)(m_send_buffer.size()
* m_ses.m_settings.tick_interval / 1000); , int(boost::int64_t(m_statistics.upload_rate()) * 2
* m_ses.m_settings.tick_interval / 1000));
// we already have quota for the bytes we want to send // we already have quota for the bytes we want to send
if (m_quota[upload_channel] >= bytes) return 0; if (m_quota[upload_channel] >= bytes) return 0;
@ -4761,7 +4762,8 @@ namespace libtorrent
if (m_channel_state[download_channel] & peer_info::bw_limit) return 0; if (m_channel_state[download_channel] & peer_info::bw_limit) return 0;
int bytes = (std::max)((std::max)(m_outstanding_bytes, m_packet_size - m_recv_pos) + 30 int bytes = (std::max)((std::max)(m_outstanding_bytes, m_packet_size - m_recv_pos) + 30
, m_statistics.download_rate() * 2 * m_ses.m_settings.tick_interval / 1000); , int(boost::int64_t(m_statistics.download_rate()) * 2
* m_ses.m_settings.tick_interval / 1000));
// we already have enough quota // we already have enough quota
if (m_quota[download_channel] >= bytes) return 0; if (m_quota[download_channel] >= bytes) return 0;

View File

@ -39,6 +39,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/socket.hpp" #include "libtorrent/socket.hpp"
#include "libtorrent/stat.hpp" #include "libtorrent/stat.hpp"
#include "libtorrent/time.hpp" #include "libtorrent/time.hpp"
#include "libtorrent/session_settings.hpp"
#include <boost/function.hpp> #include <boost/function.hpp>
#include <boost/bind.hpp> #include <boost/bind.hpp>
@ -100,7 +101,7 @@ void peer_connection::assign_bandwidth(int channel, int amount)
void peer_connection::start() void peer_connection::start()
{ {
m_bwm.request_bandwidth(self(), 150000, m_priority m_bwm.request_bandwidth(self(), 400000000, m_priority
, &m_bandwidth_channel , &m_bandwidth_channel
, &m_torrent_bandwidth_channel , &m_torrent_bandwidth_channel
, &global_bwc); , &global_bwc);
@ -151,9 +152,11 @@ void run_test(connections_t& v
std::for_each(v.begin(), v.end() std::for_each(v.begin(), v.end()
, boost::bind(&peer_connection::start, _1)); , boost::bind(&peer_connection::start, _1));
for (int i = 0; i < int(sample_time * 10); ++i) int tick_interval = session_settings().tick_interval;
for (int i = 0; i < int(sample_time * 1000 / tick_interval); ++i)
{ {
manager.update_quotas(milliseconds(100)); manager.update_quotas(milliseconds(tick_interval));
if ((i % 15) == 0) f(); if ((i % 15) == 0) f();
} }
} }
@ -459,6 +462,7 @@ int test_main()
test_equal_connections(7, 20000); test_equal_connections(7, 20000);
test_equal_connections(33, 60000); test_equal_connections(33, 60000);
test_equal_connections(33, 500000); test_equal_connections(33, 500000);
test_equal_connections(1, 100000000);
test_connections_variable_rate(2, 20, 0); test_connections_variable_rate(2, 20, 0);
test_connections_variable_rate(5, 20000, 0); test_connections_variable_rate(5, 20000, 0);
test_connections_variable_rate(3, 2000, 6000); test_connections_variable_rate(3, 2000, 6000);