added feature to set a separate global rate limit for local peers
This commit is contained in:
parent
28c334fb35
commit
31c422df0a
|
@ -1,3 +1,4 @@
|
||||||
|
* added feature to set a separate global rate limit for local peers
|
||||||
* added preset settings for low memory environments and seed machines
|
* added preset settings for low memory environments and seed machines
|
||||||
min_memory_usage() and high_performance_seeder()
|
min_memory_usage() and high_performance_seeder()
|
||||||
* optimized overall memory usage for DHT nodes and requests, peer
|
* optimized overall memory usage for DHT nodes and requests, peer
|
||||||
|
|
|
@ -229,6 +229,11 @@ namespace libtorrent
|
||||||
|
|
||||||
int upload_rate_limit() const;
|
int upload_rate_limit() const;
|
||||||
int download_rate_limit() const;
|
int download_rate_limit() const;
|
||||||
|
int local_upload_rate_limit() const;
|
||||||
|
int local_download_rate_limit() const;
|
||||||
|
|
||||||
|
void set_local_download_rate_limit(int bytes_per_second);
|
||||||
|
void set_local_upload_rate_limit(int bytes_per_second);
|
||||||
|
|
||||||
void set_download_rate_limit(int bytes_per_second);
|
void set_download_rate_limit(int bytes_per_second);
|
||||||
void set_upload_rate_limit(int bytes_per_second);
|
void set_upload_rate_limit(int bytes_per_second);
|
||||||
|
@ -426,9 +431,18 @@ namespace libtorrent
|
||||||
bandwidth_manager<peer_connection> m_download_rate;
|
bandwidth_manager<peer_connection> m_download_rate;
|
||||||
bandwidth_manager<peer_connection> m_upload_rate;
|
bandwidth_manager<peer_connection> m_upload_rate;
|
||||||
|
|
||||||
|
// the global rate limiter bandwidth channels
|
||||||
bandwidth_channel m_download_channel;
|
bandwidth_channel m_download_channel;
|
||||||
bandwidth_channel m_upload_channel;
|
bandwidth_channel m_upload_channel;
|
||||||
|
|
||||||
|
// bandwidth channels for local peers when
|
||||||
|
// rate limits are ignored. They are only
|
||||||
|
// throttled by these global rate limiters
|
||||||
|
// and they don't have a rate limit set by
|
||||||
|
// default
|
||||||
|
bandwidth_channel m_local_download_channel;
|
||||||
|
bandwidth_channel m_local_upload_channel;
|
||||||
|
|
||||||
bandwidth_channel* m_bandwidth_channel[2];
|
bandwidth_channel* m_bandwidth_channel[2];
|
||||||
|
|
||||||
tracker_manager m_tracker_manager;
|
tracker_manager m_tracker_manager;
|
||||||
|
|
|
@ -634,6 +634,16 @@ namespace libtorrent
|
||||||
void on_disk_read_complete(int ret, disk_io_job const& j, peer_request r);
|
void on_disk_read_complete(int ret, disk_io_job const& j, peer_request r);
|
||||||
void on_disk_write_complete(int ret, disk_io_job const& j
|
void on_disk_write_complete(int ret, disk_io_job const& j
|
||||||
, peer_request r, boost::shared_ptr<torrent> t);
|
, peer_request r, boost::shared_ptr<torrent> t);
|
||||||
|
void request_upload_bandwidth(
|
||||||
|
bandwidth_channel* bwc1
|
||||||
|
, bandwidth_channel* bwc2 = 0
|
||||||
|
, bandwidth_channel* bwc3 = 0
|
||||||
|
, bandwidth_channel* bwc4 = 0);
|
||||||
|
void request_download_bandwidth(
|
||||||
|
bandwidth_channel* bwc1
|
||||||
|
, bandwidth_channel* bwc2 = 0
|
||||||
|
, bandwidth_channel* bwc3 = 0
|
||||||
|
, bandwidth_channel* bwc4 = 0);
|
||||||
|
|
||||||
// keep the io_service running as long as we
|
// keep the io_service running as long as we
|
||||||
// have peer connections
|
// have peer connections
|
||||||
|
|
|
@ -370,8 +370,12 @@ namespace libtorrent
|
||||||
|
|
||||||
int upload_rate_limit() const;
|
int upload_rate_limit() const;
|
||||||
int download_rate_limit() const;
|
int download_rate_limit() const;
|
||||||
|
int local_upload_rate_limit() const;
|
||||||
|
int local_download_rate_limit() const;
|
||||||
int max_half_open_connections() const;
|
int max_half_open_connections() const;
|
||||||
|
|
||||||
|
void set_local_upload_rate_limit(int bytes_per_second);
|
||||||
|
void set_local_download_rate_limit(int bytes_per_second);
|
||||||
void set_upload_rate_limit(int bytes_per_second);
|
void set_upload_rate_limit(int bytes_per_second);
|
||||||
void set_download_rate_limit(int bytes_per_second);
|
void set_download_rate_limit(int bytes_per_second);
|
||||||
void set_max_uploads(int limit);
|
void set_max_uploads(int limit);
|
||||||
|
|
|
@ -3565,6 +3565,47 @@ namespace libtorrent
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void peer_connection::request_upload_bandwidth(
|
||||||
|
bandwidth_channel* bwc1
|
||||||
|
, bandwidth_channel* bwc2
|
||||||
|
, bandwidth_channel* bwc3
|
||||||
|
, bandwidth_channel* bwc4)
|
||||||
|
{
|
||||||
|
shared_ptr<torrent> t = m_torrent.lock();
|
||||||
|
int priority = 1 + is_interesting() * 2 + m_requests_in_buffer.size();
|
||||||
|
// peers that we are not interested in are non-prioritized
|
||||||
|
m_channel_state[upload_channel] = peer_info::bw_limit;
|
||||||
|
m_ses.m_upload_rate.request_bandwidth(self()
|
||||||
|
, m_send_buffer.size(), priority
|
||||||
|
, bwc1, bwc2, bwc3, bwc4);
|
||||||
|
#ifdef TORRENT_VERBOSE_LOGGING
|
||||||
|
(*m_logger) << time_now_string() << " *** REQUEST_BANDWIDTH [ "
|
||||||
|
"upload: " << m_send_buffer.size()
|
||||||
|
<< " prio: " << priority << "]\n";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void peer_connection::request_download_bandwidth(
|
||||||
|
bandwidth_channel* bwc1
|
||||||
|
, bandwidth_channel* bwc2
|
||||||
|
, bandwidth_channel* bwc3
|
||||||
|
, bandwidth_channel* bwc4)
|
||||||
|
{
|
||||||
|
shared_ptr<torrent> t = m_torrent.lock();
|
||||||
|
|
||||||
|
#ifdef TORRENT_VERBOSE_LOGGING
|
||||||
|
(*m_logger) << time_now_string() << " *** REQUEST_BANDWIDTH [ "
|
||||||
|
"download: " << (m_download_queue.size() * 16 * 1024 + 30)
|
||||||
|
<< " prio: " << m_priority << " ]\n";
|
||||||
|
#endif
|
||||||
|
TORRENT_ASSERT(m_channel_state[download_channel] == peer_info::bw_idle);
|
||||||
|
TORRENT_ASSERT(m_outstanding_bytes >= 0);
|
||||||
|
m_channel_state[download_channel] = peer_info::bw_limit;
|
||||||
|
m_ses.m_download_rate.request_bandwidth(self()
|
||||||
|
, m_outstanding_bytes + 30, m_priority
|
||||||
|
, bwc1, bwc2, bwc3, bwc4);
|
||||||
|
}
|
||||||
|
|
||||||
void peer_connection::setup_send()
|
void peer_connection::setup_send()
|
||||||
{
|
{
|
||||||
session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);
|
session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);
|
||||||
|
@ -3576,26 +3617,27 @@ namespace libtorrent
|
||||||
if (m_quota[upload_channel] == 0
|
if (m_quota[upload_channel] == 0
|
||||||
&& !m_send_buffer.empty()
|
&& !m_send_buffer.empty()
|
||||||
&& !m_connecting
|
&& !m_connecting
|
||||||
&& t
|
&& t)
|
||||||
&& !m_ignore_bandwidth_limits)
|
|
||||||
{
|
{
|
||||||
// in this case, we have data to send, but no
|
if (!m_ignore_bandwidth_limits)
|
||||||
// bandwidth. So, we simply request bandwidth
|
{
|
||||||
// from the torrent
|
// in this case, we have data to send, but no
|
||||||
TORRENT_ASSERT(t);
|
// bandwidth. So, we simply request bandwidth
|
||||||
int priority = 1 + is_interesting() * 2 + m_requests_in_buffer.size();
|
// from the bandwidth manager
|
||||||
// peers that we are not interested in are non-prioritized
|
request_upload_bandwidth(
|
||||||
m_channel_state[upload_channel] = peer_info::bw_limit;
|
&m_ses.m_upload_channel
|
||||||
m_ses.m_upload_rate.request_bandwidth(self()
|
, &t->m_bandwidth_channel[upload_channel]
|
||||||
, m_send_buffer.size(), priority
|
, &m_bandwidth_channel[upload_channel]);
|
||||||
, &m_ses.m_upload_channel
|
}
|
||||||
, &t->m_bandwidth_channel[upload_channel]
|
else
|
||||||
, &m_bandwidth_channel[upload_channel]);
|
{
|
||||||
#ifdef TORRENT_VERBOSE_LOGGING
|
// in this case, we're a local peer, and the settings
|
||||||
(*m_logger) << time_now_string() << " *** REQUEST_BANDWIDTH [ "
|
// are set to ignore rate limits for local peers. So,
|
||||||
"upload: " << m_send_buffer.size()
|
// instead we rate limit ourself against the special
|
||||||
<< " prio: " << priority << "]\n";
|
// global bandwidth channel for local peers, which defaults
|
||||||
#endif
|
// to unthrottled
|
||||||
|
request_upload_bandwidth(&m_ses.m_local_upload_channel);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3656,22 +3698,27 @@ namespace libtorrent
|
||||||
|
|
||||||
if (m_quota[download_channel] == 0
|
if (m_quota[download_channel] == 0
|
||||||
&& !m_connecting
|
&& !m_connecting
|
||||||
&& t
|
&& t)
|
||||||
&& !m_ignore_bandwidth_limits)
|
|
||||||
{
|
{
|
||||||
#ifdef TORRENT_VERBOSE_LOGGING
|
if (!m_ignore_bandwidth_limits)
|
||||||
(*m_logger) << time_now_string() << " *** REQUEST_BANDWIDTH [ "
|
{
|
||||||
"download: " << (m_download_queue.size() * 16 * 1024 + 30)
|
// in this case, we have outstanding data to
|
||||||
<< " prio: " << m_priority << " ]\n";
|
// receive, but no bandwidth quota. So, we simply
|
||||||
#endif
|
// request bandwidth from the bandwidth manager
|
||||||
TORRENT_ASSERT(m_channel_state[download_channel] == peer_info::bw_idle);
|
request_download_bandwidth(
|
||||||
TORRENT_ASSERT(m_outstanding_bytes >= 0);
|
&m_ses.m_download_channel
|
||||||
m_channel_state[download_channel] = peer_info::bw_limit;
|
, &t->m_bandwidth_channel[download_channel]
|
||||||
m_ses.m_download_rate.request_bandwidth(self()
|
, &m_bandwidth_channel[download_channel]);
|
||||||
, m_outstanding_bytes + 30, m_priority
|
}
|
||||||
, &m_ses.m_download_channel
|
else
|
||||||
, &t->m_bandwidth_channel[download_channel]
|
{
|
||||||
, &m_bandwidth_channel[download_channel]);
|
// in this case, we're a local peer, and the settings
|
||||||
|
// are set to ignore rate limits for local peers. So,
|
||||||
|
// instead we rate limit ourself against the special
|
||||||
|
// global bandwidth channel for local peers, which defaults
|
||||||
|
// to unthrottled
|
||||||
|
request_download_bandwidth(&m_ses.m_local_download_channel);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -652,6 +652,16 @@ namespace libtorrent
|
||||||
m_impl->set_max_half_open_connections(limit);
|
m_impl->set_max_half_open_connections(limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int session::local_upload_rate_limit() const
|
||||||
|
{
|
||||||
|
return m_impl->local_upload_rate_limit();
|
||||||
|
}
|
||||||
|
|
||||||
|
int session::local_download_rate_limit() const
|
||||||
|
{
|
||||||
|
return m_impl->local_download_rate_limit();
|
||||||
|
}
|
||||||
|
|
||||||
int session::upload_rate_limit() const
|
int session::upload_rate_limit() const
|
||||||
{
|
{
|
||||||
return m_impl->upload_rate_limit();
|
return m_impl->upload_rate_limit();
|
||||||
|
@ -662,6 +672,16 @@ namespace libtorrent
|
||||||
return m_impl->download_rate_limit();
|
return m_impl->download_rate_limit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void session::set_local_upload_rate_limit(int bytes_per_second)
|
||||||
|
{
|
||||||
|
m_impl->set_local_upload_rate_limit(bytes_per_second);
|
||||||
|
}
|
||||||
|
|
||||||
|
void session::set_local_download_rate_limit(int bytes_per_second)
|
||||||
|
{
|
||||||
|
m_impl->set_local_download_rate_limit(bytes_per_second);
|
||||||
|
}
|
||||||
|
|
||||||
void session::set_upload_rate_limit(int bytes_per_second)
|
void session::set_upload_rate_limit(int bytes_per_second)
|
||||||
{
|
{
|
||||||
m_impl->set_upload_rate_limit(bytes_per_second);
|
m_impl->set_upload_rate_limit(bytes_per_second);
|
||||||
|
|
|
@ -1772,7 +1772,8 @@ namespace aux {
|
||||||
// assume a reasonable rate is 3 kB/s, unless there's an upload limit and
|
// assume a reasonable rate is 3 kB/s, unless there's an upload limit and
|
||||||
// a max number of slots, in which case we assume each upload slot gets
|
// a max number of slots, in which case we assume each upload slot gets
|
||||||
// roughly the same amount of bandwidth
|
// roughly the same amount of bandwidth
|
||||||
if (m_upload_channel.throttle() != bandwidth_channel::inf && m_max_uploads > 0)
|
TORRENT_ASSERT(m_upload_channel.throttle() != bandwidth_channel::inf);
|
||||||
|
if (m_upload_channel.throttle() > 0 && m_max_uploads > 0)
|
||||||
rate = (std::max)(m_upload_channel.throttle() / m_max_uploads, 1);
|
rate = (std::max)(m_upload_channel.throttle() / m_max_uploads, 1);
|
||||||
|
|
||||||
// the time it takes to download one piece at this rate (in seconds)
|
// the time it takes to download one piece at this rate (in seconds)
|
||||||
|
@ -2665,14 +2666,34 @@ namespace aux {
|
||||||
m_half_open.limit(limit);
|
m_half_open.limit(limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void session_impl::set_local_download_rate_limit(int bytes_per_second)
|
||||||
|
{
|
||||||
|
mutex_t::scoped_lock l(m_mutex);
|
||||||
|
|
||||||
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
|
if (bytes_per_second <= 0) bytes_per_second = 0;
|
||||||
|
m_local_download_channel.throttle(bytes_per_second);
|
||||||
|
}
|
||||||
|
|
||||||
|
void session_impl::set_local_upload_rate_limit(int bytes_per_second)
|
||||||
|
{
|
||||||
|
mutex_t::scoped_lock l(m_mutex);
|
||||||
|
|
||||||
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
|
if (bytes_per_second <= 0) bytes_per_second = 0;
|
||||||
|
m_local_upload_channel.throttle(bytes_per_second);
|
||||||
|
}
|
||||||
|
|
||||||
void session_impl::set_download_rate_limit(int bytes_per_second)
|
void session_impl::set_download_rate_limit(int bytes_per_second)
|
||||||
{
|
{
|
||||||
mutex_t::scoped_lock l(m_mutex);
|
mutex_t::scoped_lock l(m_mutex);
|
||||||
|
|
||||||
INVARIANT_CHECK;
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
if (bytes_per_second <= 0) bytes_per_second = bandwidth_channel::inf;
|
if (bytes_per_second <= 0) bytes_per_second = 0;
|
||||||
m_bandwidth_channel[peer_connection::download_channel]->throttle(bytes_per_second);
|
m_download_channel.throttle(bytes_per_second);
|
||||||
}
|
}
|
||||||
|
|
||||||
void session_impl::set_upload_rate_limit(int bytes_per_second)
|
void session_impl::set_upload_rate_limit(int bytes_per_second)
|
||||||
|
@ -2681,8 +2702,8 @@ namespace aux {
|
||||||
|
|
||||||
INVARIANT_CHECK;
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
if (bytes_per_second <= 0) bytes_per_second = bandwidth_channel::inf;
|
if (bytes_per_second <= 0) bytes_per_second = 0;
|
||||||
m_bandwidth_channel[peer_connection::upload_channel]->throttle(bytes_per_second);
|
m_upload_channel.throttle(bytes_per_second);
|
||||||
}
|
}
|
||||||
|
|
||||||
void session_impl::set_alert_dispatch(boost::function<void(alert const&)> const& fun)
|
void session_impl::set_alert_dispatch(boost::function<void(alert const&)> const& fun)
|
||||||
|
@ -2720,21 +2741,28 @@ namespace aux {
|
||||||
return m_alerts.set_alert_queue_size_limit(queue_size_limit_);
|
return m_alerts.set_alert_queue_size_limit(queue_size_limit_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int session_impl::local_upload_rate_limit() const
|
||||||
|
{
|
||||||
|
mutex_t::scoped_lock l(m_mutex);
|
||||||
|
return m_local_upload_channel.throttle();
|
||||||
|
}
|
||||||
|
|
||||||
|
int session_impl::local_download_rate_limit() const
|
||||||
|
{
|
||||||
|
mutex_t::scoped_lock l(m_mutex);
|
||||||
|
return m_local_download_channel.throttle();
|
||||||
|
}
|
||||||
|
|
||||||
int session_impl::upload_rate_limit() const
|
int session_impl::upload_rate_limit() const
|
||||||
{
|
{
|
||||||
mutex_t::scoped_lock l(m_mutex);
|
mutex_t::scoped_lock l(m_mutex);
|
||||||
|
return m_upload_channel.throttle();
|
||||||
INVARIANT_CHECK;
|
|
||||||
|
|
||||||
int ret = m_bandwidth_channel[peer_connection::upload_channel]->throttle();
|
|
||||||
return ret == (std::numeric_limits<int>::max)() ? -1 : ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int session_impl::download_rate_limit() const
|
int session_impl::download_rate_limit() const
|
||||||
{
|
{
|
||||||
mutex_t::scoped_lock l(m_mutex);
|
mutex_t::scoped_lock l(m_mutex);
|
||||||
int ret = m_bandwidth_channel[peer_connection::download_channel]->throttle();
|
return m_download_channel.throttle();
|
||||||
return ret == (std::numeric_limits<int>::max)() ? -1 : ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void session_impl::start_lsd()
|
void session_impl::start_lsd()
|
||||||
|
|
Loading…
Reference in New Issue