fix updating of is_finished torrent status, when changing piece priorities

This commit is contained in:
arvidn 2019-09-04 09:55:50 +02:00 committed by Arvid Norberg
parent a3440e54bb
commit 9b1607a63c
7 changed files with 52 additions and 12 deletions

View File

@ -1,5 +1,6 @@
1.2.2 release
* fix updating of is_finished torrent status, when changing piece priorities
* fix regression in &left= reporting when adding a seeding torrent
* fix integer overflow in http parser
* improve sanitation of symlinks, to support more complex link targets

View File

@ -434,8 +434,24 @@ namespace libtorrent {
// been flushed to disk yet)
int num_passed() const { return m_num_passed; }
// return true if we have all the pieces we wanted
bool is_finished() const { return m_num_have - m_num_have_filtered == num_pieces() - m_num_filtered; }
// return true if all the pieces we want have passed the hash check (but
// may not have been written to disk yet)
bool is_finished() const
{
// this expression warrants some explanation:
// if the number of pieces we *want* to download
// is less than or (more likely) equal to the number of pieces that
// have passed the hash check (discounting the pieces that have passed
// the check but then had their priority set to 0). Then we're
// finished. Note that any piece we *have* implies it's both passed the
// hash check *and* been written to disk.
// num_pieces() - m_num_filtered - m_num_have_filtered
// <= (num_passed() - m_num_have_filtered)
// this can be simplified. Note how m_num_have_filtered appears on both
// side of the equation.
//
return num_pieces() - m_num_filtered <= num_passed();
}
bool is_seeding() const { return m_num_have == num_pieces(); }

View File

@ -146,6 +146,15 @@ bool is_seed(lt::session& ses)
return h.status().is_seeding;
}
bool is_finished(lt::session& ses)
{
auto handles = ses.get_torrents();
TEST_EQUAL(handles.size(), 1);
if (handles.empty()) return false;
auto h = handles[0];
return h.status().is_finished;
}
int completed_pieces(lt::session& ses)
{
auto handles = ses.get_torrents();

View File

@ -78,6 +78,7 @@ void setup_swarm(int num_nodes
bool has_metadata(lt::session& ses);
bool is_seed(lt::session& ses);
bool is_finished(lt::session& ses);
int completed_pieces(lt::session& ses);
void add_extra_peers(lt::session& ses);
lt::torrent_status get_status(lt::session& ses);

View File

@ -388,3 +388,24 @@ TORRENT_TEST(piece_extent_affinity)
);
}
TORRENT_TEST(is_finished)
{
using namespace lt;
run_test(
[](lt::session&, lt::session&) {},
[](lt::session& ses, lt::alert const* a) {
if (alert_cast<piece_finished_alert>(a))
{
TEST_EQUAL(is_finished(ses), false);
std::vector<download_priority_t> prio(4, dont_download);
ses.get_torrents()[0].prioritize_files(prio);
TEST_EQUAL(is_finished(ses), true);
}
},
[](std::shared_ptr<lt::session> ses[2]) {
TEST_EQUAL(is_finished(*ses[0]), true);
TEST_EQUAL(is_finished(*ses[1]), true);
}
);
}

View File

@ -7604,12 +7604,7 @@ bool is_downloading_state(int const st)
bool torrent::is_finished() const
{
if (is_seed()) return true;
// this is slightly different from m_picker->is_finished()
// because any piece that has *passed* is considered here,
// which may be more than the piece we *have* (i.e. written to disk)
return valid_metadata() && has_picker()
&& m_picker->want().num_pieces - m_picker->num_passed() == 0;
return valid_metadata() && has_picker() && m_picker->is_finished();
}
bool torrent::is_inactive() const

View File

@ -203,8 +203,7 @@ TORRENT_TEST(total_wanted)
std::vector<char> tmp;
bencode(std::back_inserter(tmp), t.generate());
error_code ec;
auto info = std::make_shared<torrent_info>(
tmp, std::ref(ec), from_span);
auto info = std::make_shared<torrent_info>(tmp, std::ref(ec), from_span);
settings_pack pack = settings();
pack.set_int(settings_pack::alert_mask, alert::storage_notification);
@ -220,8 +219,6 @@ TORRENT_TEST(total_wanted)
p.file_priorities.resize(4, 0_pri);
p.file_priorities[1] = 1_pri;
p.ti = info;
torrent_handle h = ses.add_torrent(std::move(p));
torrent_status st = h.status();