forked from premiere/premiere-libtorrent
merged some rate limiter polish from libtorrent_aio
This commit is contained in:
parent
dde078cdf7
commit
90e7a4c9e3
|
@ -90,6 +90,8 @@ struct TORRENT_EXTRA_EXPORT bandwidth_manager
|
||||||
|
|
||||||
void update_quotas(time_duration const& dt);
|
void update_quotas(time_duration const& dt);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
// these are the consumers that want bandwidth
|
// these are the consumers that want bandwidth
|
||||||
typedef std::vector<bw_request> queue_t;
|
typedef std::vector<bw_request> queue_t;
|
||||||
queue_t m_queue;
|
queue_t m_queue;
|
||||||
|
|
|
@ -62,7 +62,9 @@ struct TORRENT_EXTRA_EXPORT bw_request
|
||||||
// from the most limiting one
|
// from the most limiting one
|
||||||
int assign_bandwidth();
|
int assign_bandwidth();
|
||||||
|
|
||||||
bandwidth_channel* channel[5];
|
enum { max_bandwidth_channels = 5 };
|
||||||
|
// we don't actually support more than 5 channels per peer
|
||||||
|
bandwidth_channel* channel[max_bandwidth_channels];
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -486,7 +486,7 @@ namespace libtorrent
|
||||||
void start_receive_piece(peer_request const& r);
|
void start_receive_piece(peer_request const& r);
|
||||||
void incoming_cancel(peer_request const& r);
|
void incoming_cancel(peer_request const& r);
|
||||||
|
|
||||||
bool can_disconnect(error_code const& ec);
|
bool can_disconnect(error_code const& ec) const;
|
||||||
void incoming_dht_port(int listen_port);
|
void incoming_dht_port(int listen_port);
|
||||||
|
|
||||||
void incoming_reject_request(peer_request const& r);
|
void incoming_reject_request(peer_request const& r);
|
||||||
|
|
|
@ -147,6 +147,8 @@ namespace libtorrent
|
||||||
|
|
||||||
std::vector<bandwidth_channel*> channels;
|
std::vector<bandwidth_channel*> channels;
|
||||||
|
|
||||||
|
queue_t tm;
|
||||||
|
|
||||||
for (queue_t::iterator i = m_queue.begin();
|
for (queue_t::iterator i = m_queue.begin();
|
||||||
i != m_queue.end();)
|
i != m_queue.end();)
|
||||||
{
|
{
|
||||||
|
@ -156,16 +158,18 @@ namespace libtorrent
|
||||||
|
|
||||||
// return all assigned quota to all the
|
// return all assigned quota to all the
|
||||||
// bandwidth channels this peer belongs to
|
// bandwidth channels this peer belongs to
|
||||||
for (int j = 0; j < 5 && i->channel[j]; ++j)
|
for (int j = 0; j < bw_request::max_bandwidth_channels && i->channel[j]; ++j)
|
||||||
{
|
{
|
||||||
bandwidth_channel* bwc = i->channel[j];
|
bandwidth_channel* bwc = i->channel[j];
|
||||||
bwc->return_quota(i->assigned);
|
bwc->return_quota(i->assigned);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
i->assigned = 0;
|
||||||
|
tm.push_back(*i);
|
||||||
i = m_queue.erase(i);
|
i = m_queue.erase(i);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for (int j = 0; j < 5 && i->channel[j]; ++j)
|
for (int j = 0; j < bw_request::max_bandwidth_channels && i->channel[j]; ++j)
|
||||||
{
|
{
|
||||||
bandwidth_channel* bwc = i->channel[j];
|
bandwidth_channel* bwc = i->channel[j];
|
||||||
bwc->tmp = 0;
|
bwc->tmp = 0;
|
||||||
|
@ -176,7 +180,7 @@ namespace libtorrent
|
||||||
for (queue_t::iterator i = m_queue.begin()
|
for (queue_t::iterator i = m_queue.begin()
|
||||||
, end(m_queue.end()); i != end; ++i)
|
, end(m_queue.end()); i != end; ++i)
|
||||||
{
|
{
|
||||||
for (int j = 0; j < 5 && i->channel[j]; ++j)
|
for (int j = 0; j < bw_request::max_bandwidth_channels && i->channel[j]; ++j)
|
||||||
{
|
{
|
||||||
bandwidth_channel* bwc = i->channel[j];
|
bandwidth_channel* bwc = i->channel[j];
|
||||||
if (bwc->tmp == 0) channels.push_back(bwc);
|
if (bwc->tmp == 0) channels.push_back(bwc);
|
||||||
|
@ -191,8 +195,6 @@ namespace libtorrent
|
||||||
(*i)->update_quota(dt_milliseconds);
|
(*i)->update_quota(dt_milliseconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
queue_t tm;
|
|
||||||
|
|
||||||
for (queue_t::iterator i = m_queue.begin();
|
for (queue_t::iterator i = m_queue.begin();
|
||||||
i != m_queue.end();)
|
i != m_queue.end();)
|
||||||
{
|
{
|
||||||
|
|
|
@ -893,6 +893,9 @@ namespace libtorrent
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
disconnect_if_redundant();
|
||||||
|
if (is_disconnecting()) return;
|
||||||
|
|
||||||
#ifdef TORRENT_VERBOSE_LOGGING
|
#ifdef TORRENT_VERBOSE_LOGGING
|
||||||
peer_log("==> HAVE [ piece: %d ]", index);
|
peer_log("==> HAVE [ piece: %d ]", index);
|
||||||
#endif
|
#endif
|
||||||
|
@ -1896,10 +1899,10 @@ namespace libtorrent
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool peer_connection::can_disconnect(error_code const& ec)
|
bool peer_connection::can_disconnect(error_code const& ec) const
|
||||||
{
|
{
|
||||||
#ifndef TORRENT_DISABLE_EXTENSIONS
|
#ifndef TORRENT_DISABLE_EXTENSIONS
|
||||||
for (extension_list_t::iterator i = m_extensions.begin()
|
for (extension_list_t::const_iterator i = m_extensions.begin()
|
||||||
, end(m_extensions.end()); i != end; ++i)
|
, end(m_extensions.end()); i != end; ++i)
|
||||||
{
|
{
|
||||||
if (!(*i)->can_disconnect(ec)) return false;
|
if (!(*i)->can_disconnect(ec)) return false;
|
||||||
|
@ -4637,10 +4640,16 @@ namespace libtorrent
|
||||||
, channel == upload_channel ? ">>>" : "<<<", amount);
|
, channel == upload_channel ? ">>>" : "<<<", amount);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TORRENT_ASSERT(amount > 0);
|
TORRENT_ASSERT(amount > 0 || is_disconnecting());
|
||||||
m_quota[channel] += amount;
|
m_quota[channel] += amount;
|
||||||
TORRENT_ASSERT(m_channel_state[channel] & peer_info::bw_limit);
|
TORRENT_ASSERT(m_channel_state[channel] & peer_info::bw_limit);
|
||||||
m_channel_state[channel] &= ~peer_info::bw_limit;
|
m_channel_state[channel] &= ~peer_info::bw_limit;
|
||||||
|
|
||||||
|
#if defined TORRENT_DEBUG && !defined TORRENT_DISABLE_INVARIANT_CHECKS
|
||||||
|
check_invariant();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (is_disconnecting()) return;
|
||||||
if (channel == upload_channel)
|
if (channel == upload_channel)
|
||||||
{
|
{
|
||||||
setup_send();
|
setup_send();
|
||||||
|
@ -4740,6 +4749,7 @@ namespace libtorrent
|
||||||
, bandwidth_channel* bwc3
|
, bandwidth_channel* bwc3
|
||||||
, bandwidth_channel* bwc4)
|
, bandwidth_channel* bwc4)
|
||||||
{
|
{
|
||||||
|
INVARIANT_CHECK;
|
||||||
// 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[download_channel] & peer_info::bw_limit) return 0;
|
if (m_channel_state[download_channel] & peer_info::bw_limit) return 0;
|
||||||
|
|
||||||
|
@ -5734,6 +5744,14 @@ namespace libtorrent
|
||||||
TORRENT_ASSERT(m_upload_limit >= 0);
|
TORRENT_ASSERT(m_upload_limit >= 0);
|
||||||
TORRENT_ASSERT(m_download_limit >= 0);
|
TORRENT_ASSERT(m_download_limit >= 0);
|
||||||
|
|
||||||
|
// TODO: why does this invariant not hold?
|
||||||
|
/*
|
||||||
|
if (m_channel_state[upload_channel] & peer_info::bw_limit)
|
||||||
|
TORRENT_ASSERT(m_ses.m_upload_rate.is_queued(this));
|
||||||
|
if (m_channel_state[download_channel] & peer_info::bw_limit)
|
||||||
|
TORRENT_ASSERT(m_ses.m_download_rate.is_queued(this));
|
||||||
|
*/
|
||||||
|
|
||||||
boost::shared_ptr<torrent> t = m_torrent.lock();
|
boost::shared_ptr<torrent> t = m_torrent.lock();
|
||||||
|
|
||||||
if (!m_disconnect_started && m_initialized)
|
if (!m_disconnect_started && m_initialized)
|
||||||
|
@ -5829,11 +5847,20 @@ namespace libtorrent
|
||||||
// in share mode we don't close redundant connections
|
// in share mode we don't close redundant connections
|
||||||
if (m_ses.settings().close_redundant_connections && !t->share_mode())
|
if (m_ses.settings().close_redundant_connections && !t->share_mode())
|
||||||
{
|
{
|
||||||
|
bool ok_to_disconnect =
|
||||||
|
can_disconnect(error_code(errors::upload_upload_connection, get_libtorrent_category()))
|
||||||
|
|| can_disconnect(error_code(errors::uninteresting_upload_peer, get_libtorrent_category()))
|
||||||
|
|| can_disconnect(error_code(errors::too_many_requests_when_choked, get_libtorrent_category()))
|
||||||
|
|| can_disconnect(error_code(errors::timed_out_no_interest, get_libtorrent_category()))
|
||||||
|
|| can_disconnect(error_code(errors::timed_out_no_request, get_libtorrent_category()))
|
||||||
|
|| can_disconnect(error_code(errors::timed_out_inactivity, get_libtorrent_category()));
|
||||||
|
|
||||||
// make sure upload only peers are disconnected
|
// make sure upload only peers are disconnected
|
||||||
if (t->is_upload_only()
|
if (t->is_upload_only()
|
||||||
&& m_upload_only
|
&& m_upload_only
|
||||||
&& t->valid_metadata()
|
&& t->valid_metadata()
|
||||||
&& has_metadata())
|
&& has_metadata()
|
||||||
|
&& ok_to_disconnect)
|
||||||
TORRENT_ASSERT(m_disconnect_started || t->graceful_pause() || t->has_error());
|
TORRENT_ASSERT(m_disconnect_started || t->graceful_pause() || t->has_error());
|
||||||
|
|
||||||
if (m_upload_only
|
if (m_upload_only
|
||||||
|
@ -5841,7 +5868,8 @@ namespace libtorrent
|
||||||
&& m_bitfield_received
|
&& m_bitfield_received
|
||||||
&& t->are_files_checked()
|
&& t->are_files_checked()
|
||||||
&& t->valid_metadata()
|
&& t->valid_metadata()
|
||||||
&& has_metadata())
|
&& has_metadata()
|
||||||
|
&& ok_to_disconnect)
|
||||||
TORRENT_ASSERT(m_disconnect_started);
|
TORRENT_ASSERT(m_disconnect_started);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3040,6 +3040,7 @@ retry:
|
||||||
if (num_connections() >= m_settings.connections_limit)
|
if (num_connections() >= m_settings.connections_limit)
|
||||||
c->peer_exceeds_limit();
|
c->peer_exceeds_limit();
|
||||||
|
|
||||||
|
TORRENT_ASSERT(!c->m_in_constructor);
|
||||||
m_connections.insert(c);
|
m_connections.insert(c);
|
||||||
c->start();
|
c->start();
|
||||||
// update the next disk peer round-robin cursor
|
// update the next disk peer round-robin cursor
|
||||||
|
@ -3360,8 +3361,8 @@ retry:
|
||||||
int total_peers = num_peers[0][i] + num_peers[1][i];
|
int total_peers = num_peers[0][i] + num_peers[1][i];
|
||||||
// this are 64 bits since it's multiplied by the number
|
// this are 64 bits since it's multiplied by the number
|
||||||
// of peers, which otherwise might overflow an int
|
// of peers, which otherwise might overflow an int
|
||||||
boost::uint64_t rate = (std::max)(stat_rate[i], lower_limit[i]);
|
boost::uint64_t rate = stat_rate[i];
|
||||||
tcp_channel[i]->throttle(int(rate * num_peers[0][i] / total_peers));
|
tcp_channel[i]->throttle((std::max)(int(rate * num_peers[0][i] / total_peers), lower_limit[i]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4949,6 +4949,7 @@ namespace libtorrent
|
||||||
|
|
||||||
TORRENT_TRY
|
TORRENT_TRY
|
||||||
{
|
{
|
||||||
|
TORRENT_ASSERT(!c->m_in_constructor);
|
||||||
// add the newly connected peer to this torrent's peer list
|
// add the newly connected peer to this torrent's peer list
|
||||||
m_connections.insert(boost::get_pointer(c));
|
m_connections.insert(boost::get_pointer(c));
|
||||||
m_ses.m_connections.insert(c);
|
m_ses.m_connections.insert(c);
|
||||||
|
|
|
@ -490,6 +490,9 @@ namespace libtorrent
|
||||||
// if the status code is not one of the accepted ones, abort
|
// if the status code is not one of the accepted ones, abort
|
||||||
if (!is_ok_status(m_parser.status_code()))
|
if (!is_ok_status(m_parser.status_code()))
|
||||||
{
|
{
|
||||||
|
// TODO: 3 just make this peer not have the pieces
|
||||||
|
// associated with the file we just requested. Only
|
||||||
|
// when it doesn't have any of the file do the following
|
||||||
int retry_time = atoi(m_parser.header("retry-after").c_str());
|
int retry_time = atoi(m_parser.header("retry-after").c_str());
|
||||||
if (retry_time <= 0) retry_time = m_ses.settings().urlseed_wait_retry;
|
if (retry_time <= 0) retry_time = m_ses.settings().urlseed_wait_retry;
|
||||||
// temporarily unavailable, retry later
|
// temporarily unavailable, retry later
|
||||||
|
@ -540,6 +543,7 @@ namespace libtorrent
|
||||||
TORRENT_ASSERT(!m_file_requests.empty());
|
TORRENT_ASSERT(!m_file_requests.empty());
|
||||||
int file_index = m_file_requests.front();
|
int file_index = m_file_requests.front();
|
||||||
|
|
||||||
|
// TODO: 2 create a mapping of file-index to redirection URLs. Use that to form URLs instead. Support to reconnect to a new server without destructing this peer_connection
|
||||||
torrent_info const& info = t->torrent_file();
|
torrent_info const& info = t->torrent_file();
|
||||||
std::string path = info.orig_files().file_path(file_index);
|
std::string path = info.orig_files().file_path(file_index);
|
||||||
#ifdef TORRENT_WINDOWS
|
#ifdef TORRENT_WINDOWS
|
||||||
|
|
Loading…
Reference in New Issue