forked from premiere/premiere-libtorrent
fixed potential hang issue when receiving faster than we can handle the incoming messages
This commit is contained in:
parent
2ac1e69205
commit
18a3d545b0
|
@ -561,11 +561,11 @@ namespace libtorrent
|
|||
size_type downloaded_since_unchoke() const
|
||||
{ return m_statistics.total_payload_download() - m_downloaded_at_last_unchoke; }
|
||||
|
||||
void setup_receive();
|
||||
enum sync_t { read_async, read_sync };
|
||||
void setup_receive(sync_t sync = read_sync);
|
||||
|
||||
protected:
|
||||
|
||||
enum sync_t { read_async, read_sync };
|
||||
size_t try_read(sync_t s, error_code& ec);
|
||||
|
||||
virtual void get_specific_peer_info(peer_info& p) const = 0;
|
||||
|
@ -966,6 +966,10 @@ namespace libtorrent
|
|||
// requesting too many pieces while being choked
|
||||
boost::uint8_t m_choke_rejects;
|
||||
|
||||
// counts the number of recursive calls to on_receive_data
|
||||
// used to limit recursion
|
||||
boost::uint8_t m_read_recurse:5;
|
||||
|
||||
// if this is true, the disconnection
|
||||
// timestamp is not updated when the connection
|
||||
// is closed. This means the time until we can
|
||||
|
|
|
@ -129,6 +129,7 @@ namespace libtorrent
|
|||
, m_prefer_whole_pieces(0)
|
||||
, m_desired_queue_size(2)
|
||||
, m_choke_rejects(0)
|
||||
, m_read_recurse(0)
|
||||
, m_fast_reconnect(false)
|
||||
, m_active(true)
|
||||
, m_peer_interested(false)
|
||||
|
@ -266,6 +267,7 @@ namespace libtorrent
|
|||
, m_prefer_whole_pieces(0)
|
||||
, m_desired_queue_size(2)
|
||||
, m_choke_rejects(0)
|
||||
, m_read_recurse(0)
|
||||
, m_fast_reconnect(false)
|
||||
, m_active(false)
|
||||
, m_peer_interested(false)
|
||||
|
@ -4332,7 +4334,7 @@ namespace libtorrent
|
|||
m_channel_state[upload_channel] = peer_info::bw_network;
|
||||
}
|
||||
|
||||
void peer_connection::setup_receive()
|
||||
void peer_connection::setup_receive(sync_t sync)
|
||||
{
|
||||
INVARIANT_CHECK;
|
||||
|
||||
|
@ -4384,21 +4386,31 @@ namespace libtorrent
|
|||
// from being at or exceeding the limit down to below the limit
|
||||
return;
|
||||
}
|
||||
|
||||
error_code ec;
|
||||
|
||||
if (sync == read_sync && m_read_recurse < 10)
|
||||
{
|
||||
size_t bytes_transferred = try_read(read_sync, ec);
|
||||
|
||||
if (ec == asio::error::would_block)
|
||||
{
|
||||
try_read(read_async, ec);
|
||||
}
|
||||
else
|
||||
if (ec != asio::error::would_block)
|
||||
{
|
||||
++m_read_recurse;
|
||||
m_channel_state[download_channel] = peer_info::bw_network;
|
||||
on_receive_data(ec, bytes_transferred);
|
||||
--m_read_recurse;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef TORRENT_VERBOSE_LOGGING
|
||||
if (m_read_recurse >= 10)
|
||||
{
|
||||
(*m_logger) << time_now_string() << " *** reached recursion limit\n";
|
||||
}
|
||||
#endif
|
||||
try_read(read_async, ec);
|
||||
}
|
||||
|
||||
size_t peer_connection::try_read(sync_t s, error_code& ec)
|
||||
{
|
||||
TORRENT_ASSERT(m_packet_size > 0);
|
||||
|
@ -4680,6 +4692,7 @@ namespace libtorrent
|
|||
}
|
||||
|
||||
int max_receive = 0;
|
||||
int num_loops = 0;
|
||||
do
|
||||
{
|
||||
#ifdef TORRENT_VERBOSE_LOGGING
|
||||
|
@ -4731,6 +4744,8 @@ namespace libtorrent
|
|||
|
||||
if (m_recv_pos >= m_soft_packet_size) m_soft_packet_size = 0;
|
||||
|
||||
if (num_loops > 20) break;
|
||||
|
||||
error_code ec;
|
||||
bytes_transferred = try_read(read_sync, ec);
|
||||
if (ec && ec != asio::error::would_block)
|
||||
|
@ -4741,6 +4756,7 @@ namespace libtorrent
|
|||
}
|
||||
if (ec == asio::error::would_block) break;
|
||||
bytes_in_loop += bytes_transferred;
|
||||
++num_loops;
|
||||
}
|
||||
while (bytes_transferred > 0);
|
||||
|
||||
|
@ -4751,7 +4767,7 @@ namespace libtorrent
|
|||
}
|
||||
|
||||
m_statistics.trancieve_ip_packet(bytes_in_loop, m_remote.address().is_v6());
|
||||
setup_receive();
|
||||
setup_receive(read_async);
|
||||
}
|
||||
|
||||
bool peer_connection::can_write() const
|
||||
|
|
Loading…
Reference in New Issue