forked from premiere/premiere-libtorrent
Changing file priorities while checking interrupts checking.
Also, if the last file has zero priority, checking is interrupted prematurely.
This commit is contained in:
parent
02a01fa22e
commit
1c867a5026
|
@ -1,4 +1,5 @@
|
||||||
|
|
||||||
|
* fix issue where setting file/piece priority would stop checking
|
||||||
* expose post_dht_stats() to python binding
|
* expose post_dht_stats() to python binding
|
||||||
* fix backwards compatibility to downloads without partfiles
|
* fix backwards compatibility to downloads without partfiles
|
||||||
* improve part-file related error messages
|
* improve part-file related error messages
|
||||||
|
|
|
@ -87,17 +87,9 @@ TORRENT_TEST(status_timers)
|
||||||
TEST_EQUAL(st.last_scrape, -1);
|
TEST_EQUAL(st.last_scrape, -1);
|
||||||
TEST_EQUAL(st.time_since_upload, -1);
|
TEST_EQUAL(st.time_since_upload, -1);
|
||||||
|
|
||||||
// checking the torrent counts as downloading
|
// checking the torrent does not count as downloading
|
||||||
// eventually though, we've forgotten about it and go back to -1
|
|
||||||
if (since_start > 65000)
|
|
||||||
{
|
|
||||||
TEST_EQUAL(st.time_since_download, -1);
|
TEST_EQUAL(st.time_since_download, -1);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
TEST_EQUAL(st.time_since_download, since_start);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
TEST_CHECK(ran_to_completion);
|
TEST_CHECK(ran_to_completion);
|
||||||
|
|
|
@ -115,6 +115,26 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
bool is_downloading_state(int st)
|
||||||
|
{
|
||||||
|
switch (st)
|
||||||
|
{
|
||||||
|
case torrent_status::checking_files:
|
||||||
|
case torrent_status::allocating:
|
||||||
|
case torrent_status::checking_resume_data:
|
||||||
|
return false;
|
||||||
|
case torrent_status::downloading_metadata:
|
||||||
|
case torrent_status::downloading:
|
||||||
|
case torrent_status::finished:
|
||||||
|
case torrent_status::seeding:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
// unexpected state
|
||||||
|
TORRENT_ASSERT_VAL(false, st);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int root2(int x)
|
int root2(int x)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
@ -4368,6 +4388,8 @@ namespace {
|
||||||
|
|
||||||
remove_time_critical_piece(index, true);
|
remove_time_critical_piece(index, true);
|
||||||
|
|
||||||
|
if (is_downloading_state(m_state))
|
||||||
|
{
|
||||||
if (is_finished()
|
if (is_finished()
|
||||||
&& m_state != torrent_status::finished
|
&& m_state != torrent_status::finished
|
||||||
&& m_state != torrent_status::seeding)
|
&& m_state != torrent_status::seeding)
|
||||||
|
@ -4386,6 +4408,7 @@ namespace {
|
||||||
if (m_share_mode)
|
if (m_share_mode)
|
||||||
recalc_share_mode();
|
recalc_share_mode();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// this is called when the piece hash is checked as correct. Note
|
// this is called when the piece hash is checked as correct. Note
|
||||||
// that the piece picker and the torrent won't necessarily consider
|
// that the piece picker and the torrent won't necessarily consider
|
||||||
|
@ -5795,6 +5818,15 @@ namespace {
|
||||||
p->update_interest();
|
p->update_interest();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!is_downloading_state(m_state))
|
||||||
|
{
|
||||||
|
#ifndef TORRENT_DISABLE_LOGGING
|
||||||
|
debug_log("*** UPDATE_PEER_INTEREST [ skipping, state: %d ]"
|
||||||
|
, int(m_state));
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef TORRENT_DISABLE_LOGGING
|
#ifndef TORRENT_DISABLE_LOGGING
|
||||||
debug_log("*** UPDATE_PEER_INTEREST [ finished: %d was_finished %d ]"
|
debug_log("*** UPDATE_PEER_INTEREST [ finished: %d was_finished %d ]"
|
||||||
, is_finished(), was_finished);
|
, is_finished(), was_finished);
|
||||||
|
@ -8108,8 +8140,7 @@ namespace {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((m_state == torrent_status::checking_files
|
if (!is_downloading_state(m_state)
|
||||||
|| m_state == torrent_status::checking_resume_data)
|
|
||||||
&& valid_metadata())
|
&& valid_metadata())
|
||||||
{
|
{
|
||||||
p->disconnect(errors::torrent_not_ready, op_bittorrent);
|
p->disconnect(errors::torrent_not_ready, op_bittorrent);
|
||||||
|
@ -8646,16 +8677,9 @@ namespace {
|
||||||
// to be in downloading state (which it will be set to shortly)
|
// to be in downloading state (which it will be set to shortly)
|
||||||
// INVARIANT_CHECK;
|
// INVARIANT_CHECK;
|
||||||
|
|
||||||
if (m_state == torrent_status::checking_resume_data
|
TORRENT_ASSERT(m_state != torrent_status::checking_resume_data
|
||||||
|| m_state == torrent_status::checking_files
|
&& m_state != torrent_status::checking_files
|
||||||
|| m_state == torrent_status::allocating)
|
&& m_state != torrent_status::allocating);
|
||||||
{
|
|
||||||
#ifndef TORRENT_DISABLE_LOGGING
|
|
||||||
debug_log("*** RESUME_DOWNLOAD [ skipping, state: %d ]"
|
|
||||||
, int(m_state));
|
|
||||||
#endif
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// we're downloading now, which means we're no longer in seed mode
|
// we're downloading now, which means we're no longer in seed mode
|
||||||
if (m_seed_mode)
|
if (m_seed_mode)
|
||||||
|
@ -11945,29 +11969,6 @@ namespace {
|
||||||
if (m_peer_list) m_peer_list->clear_peer_prio();
|
if (m_peer_list) m_peer_list->clear_peer_prio();
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
bool is_downloading_state(int st)
|
|
||||||
{
|
|
||||||
switch (st)
|
|
||||||
{
|
|
||||||
case torrent_status::checking_files:
|
|
||||||
case torrent_status::allocating:
|
|
||||||
case torrent_status::checking_resume_data:
|
|
||||||
return false;
|
|
||||||
case torrent_status::downloading_metadata:
|
|
||||||
case torrent_status::downloading:
|
|
||||||
case torrent_status::finished:
|
|
||||||
case torrent_status::seeding:
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
// unexpected state
|
|
||||||
TORRENT_ASSERT_VAL(false, st);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void torrent::stop_when_ready(bool b)
|
void torrent::stop_when_ready(bool b)
|
||||||
{
|
{
|
||||||
m_stop_when_ready = b;
|
m_stop_when_ready = b;
|
||||||
|
|
|
@ -145,9 +145,10 @@ std::map<std::string, boost::int64_t> get_counters(libtorrent::session& s)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
alert const* wait_for_alert(lt::session& ses, int type, char const* name, int num)
|
alert const* wait_for_alert(lt::session& ses, int type, char const* name, int num
|
||||||
|
, lt::time_duration timeout)
|
||||||
{
|
{
|
||||||
time_point end = libtorrent::clock_type::now() + seconds(10);
|
time_point end = libtorrent::clock_type::now() + timeout;
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
time_point now = clock_type::now();
|
time_point now = clock_type::now();
|
||||||
|
|
|
@ -65,7 +65,9 @@ EXPORT libtorrent::sha1_hash rand_hash();
|
||||||
EXPORT std::map<std::string, boost::int64_t> get_counters(libtorrent::session& s);
|
EXPORT std::map<std::string, boost::int64_t> get_counters(libtorrent::session& s);
|
||||||
|
|
||||||
EXPORT libtorrent::alert const* wait_for_alert(
|
EXPORT libtorrent::alert const* wait_for_alert(
|
||||||
libtorrent::session& ses, int type, char const* name = "", int num = 1);
|
libtorrent::session& ses, int type, char const* name = ""
|
||||||
|
, int num = 1
|
||||||
|
, lt::time_duration timeout = lt::seconds(10));
|
||||||
|
|
||||||
EXPORT void print_ses_rate(float time
|
EXPORT void print_ses_rate(float time
|
||||||
, libtorrent::torrent_status const* st1
|
, libtorrent::torrent_status const* st1
|
||||||
|
|
|
@ -34,16 +34,29 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include "libtorrent/session.hpp"
|
#include "libtorrent/session.hpp"
|
||||||
#include "test.hpp"
|
#include "test.hpp"
|
||||||
|
#include "settings.hpp"
|
||||||
#include "setup_transfer.hpp"
|
#include "setup_transfer.hpp"
|
||||||
#include "libtorrent/create_torrent.hpp"
|
#include "libtorrent/create_torrent.hpp"
|
||||||
#include "libtorrent/alert_types.hpp"
|
#include "libtorrent/alert_types.hpp"
|
||||||
#include "libtorrent/torrent_info.hpp"
|
#include "libtorrent/torrent_info.hpp"
|
||||||
#include "libtorrent/torrent_status.hpp"
|
#include "libtorrent/torrent_status.hpp"
|
||||||
|
|
||||||
static const int file_sizes[] =
|
namespace
|
||||||
{ 0, 5, 16 - 5, 16000, 17, 10, 8000, 8000, 1,1,1,1,1,100,1,1,1,1,100,1,1,1,1,1,1
|
{
|
||||||
,1,1,1,1,1,1,13,65000,34,75,2,30,400,500,23000,900,43000,400,4300,6, 4};
|
const int file_sizes[] =
|
||||||
const int num_files = sizeof(file_sizes)/sizeof(file_sizes[0]);
|
{ 0, 5, 16 - 5, 16000, 17, 10, 8000, 8000, 1,1,1,1,1,100,1,1,1,1,100,1,1,1,1,1,1
|
||||||
|
,1,1,1,1,1,1,13,65000,34,75,2,30,400,500,23000,900,43000,400,4300,6, 4 };
|
||||||
|
const int num_files = sizeof(file_sizes) / sizeof(file_sizes[0]);
|
||||||
|
|
||||||
|
bool is_checking(int const state)
|
||||||
|
{
|
||||||
|
return state == lt::torrent_status::checking_files
|
||||||
|
#ifndef TORRENT_NO_DEPRECATE
|
||||||
|
|| state == lt::torrent_status::queued_for_checking
|
||||||
|
#endif
|
||||||
|
|| state == lt::torrent_status::checking_resume_data;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
@ -63,7 +76,7 @@ enum
|
||||||
force_recheck = 8,
|
force_recheck = 8,
|
||||||
};
|
};
|
||||||
|
|
||||||
void test_checking(int flags = read_only_files)
|
void test_checking(int flags)
|
||||||
{
|
{
|
||||||
using namespace libtorrent;
|
using namespace libtorrent;
|
||||||
namespace lt = libtorrent;
|
namespace lt = libtorrent;
|
||||||
|
@ -167,20 +180,7 @@ void test_checking(int flags = read_only_files)
|
||||||
, ec.value(), ec.message().c_str());
|
, ec.value(), ec.message().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
int const mask = alert::all_categories
|
lt::session ses1(settings());
|
||||||
& ~(alert::progress_notification
|
|
||||||
| alert::performance_warning
|
|
||||||
| alert::stats_notification);
|
|
||||||
|
|
||||||
settings_pack pack;
|
|
||||||
pack.set_bool(settings_pack::enable_lsd, false);
|
|
||||||
pack.set_bool(settings_pack::enable_natpmp, false);
|
|
||||||
pack.set_bool(settings_pack::enable_upnp, false);
|
|
||||||
pack.set_bool(settings_pack::enable_dht, false);
|
|
||||||
pack.set_int(settings_pack::alert_mask, mask);
|
|
||||||
pack.set_str(settings_pack::listen_interfaces, "0.0.0.0:48000");
|
|
||||||
pack.set_int(settings_pack::max_retry_port_bind, 1000);
|
|
||||||
lt::session ses1(pack);
|
|
||||||
|
|
||||||
add_torrent_params p;
|
add_torrent_params p;
|
||||||
p.save_path = ".";
|
p.save_path = ".";
|
||||||
|
@ -216,15 +216,7 @@ void test_checking(int flags = read_only_files)
|
||||||
|
|
||||||
printf("%d %f %s\n", st.state, st.progress_ppm / 10000.f, st.errc.message().c_str());
|
printf("%d %f %s\n", st.state, st.progress_ppm / 10000.f, st.errc.message().c_str());
|
||||||
|
|
||||||
if (
|
if (!is_checking(st.state) || st.errc) break;
|
||||||
#ifndef TORRENT_NO_DEPRECATE
|
|
||||||
st.state != torrent_status::queued_for_checking &&
|
|
||||||
#endif
|
|
||||||
st.state != torrent_status::checking_files
|
|
||||||
&& st.state != torrent_status::checking_resume_data)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (st.errc) break;
|
|
||||||
test_sleep(500);
|
test_sleep(500);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -280,7 +272,7 @@ void test_checking(int flags = read_only_files)
|
||||||
|
|
||||||
TORRENT_TEST(checking)
|
TORRENT_TEST(checking)
|
||||||
{
|
{
|
||||||
test_checking();
|
test_checking(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
TORRENT_TEST(read_only_corrupt)
|
TORRENT_TEST(read_only_corrupt)
|
||||||
|
@ -308,3 +300,45 @@ TORRENT_TEST(force_recheck)
|
||||||
test_checking(force_recheck);
|
test_checking(force_recheck);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TORRENT_TEST(discrete_checking)
|
||||||
|
{
|
||||||
|
using namespace lt;
|
||||||
|
printf("\n==== TEST CHECKING discrete =====\n\n");
|
||||||
|
error_code ec;
|
||||||
|
create_directory("test_torrent_dir", ec);
|
||||||
|
if (ec) printf("ERROR: creating directory test_torrent_dir: (%d) %s\n", ec.value(), ec.message().c_str());
|
||||||
|
|
||||||
|
int const megabyte = 0x100000;
|
||||||
|
int const piece_size = 2 * megabyte;
|
||||||
|
int const file_sizes[] = { 9 * megabyte, 4 * megabyte };
|
||||||
|
int const num_files = sizeof(file_sizes) / sizeof(file_sizes[0]);
|
||||||
|
|
||||||
|
file_storage fs;
|
||||||
|
create_random_files("test_torrent_dir", file_sizes, num_files, &fs);
|
||||||
|
lt::create_torrent t(fs, piece_size, 0, lt::create_torrent::optimize_alignment);
|
||||||
|
set_piece_hashes(t, ".", ec);
|
||||||
|
if (ec) printf("ERROR: set_piece_hashes: (%d) %s\n", ec.value(), ec.message().c_str());
|
||||||
|
|
||||||
|
std::vector<char> buf;
|
||||||
|
bencode(std::back_inserter(buf), t.generate());
|
||||||
|
boost::shared_ptr<torrent_info> ti(new torrent_info(&buf[0], buf.size(), ec));
|
||||||
|
printf("generated torrent: %s test_torrent_dir\n", to_hex(ti->info_hash().to_string()).c_str());
|
||||||
|
TEST_EQUAL(ti->num_files(), 3);
|
||||||
|
{
|
||||||
|
session ses1(settings());
|
||||||
|
add_torrent_params p;
|
||||||
|
p.file_priorities.resize(ti->num_files());
|
||||||
|
p.file_priorities[0] = 1;
|
||||||
|
p.save_path = ".";
|
||||||
|
p.ti = ti;
|
||||||
|
torrent_handle tor1 = ses1.add_torrent(p, ec);
|
||||||
|
// change the priority of a file while checking and make sure it doesn't interrupt the checking.
|
||||||
|
std::vector<int> prio(ti->num_files(), 0);
|
||||||
|
prio[2] = 1;
|
||||||
|
tor1.prioritize_files(prio);
|
||||||
|
TEST_CHECK(wait_for_alert(ses1, torrent_checked_alert::alert_type, "torrent checked", 1, seconds(50)));
|
||||||
|
TEST_CHECK(tor1.status(0).is_seeding);
|
||||||
|
}
|
||||||
|
remove_all("test_torrent_dir", ec);
|
||||||
|
if (ec) fprintf(stdout, "ERROR: removing test_torrent_dir: (%d) %s\n", ec.value(), ec.message().c_str());
|
||||||
|
}
|
||||||
|
|
|
@ -417,6 +417,8 @@ void test_queue(add_torrent_params p)
|
||||||
torrents.push_back(ses.add_torrent(p));
|
torrents.push_back(ses.add_torrent(p));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
print_alerts(ses, "ses");
|
||||||
|
|
||||||
std::vector<int> pieces = torrents[5].piece_priorities();
|
std::vector<int> pieces = torrents[5].piece_priorities();
|
||||||
std::vector<std::pair<int, int> > piece_prios;
|
std::vector<std::pair<int, int> > piece_prios;
|
||||||
for (int i = 0; i < int(pieces.size()); ++i) {
|
for (int i = 0; i < int(pieces.size()); ++i) {
|
||||||
|
@ -425,6 +427,8 @@ void test_queue(add_torrent_params p)
|
||||||
torrents[5].prioritize_pieces(piece_prios);
|
torrents[5].prioritize_pieces(piece_prios);
|
||||||
torrent_handle finished = torrents[5];
|
torrent_handle finished = torrents[5];
|
||||||
|
|
||||||
|
wait_for_alert(ses, torrent_finished_alert::alert_type, "ses");
|
||||||
|
|
||||||
// add_torrent should be ordered
|
// add_torrent should be ordered
|
||||||
TEST_EQUAL(finished.queue_position(), -1);
|
TEST_EQUAL(finished.queue_position(), -1);
|
||||||
TEST_EQUAL(torrents[0].queue_position(), 0);
|
TEST_EQUAL(torrents[0].queue_position(), 0);
|
||||||
|
|
Loading…
Reference in New Issue