fixed issue with queued resume data saving, and fixed regression in recent disk error check changes

This commit is contained in:
Arvid Norberg 2014-07-21 03:03:59 +00:00
parent c519968aa4
commit 79a2744fa8
7 changed files with 60 additions and 34 deletions

View File

@ -57,8 +57,8 @@ namespace libtorrent {
void post_alert(const alert& alert_);
void post_alert_ptr(alert* alert_);
bool pending() const;
std::auto_ptr<alert> get();
void get_all(std::deque<alert*>* alerts);
std::auto_ptr<alert> get(int& num_resume);
void get_all(std::deque<alert*>* alerts, int& num_resume);
template <class T>
bool should_post() const
@ -88,6 +88,8 @@ namespace libtorrent {
void set_dispatch_function(boost::function<void(std::auto_ptr<alert>)> const&);
int num_queued_resume() const;
#ifndef TORRENT_DISABLE_EXTENSIONS
void add_extension(boost::shared_ptr<plugin> ext);
#endif
@ -102,6 +104,9 @@ namespace libtorrent {
size_t m_queue_size_limit;
boost::function<void(std::auto_ptr<alert>)> m_dispatch;
// the number of resume data alerts in the alert queue
int m_num_queued_resume;
#ifndef TORRENT_DISABLE_EXTENSIONS
typedef std::list<boost::shared_ptr<plugin> > ses_extension_list_t;
ses_extension_list_t m_ses_extensions;

View File

@ -250,7 +250,7 @@ namespace libtorrent
void queue_async_resume_data(boost::shared_ptr<torrent> const& t);
void done_async_resume();
void async_resume_dispatched(bool all);
void async_resume_dispatched(int num_popped_resume);
void init_peer_class_filter(bool unlimited_local);
@ -835,10 +835,6 @@ namespace libtorrent
// outstanding
int m_num_save_resume;
// the number of resume data job that are complete and are waiting
// to be reaped in the alert queue
int m_num_queued_resume;
// peer connections are put here when disconnected to avoid
// race conditions with the disk thread. It's important that
// peer connections are destructed from the network thread,

View File

@ -287,8 +287,8 @@ namespace libtorrent
//
// returns one of:
// | no_error = 0
// | need_full_check = -1
// | fatal_disk_error = -2
// | fatal_disk_error = -1
// | need_full_check = -2
// | file_exist = -4
virtual int move_storage(std::string const& save_path, int flags
, storage_error& ec) = 0;

View File

@ -44,6 +44,7 @@ namespace libtorrent
alert_manager::alert_manager(int queue_limit, boost::uint32_t alert_mask)
: m_alert_mask(alert_mask)
, m_queue_size_limit(queue_limit)
, m_num_queued_resume(0)
{}
alert_manager::~alert_manager()
@ -59,6 +60,12 @@ namespace libtorrent
}
}
int alert_manager::num_queued_resume() const
{
mutex::scoped_lock lock(m_mutex);
return m_num_queued_resume;
}
alert const* alert_manager::wait_for_alert(time_duration max_wait)
{
mutex::scoped_lock lock(m_mutex);
@ -137,6 +144,11 @@ namespace libtorrent
void alert_manager::post_impl(std::auto_ptr<alert>& alert_
, mutex::scoped_lock& /* l */)
{
if (alert_cast<save_resume_data_failed_alert>(alert_.get())
|| alert_cast<save_resume_data_alert>(alert_.get()))
++m_num_queued_resume;
if (m_dispatch)
{
TORRENT_ASSERT(m_alerts.empty());
@ -159,21 +171,37 @@ namespace libtorrent
}
#endif
std::auto_ptr<alert> alert_manager::get()
std::auto_ptr<alert> alert_manager::get(int& num_resume)
{
mutex::scoped_lock lock(m_mutex);
if (m_alerts.empty())
return std::auto_ptr<alert>(0);
TORRENT_ASSERT(m_num_queued_resume <= int(m_alerts.size()));
alert* result = m_alerts.front();
m_alerts.pop_front();
if (alert_cast<save_resume_data_failed_alert>(result)
|| alert_cast<save_resume_data_alert>(result))
{
--m_num_queued_resume;
num_resume = 1;
}
else
{
num_resume = 0;
}
return std::auto_ptr<alert>(result);
}
void alert_manager::get_all(std::deque<alert*>* alerts)
void alert_manager::get_all(std::deque<alert*>* alerts, int& num_resume)
{
mutex::scoped_lock lock(m_mutex);
TORRENT_ASSERT(m_num_queued_resume <= int(m_alerts.size()));
num_resume = m_num_queued_resume;
m_num_queued_resume = 0;
if (m_alerts.empty()) return;
m_alerts.swap(*alerts);
}

View File

@ -451,7 +451,6 @@ namespace aux {
#endif
, m_tracker_manager(*this)
, m_num_save_resume(0)
, m_num_queued_resume(0)
, m_work(io_service::work(m_io_service))
, m_max_queue_pos(-1)
, m_key(0)
@ -1118,7 +1117,7 @@ namespace aux {
int loaded_limit = m_settings.get_int(settings_pack::active_loaded_limit);
if (m_num_save_resume + m_num_queued_resume >= loaded_limit
if (m_num_save_resume + m_alerts.num_queued_resume() >= loaded_limit
&& m_user_load_torrent
&& loaded_limit > 0)
{
@ -1142,28 +1141,19 @@ namespace aux {
{
TORRENT_ASSERT(m_num_save_resume > 0);
--m_num_save_resume;
++m_num_queued_resume;
}
// this is called when one or all save resume alerts are
// popped off the alert queue
void session_impl::async_resume_dispatched(bool all)
void session_impl::async_resume_dispatched(int num_popped_resume)
{
INVARIANT_CHECK;
if (all)
{
m_num_queued_resume = 0;
}
else
{
TORRENT_ASSERT(m_num_queued_resume > 0);
--m_num_queued_resume;
}
int num_queued_resume = m_alerts.num_queued_resume();
int loaded_limit = m_settings.get_int(settings_pack::active_loaded_limit);
while (!m_save_resume_queue.empty()
&& (m_num_save_resume + m_num_queued_resume < loaded_limit
&& (m_num_save_resume + num_queued_resume < loaded_limit
|| loaded_limit == 0))
{
boost::shared_ptr<torrent> t = m_save_resume_queue.front();
@ -7446,14 +7436,14 @@ retry:
// not the network thread
std::auto_ptr<alert> session_impl::pop_alert()
{
std::auto_ptr<alert> ret = m_alerts.get();
if (alert_cast<save_resume_data_failed_alert>(ret.get())
|| alert_cast<save_resume_data_alert>(ret.get()))
int num_resume = 0;
std::auto_ptr<alert> ret = m_alerts.get(num_resume);
if (num_resume > 0)
{
// we can only issue more resume data jobs from
// the network thread
m_io_service.post(boost::bind(&session_impl::async_resume_dispatched
, this, false));
, this, num_resume));
}
return ret;
}
@ -7462,11 +7452,12 @@ retry:
// not the network thread
void session_impl::pop_alerts(std::deque<alert*>* alerts)
{
m_alerts.get_all(alerts);
int num_resume = 0;
m_alerts.get_all(alerts, num_resume);
// we can only issue more resume data jobs from
// the network thread
m_io_service.post(boost::bind(&session_impl::async_resume_dispatched
, this, true));
, this, num_resume));
}
alert const* session_impl::wait_for_alert(time_duration max_wait)

View File

@ -2422,7 +2422,7 @@ namespace libtorrent
dec_refcount("force_recheck");
state_updated();
if (j->ret < 0)
if (j->ret == piece_manager::fatal_disk_error)
{
handle_disk_error(j);
return;

View File

@ -245,8 +245,12 @@ void test_transfer(settings_pack const& sett)
test_sleep(100);
}
TEST_CHECK(st2.state != torrent_status::checking_files);
if (st2.state != torrent_status::checking_files) std::cerr << "recheck complete" << std::endl;
TEST_EQUAL(st2.state, torrent_status::finished);
if (st2.state != torrent_status::finished)
return;
std::cerr << "recheck complete" << std::endl;
priorities2 = tor2.piece_priorities();
std::copy(priorities2.begin(), priorities2.end(), std::ostream_iterator<int>(std::cerr, ", "));
@ -291,6 +295,8 @@ void test_transfer(settings_pack const& sett)
}
TEST_CHECK(resume_data.size());
fprintf(stderr, "%s\n", resume_data.data());
ses2.remove_torrent(tor2);
std::cerr << "removed" << std::endl;