forked from premiere/premiere-libtorrent
Merge pull request #309 from arvidn/graceful-pause-fix
fix graceful pause issue.
This commit is contained in:
commit
c1cb1393fb
|
@ -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);
|
||||
|
|
|
@ -85,3 +85,13 @@ TORRENT_TEST(shutdown)
|
|||
simulate_swarm(early_shutdown);
|
||||
}
|
||||
|
||||
// TODO: the swarm_suite is probably not a very good abstraction, it's not
|
||||
// configurable enough.
|
||||
|
||||
// TODO: add test that makes sure a torrent in graceful pause mode won't make
|
||||
// outgoing connections
|
||||
// TODO: add test that makes sure a torrent in graceful pause mode won't accept
|
||||
// incoming connections
|
||||
// TODO: add test that makes sure a torrent in graceful pause mode only posts
|
||||
// the torrent_paused_alert once, and exactly once
|
||||
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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()
|
||||
|
|
Loading…
Reference in New Issue