fixed torrent checking race condition

This commit is contained in:
Arvid Norberg 2009-02-09 02:04:43 +00:00
parent 41ff39605b
commit fe714b4b89
2 changed files with 24 additions and 17 deletions

View File

@ -54,6 +54,8 @@ release 0.14.2
* added support for SunPro C++ compiler * added support for SunPro C++ compiler
* fixed bug where messeges sometimes could be encrypted in the * fixed bug where messeges sometimes could be encrypted in the
wrong order, for encrypted connections. wrong order, for encrypted connections.
* fixed race condition where torrents could get stuck waiting to
get checked
release 0.14.1 release 0.14.1

View File

@ -836,11 +836,9 @@ namespace libtorrent
pause(); pause();
return; return;
} }
if (!is_torrent_paused() || is_auto_managed()) set_state(torrent_status::queued_for_checking);
{ if (should_check_files())
set_state(torrent_status::queued_for_checking);
queue_torrent_check(); queue_torrent_check();
}
} }
void torrent::start_checking() void torrent::start_checking()
@ -860,6 +858,7 @@ namespace libtorrent
if (ret == piece_manager::disk_check_aborted) if (ret == piece_manager::disk_check_aborted)
{ {
dequeue_torrent_check();
return; return;
} }
if (ret == piece_manager::fatal_disk_error) if (ret == piece_manager::fatal_disk_error)
@ -890,7 +889,7 @@ namespace libtorrent
// we're done, or encounter a failure // we're done, or encounter a failure
if (ret == piece_manager::need_full_check) return; if (ret == piece_manager::need_full_check) return;
if (!m_abort) m_ses.done_checking(shared_from_this()); dequeue_torrent_check();
files_checked(); files_checked();
} }
@ -1838,6 +1837,8 @@ namespace libtorrent
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
if (m_abort) return;
m_abort = true; m_abort = true;
// if the torrent is paused, it doesn't need // if the torrent is paused, it doesn't need
// to announce with even=stopped again. // to announce with even=stopped again.
@ -1864,12 +1865,8 @@ namespace libtorrent
m_storage->abort_disk_io(); m_storage->abort_disk_io();
} }
if (m_state == torrent_status::checking_files) dequeue_torrent_check();
{
dequeue_torrent_check();
set_state(torrent_status::queued_for_checking);
}
m_owning_storage = 0; m_owning_storage = 0;
m_host_resolver.cancel(); m_host_resolver.cancel();
} }
@ -3852,7 +3849,6 @@ namespace libtorrent
session_impl::mutex_t::scoped_lock l(m_ses.m_mutex); session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);
TORRENT_ASSERT(m_torrent_file->is_valid()); TORRENT_ASSERT(m_torrent_file->is_valid());
INVARIANT_CHECK;
if (m_abort) return; if (m_abort) return;
@ -3862,6 +3858,8 @@ namespace libtorrent
if (m_state != torrent_status::finished) if (m_state != torrent_status::finished)
set_state(torrent_status::downloading); set_state(torrent_status::downloading);
INVARIANT_CHECK;
if (m_ses.m_alerts.should_post<torrent_checked_alert>()) if (m_ses.m_alerts.should_post<torrent_checked_alert>())
{ {
m_ses.m_alerts.post_alert(torrent_checked_alert( m_ses.m_alerts.post_alert(torrent_checked_alert(
@ -4004,6 +4002,8 @@ namespace libtorrent
if (!should_check_files()) if (!should_check_files())
TORRENT_ASSERT(m_state != torrent_status::checking_files); TORRENT_ASSERT(m_state != torrent_status::checking_files);
else
TORRENT_ASSERT(m_queued_for_checking);
if (!m_ses.m_queued_for_checking.empty()) if (!m_ses.m_queued_for_checking.empty())
{ {
@ -4021,7 +4021,8 @@ namespace libtorrent
} }
// the case of 2 is in the special case where one switches over from // the case of 2 is in the special case where one switches over from
// checking to complete. // checking to complete.
TORRENT_ASSERT(found_active == 1 || found_active == 2); TORRENT_ASSERT(found_active >= 1);
TORRENT_ASSERT(found_active <= 2);
TORRENT_ASSERT(found >= 1); TORRENT_ASSERT(found >= 1);
} }
@ -4440,8 +4441,9 @@ namespace libtorrent
{ {
return (m_state == torrent_status::checking_files return (m_state == torrent_status::checking_files
|| m_state == torrent_status::queued_for_checking) || m_state == torrent_status::queued_for_checking)
&& (!is_paused() || m_auto_managed) && (!m_paused || m_auto_managed)
&& m_error.empty(); && m_error.empty()
&& !m_abort;
} }
bool torrent::is_paused() const bool torrent::is_paused() const
@ -4456,8 +4458,8 @@ namespace libtorrent
if (m_paused) return; if (m_paused) return;
bool checking_files = should_check_files(); bool checking_files = should_check_files();
m_paused = true; m_paused = true;
if (m_ses.is_paused()) return; if (!m_ses.is_paused())
do_pause(); do_pause();
if (checking_files && !should_check_files()) if (checking_files && !should_check_files())
{ {
// stop checking // stop checking
@ -5001,6 +5003,9 @@ namespace libtorrent
void torrent::set_state(torrent_status::state_t s) void torrent::set_state(torrent_status::state_t s)
{ {
#ifdef TORRENT_DEBUG #ifdef TORRENT_DEBUG
if (s != torrent_status::checking_files
&& s != torrent_status::queued_for_checking)
TORRENT_ASSERT(!m_queued_for_checking);
if (s == torrent_status::seeding) if (s == torrent_status::seeding)
TORRENT_ASSERT(is_seed()); TORRENT_ASSERT(is_seed());
if (s == torrent_status::finished) if (s == torrent_status::finished)