forked from premiere/premiere-libtorrent
merged RC_1_1 into master
This commit is contained in:
commit
d080c6f532
|
@ -82,6 +82,7 @@
|
|||
* resume data no longer has timestamps of files
|
||||
* require C++11 to build libtorrent
|
||||
|
||||
* fix issue where setting file/piece priority would stop checking
|
||||
* expose post_dht_stats() to python binding
|
||||
* fix backwards compatibility to downloads without partfiles
|
||||
* improve part-file related error messages
|
||||
|
|
103
src/torrent.cpp
103
src/torrent.cpp
|
@ -109,6 +109,28 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
using namespace std::placeholders;
|
||||
|
||||
namespace libtorrent {
|
||||
namespace {
|
||||
|
||||
bool is_downloading_state(int const 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_FAIL_VAL(st);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} // anonymous namespace
|
||||
|
||||
web_seed_t::web_seed_t(web_seed_entry const& wse)
|
||||
: web_seed_entry(wse)
|
||||
|
@ -3892,23 +3914,26 @@ namespace libtorrent {
|
|||
|
||||
remove_time_critical_piece(index, true);
|
||||
|
||||
if (m_state != torrent_status::finished
|
||||
&& m_state != torrent_status::seeding
|
||||
&& is_finished())
|
||||
if (is_downloading_state(m_state))
|
||||
{
|
||||
// torrent finished
|
||||
// i.e. all the pieces we're interested in have
|
||||
// been downloaded. Release the files (they will open
|
||||
// in read only mode if needed)
|
||||
finished();
|
||||
// if we just became a seed, picker is now invalid, since it
|
||||
// is deallocated by the torrent once it starts seeding
|
||||
if (m_state != torrent_status::finished
|
||||
&& m_state != torrent_status::seeding
|
||||
&& is_finished())
|
||||
{
|
||||
// torrent finished
|
||||
// i.e. all the pieces we're interested in have
|
||||
// been downloaded. Release the files (they will open
|
||||
// in read only mode if needed)
|
||||
finished();
|
||||
// if we just became a seed, picker is now invalid, since it
|
||||
// is deallocated by the torrent once it starts seeding
|
||||
}
|
||||
|
||||
m_last_download = aux::time_now32();
|
||||
|
||||
if (m_share_mode)
|
||||
recalc_share_mode();
|
||||
}
|
||||
|
||||
m_last_download = aux::time_now32();
|
||||
|
||||
if (m_share_mode)
|
||||
recalc_share_mode();
|
||||
}
|
||||
|
||||
// this is called when the piece hash is checked as correct. Note
|
||||
|
@ -5138,6 +5163,15 @@ namespace libtorrent {
|
|||
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
|
||||
if (should_log())
|
||||
{
|
||||
|
@ -6820,8 +6854,7 @@ namespace libtorrent {
|
|||
return false;
|
||||
}
|
||||
|
||||
if ((m_state == torrent_status::checking_files
|
||||
|| m_state == torrent_status::checking_resume_data)
|
||||
if (!is_downloading_state(m_state)
|
||||
&& valid_metadata())
|
||||
{
|
||||
p->disconnect(errors::torrent_not_ready, operation_t::bittorrent);
|
||||
|
@ -7341,16 +7374,9 @@ namespace libtorrent {
|
|||
// to be in downloading state (which it will be set to shortly)
|
||||
// INVARIANT_CHECK;
|
||||
|
||||
if (m_state == torrent_status::checking_resume_data
|
||||
|| m_state == torrent_status::checking_files
|
||||
|| m_state == torrent_status::allocating)
|
||||
{
|
||||
#ifndef TORRENT_DISABLE_LOGGING
|
||||
debug_log("*** RESUME_DOWNLOAD [ skipping, state: %d ]"
|
||||
, int(m_state));
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
TORRENT_ASSERT(m_state != torrent_status::checking_resume_data
|
||||
&& m_state != torrent_status::checking_files
|
||||
&& m_state != torrent_status::allocating);
|
||||
|
||||
// we're downloading now, which means we're no longer in seed mode
|
||||
if (m_seed_mode)
|
||||
|
@ -10436,29 +10462,6 @@ namespace libtorrent {
|
|||
if (m_peer_list) m_peer_list->clear_peer_prio();
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
bool is_downloading_state(int const 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_FAIL_VAL(st);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void torrent::stop_when_ready(bool const b)
|
||||
{
|
||||
m_stop_when_ready = b;
|
||||
|
|
|
@ -168,8 +168,9 @@ bool should_print(lt::alert* a)
|
|||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
alert const* wait_for_alert(lt::session& ses, int type, char const* name
|
||||
, pop_alerts const p)
|
||||
, pop_alerts const p, lt::time_duration timeout)
|
||||
{
|
||||
// we pop alerts in batches, but we wait for individual messages. This is a
|
||||
// cache to keep around alerts that came *after* the one we're waiting for.
|
||||
|
@ -178,7 +179,8 @@ alert const* wait_for_alert(lt::session& ses, int type, char const* name
|
|||
static std::map<lt::session*, std::vector<alert*>> cache;
|
||||
auto& alerts = cache[&ses];
|
||||
|
||||
time_point const end_time = lt::clock_type::now() + seconds(10);
|
||||
time_point const end_time = lt::clock_type::now() + timeout;
|
||||
|
||||
while (true)
|
||||
{
|
||||
time_point now = clock_type::now();
|
||||
|
|
|
@ -71,7 +71,8 @@ enum class pop_alerts { pop_all, cache_alerts };
|
|||
|
||||
EXPORT lt::alert const* wait_for_alert(
|
||||
lt::session& ses, int type, char const* name = ""
|
||||
, pop_alerts const p = pop_alerts::pop_all);
|
||||
, pop_alerts const p = pop_alerts::pop_all
|
||||
, lt::time_duration timeout = lt::seconds(10));
|
||||
|
||||
EXPORT void print_ses_rate(float time
|
||||
, lt::torrent_status const* st1
|
||||
|
|
|
@ -34,7 +34,9 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#include "libtorrent/session.hpp"
|
||||
#include "test.hpp"
|
||||
#include "settings.hpp"
|
||||
#include "setup_transfer.hpp"
|
||||
#include "test_utils.hpp"
|
||||
#include "libtorrent/create_torrent.hpp"
|
||||
#include "libtorrent/alert_types.hpp"
|
||||
#include "libtorrent/torrent_info.hpp"
|
||||
|
@ -44,10 +46,17 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
namespace {
|
||||
|
||||
static const int file_sizes[] =
|
||||
{ 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]);
|
||||
namespace
|
||||
{
|
||||
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
|
||||
{
|
||||
|
@ -67,7 +76,7 @@ enum
|
|||
force_recheck = 8,
|
||||
};
|
||||
|
||||
void test_checking(int flags = read_only_files)
|
||||
void test_checking(int flags)
|
||||
{
|
||||
using namespace lt;
|
||||
|
||||
|
@ -86,6 +95,11 @@ void test_checking(int flags = read_only_files)
|
|||
std::srand(10);
|
||||
int piece_size = 0x4000;
|
||||
|
||||
const int file_sizes[] =
|
||||
{ 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]);
|
||||
|
||||
create_random_files("test_torrent_dir", file_sizes, num_files, &fs);
|
||||
|
||||
lt::create_torrent t(fs, piece_size, 0x4000
|
||||
|
@ -169,20 +183,7 @@ void test_checking(int flags = read_only_files)
|
|||
, ec.value(), ec.message().c_str());
|
||||
}
|
||||
|
||||
auto const mask = alert::all_categories
|
||||
& ~(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);
|
||||
lt::session ses1(settings());
|
||||
|
||||
add_torrent_params p;
|
||||
p.save_path = ".";
|
||||
|
@ -218,15 +219,7 @@ void test_checking(int flags = read_only_files)
|
|||
|
||||
std::printf("%d %f %s\n", st.state, st.progress_ppm / 10000.0, st.errc.message().c_str());
|
||||
|
||||
if (
|
||||
#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;
|
||||
if (!is_checking(st.state) || st.errc) break;
|
||||
std::this_thread::sleep_for(lt::milliseconds(500));
|
||||
}
|
||||
|
||||
|
@ -284,7 +277,7 @@ void test_checking(int flags = read_only_files)
|
|||
|
||||
TORRENT_TEST(checking)
|
||||
{
|
||||
test_checking();
|
||||
test_checking(0);
|
||||
}
|
||||
|
||||
TORRENT_TEST(read_only_corrupt)
|
||||
|
@ -311,3 +304,47 @@ TORRENT_TEST(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, 3 * 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, 1, 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());
|
||||
auto ti = std::make_shared<torrent_info>(buf, ec, from_span);
|
||||
printf("generated torrent: %s test_torrent_dir\n", aux::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(std::size_t(ti->num_files()));
|
||||
p.file_priorities[0] = 1_pri;
|
||||
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<download_priority_t> prio(std::size_t(ti->num_files()), 0_pri);
|
||||
prio[2] = 1_pri;
|
||||
tor1.prioritize_files(prio);
|
||||
TEST_CHECK(wait_for_alert(ses1, torrent_checked_alert::alert_type
|
||||
, "torrent checked", pop_alerts::pop_all, seconds(50)));
|
||||
TEST_CHECK(tor1.status({}).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());
|
||||
}
|
||||
|
|
|
@ -490,11 +490,15 @@ void test_queue(add_torrent_params)
|
|||
torrents.push_back(ses.add_torrent(std::move(p)));
|
||||
}
|
||||
|
||||
print_alerts(ses, "ses");
|
||||
|
||||
std::vector<download_priority_t> pieces(
|
||||
std::size_t(torrents[5].torrent_file()->num_pieces()), 0_pri);
|
||||
torrents[5].prioritize_pieces(pieces);
|
||||
torrent_handle finished = torrents[5];
|
||||
|
||||
wait_for_alert(ses, torrent_finished_alert::alert_type, "ses");
|
||||
|
||||
// add_torrent should be ordered
|
||||
TEST_EQUAL(finished.queue_position(), no_pos);
|
||||
TEST_EQUAL(torrents[0].queue_position(), queue_position_t{0});
|
||||
|
|
Loading…
Reference in New Issue