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
* handle DHT error responses correctly
* 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 ;
}
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)
|| <asserts>on in $(properties) )
{
@ -645,8 +653,6 @@ local usage-requirements =
<toolset>gcc:<cflags>-fno-strict-aliasing
<toolset>gcc:<cflags>-Wno-missing-braces
# assert on integer overflow
<toolset>gcc,<variant>debug:<cflags>-ftrapv
<toolset>darwin,<variant>debug:<cflags>-ftrapv
<toolset>clang:<cflags>-Wno-invalid-offsetof
<toolset>clang-darwin:<cflags>-Wno-invalid-offsetof
<boost>system:<cxxflags>$(CXXFLAGS)

View File

@ -96,7 +96,7 @@ private:
typedef std::vector<bw_request> queue_t;
queue_t m_queue;
// 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
// that bandwidth is assigned to (upload or download)

View File

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

View File

@ -123,7 +123,7 @@ namespace libtorrent
#if defined TORRENT_DEBUG && !defined TORRENT_DISABLE_INVARIANT_CHECKS
void bandwidth_manager::check_invariant() const
{
int queued = 0;
boost::int64_t queued = 0;
for (queue_t::const_iterator i = m_queue.begin()
, 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
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
* m_ses.m_settings.tick_interval / 1000);
int bytes = (std::max)(m_send_buffer.size()
, 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
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;
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
if (m_quota[download_channel] >= bytes) return 0;

View File

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