fix graceful pause issue. peers regularly check whether they should disconnect or not

This commit is contained in:
arvidn 2015-12-04 01:08:01 -05:00
parent 470e8dc20a
commit cc3b064cff
4 changed files with 39 additions and 22 deletions

View File

@ -813,6 +813,7 @@ namespace libtorrent
, peer_request r, boost::shared_ptr<torrent> t);
void on_seed_mode_hashed(disk_io_job const* j);
int request_timeout() const;
void check_graceful_pause();
int wanted_transfer(int channel);
int request_bandwidth(int channel, int bytes = 0);

View File

@ -1234,13 +1234,14 @@ namespace libtorrent
}
if (t->is_paused()
&& t->is_auto_managed()
&& m_settings.get_bool(settings_pack::incoming_starts_queued_torrents)
&& !t->is_aborted())
{
t->resume();
}
if (t->is_paused() || t->is_aborted())
if (t->is_paused() || t->is_aborted() || t->graceful_pause())
{
// paused torrents will not accept
// incoming connections unless they are auto managed
@ -1510,6 +1511,9 @@ namespace libtorrent
m_suggested_pieces.erase(i);
}
check_graceful_pause();
if (is_disconnecting()) return;
if (m_request_queue.empty() && m_download_queue.size() < 2)
{
if (request_a_block(*t, *this))
@ -2942,6 +2946,8 @@ namespace libtorrent
t->verify_piece(p.piece);
}
check_graceful_pause();
if (is_disconnecting()) return;
if (request_a_block(*t, *this))
@ -2949,6 +2955,24 @@ namespace libtorrent
send_block_requests();
}
void peer_connection::check_graceful_pause()
{
// TODO: 3 instead of having to ask the torrent whether it's in graceful
// pause mode or not, the peers should keep that state (and the torrent
// should update them when it enters graceful pause). When a peer enters
// graceful pause mode, it should cancel all outstanding requests and
// clear its request queue.
boost::shared_ptr<torrent> t = m_torrent.lock();
if (!t || !t->graceful_pause()) return;
if (m_outstanding_bytes > 0) return;
#ifndef TORRENT_DISABLE_LOGGING
peer_log(peer_log_alert::info, "GRACEFUL_PAUSE", "NO MORE DOWNLOAD");
#endif
disconnect(errors::torrent_paused, op_bittorrent);
}
void peer_connection::on_disk_write_complete(disk_io_job const* j
, peer_request p, boost::shared_ptr<torrent> t)
{
@ -3803,23 +3827,9 @@ namespace libtorrent
if (m_disconnecting) return;
if (t->graceful_pause() && m_outstanding_bytes == 0)
{
#ifndef TORRENT_DISABLE_LOGGING
peer_log(peer_log_alert::info, "GRACEFUL_PAUSE", "NO MORE DOWNLOAD");
#endif
disconnect(errors::torrent_paused, op_bittorrent);
// if this was the last connection, post the alert
// TODO: it would be nice if none of this logic would leak outside of
// the torrent object)
if (t->num_peers() == 0)
{
if (t->alerts().should_post<torrent_paused_alert>())
t->alerts().emplace_alert<torrent_paused_alert>(t->get_handle());
}
return;
}
// TODO: 3 once peers are properly put in graceful pause mode, they can
// cancel all outstanding requests and this test can be removed.
if (t->graceful_pause()) return;
// we can't download pieces in these states
if (t->state() == torrent_status::checking_files
@ -6127,6 +6137,9 @@ namespace libtorrent
if (m_extension_outstanding_bytes > 0)
m_extension_outstanding_bytes -= (std::min)(m_extension_outstanding_bytes, int(bytes_transferred));
check_graceful_pause();
if (m_disconnecting) return;
int num_loops = 0;
do
{

View File

@ -73,6 +73,9 @@ namespace libtorrent
// initialized after we have the metadata
if (!t.are_files_checked()) return false;
// we don't want to request more blocks while trying to gracefully pause
if (t.graceful_pause()) return false;
TORRENT_ASSERT(c.peer_info_struct() != 0 || c.type() != peer_connection::bittorrent_connection);
bool time_critical_mode = t.num_time_critical_pieces() > 0;

View File

@ -6111,6 +6111,8 @@ namespace libtorrent
// disconnected. This will clear the graceful_pause_mode and post the
// torrent_paused_alert.
TORRENT_ASSERT(is_paused());
// this will post torrent_paused alert
set_allow_peers(false);
}
@ -8180,7 +8182,7 @@ namespace libtorrent
if (m_connections.size() >= m_max_connections) return false;
// if we're paused, obviously we're not connecting to peers
if (is_paused() || m_abort) return false;
if (is_paused() || m_abort || m_graceful_pause_mode) return false;
if ((m_state == torrent_status::checking_files
|| m_state == torrent_status::checking_resume_data)
@ -9609,7 +9611,7 @@ namespace libtorrent
INVARIANT_CHECK;
if (!m_allow_peers) return;
if (!graceful) set_allow_peers(false);
set_allow_peers(graceful ? true : false, graceful);
m_announce_to_dht = false;
m_announce_to_trackers = false;
@ -9619,11 +9621,9 @@ namespace libtorrent
set_need_save_resume();
state_updated();
m_graceful_pause_mode = graceful;
update_gauge();
update_want_peers();
update_want_scrape();
}
void torrent::do_pause()