rename async_check_fastresume to async_check_files, and make it take an add_torrent_params object instead of bencoded resume data

This commit is contained in:
arvidn 2016-02-14 15:17:32 -08:00 committed by arvidn
parent 4ef55073e3
commit 8135ea326f
10 changed files with 107 additions and 154 deletions

View File

@ -66,8 +66,8 @@ namespace libtorrent
virtual void async_release_files(piece_manager* storage
, boost::function<void(disk_io_job const*)> const& handler
= boost::function<void(disk_io_job const*)>()) = 0;
virtual void async_check_fastresume(piece_manager* storage
, bdecode_node const* resume_data
virtual void async_check_files(piece_manager* storage
, add_torrent_params const* resume_data
, std::vector<std::string>& links
, boost::function<void(disk_io_job const*)> const& handler) = 0;
#ifndef TORRENT_NO_DEPRECATE

View File

@ -54,6 +54,7 @@ namespace libtorrent
struct cached_piece_entry;
struct bdecode_node;
class torrent_info;
struct add_torrent_params;
struct block_cache_reference
{
@ -156,8 +157,7 @@ namespace libtorrent
{
char* disk_block;
char* string;
entry* resume_data;
bdecode_node const* check_resume_data;
add_torrent_params const* check_resume_data;
std::vector<boost::uint8_t>* priorities;
torrent_info* torrent_file;
} buffer;

View File

@ -299,60 +299,60 @@ namespace libtorrent
void async_read(piece_manager* storage, peer_request const& r
, boost::function<void(disk_io_job const*)> const& handler, void* requester
, int flags = 0);
, int flags = 0) TORRENT_OVERRIDE;
void async_write(piece_manager* storage, peer_request const& r
, disk_buffer_holder& buffer
, boost::function<void(disk_io_job const*)> const& handler
, int flags = 0);
, int flags = 0) TORRENT_OVERRIDE;
void async_hash(piece_manager* storage, int piece, int flags
, boost::function<void(disk_io_job const*)> const& handler, void* requester);
, boost::function<void(disk_io_job const*)> const& handler, void* requester) TORRENT_OVERRIDE;
void async_move_storage(piece_manager* storage, std::string const& p, int flags
, boost::function<void(disk_io_job const*)> const& handler);
, boost::function<void(disk_io_job const*)> const& handler) TORRENT_OVERRIDE;
void async_release_files(piece_manager* storage
, boost::function<void(disk_io_job const*)> const& handler
= boost::function<void(disk_io_job const*)>());
= boost::function<void(disk_io_job const*)>()) TORRENT_OVERRIDE;
void async_delete_files(piece_manager* storage
, boost::function<void(disk_io_job const*)> const& handler);
void async_check_fastresume(piece_manager* storage
, bdecode_node const* resume_data
, boost::function<void(disk_io_job const*)> const& handler) TORRENT_OVERRIDE;
void async_check_files(piece_manager* storage
, add_torrent_params const* resume_data
, std::vector<std::string>& links
, boost::function<void(disk_io_job const*)> const& handler);
, boost::function<void(disk_io_job const*)> const& handler) TORRENT_OVERRIDE;
void async_rename_file(piece_manager* storage, int index, std::string const& name
, boost::function<void(disk_io_job const*)> const& handler);
, boost::function<void(disk_io_job const*)> const& handler) TORRENT_OVERRIDE;
void async_stop_torrent(piece_manager* storage
, boost::function<void(disk_io_job const*)> const& handler);
, boost::function<void(disk_io_job const*)> const& handler) TORRENT_OVERRIDE;
void async_cache_piece(piece_manager* storage, int piece
, boost::function<void(disk_io_job const*)> const& handler);
, boost::function<void(disk_io_job const*)> const& handler) TORRENT_OVERRIDE;
#ifndef TORRENT_NO_DEPRECATE
void async_finalize_file(piece_manager* storage, int file
, boost::function<void(disk_io_job const*)> const& handler
= boost::function<void(disk_io_job const*)>());
= boost::function<void(disk_io_job const*)>()) TORRENT_OVERRIDE;
#endif
void async_flush_piece(piece_manager* storage, int piece
, boost::function<void(disk_io_job const*)> const& handler
= boost::function<void(disk_io_job const*)>());
= boost::function<void(disk_io_job const*)>()) TORRENT_OVERRIDE;
void async_set_file_priority(piece_manager* storage
, std::vector<boost::uint8_t> const& prio
, boost::function<void(disk_io_job const*)> const& handler);
, boost::function<void(disk_io_job const*)> const& handler) TORRENT_OVERRIDE;
void async_load_torrent(add_torrent_params* params
, boost::function<void(disk_io_job const*)> const& handler);
, boost::function<void(disk_io_job const*)> const& handler) TORRENT_OVERRIDE;
void async_tick_torrent(piece_manager* storage
, boost::function<void(disk_io_job const*)> const& handler);
, boost::function<void(disk_io_job const*)> const& handler) TORRENT_OVERRIDE;
void clear_read_cache(piece_manager* storage);
void clear_read_cache(piece_manager* storage) TORRENT_OVERRIDE;
void async_clear_piece(piece_manager* storage, int index
, boost::function<void(disk_io_job const*)> const& handler);
, boost::function<void(disk_io_job const*)> const& handler) TORRENT_OVERRIDE;
// this is not asynchronous and requires that the piece does not
// have any pending buffers. It's meant to be used for pieces that
// were just read and hashed and failed the hash check.
// there should be no read-operations left, and all buffers should
// be discardable
void clear_piece(piece_manager* storage, int index);
void clear_piece(piece_manager* storage, int index) TORRENT_OVERRIDE;
// implements buffer_allocator_interface
void reclaim_block(block_cache_reference ref);
void free_disk_buffer(char* buf) { m_disk_cache.free_buffer(buf); }
char* allocate_disk_buffer(char const* category)
void free_disk_buffer(char* buf) TORRENT_OVERRIDE { m_disk_cache.free_buffer(buf); }
char* allocate_disk_buffer(char const* category) TORRENT_OVERRIDE
{
bool exceed = false;
return allocate_disk_buffer(exceed, boost::shared_ptr<disk_observer>(), category);
@ -360,15 +360,15 @@ namespace libtorrent
void trigger_cache_trim();
char* allocate_disk_buffer(bool& exceeded, boost::shared_ptr<disk_observer> o
, char const* category);
char* async_allocate_disk_buffer(char const* category, boost::function<void(char*)> const& handler);
, char const* category) TORRENT_OVERRIDE;
char* async_allocate_disk_buffer(char const* category, boost::function<void(char*)> const& handler) TORRENT_OVERRIDE;
bool exceeded_cache_use() const
{ return m_disk_cache.exceeded_max_size(); }
void update_stats_counters(counters& c) const;
void update_stats_counters(counters& c) const TORRENT_OVERRIDE;
void get_cache_info(cache_status* ret, bool no_pieces = true
, piece_manager const* storage = 0) const;
, piece_manager const* storage = 0) const TORRENT_OVERRIDE;
// this submits all queued up jobs to the thread
void submit_jobs();

View File

@ -110,7 +110,7 @@ POSSIBILITY OF SUCH DAMAGE.
// virtual bool rename_file(int file, std::string const& new_name)
// { assert(false); return false; }
// virtual bool move_storage(std::string const& save_path) { return false; }
// virtual bool verify_resume_data(bdecode_node const& rd
// virtual bool verify_resume_data(add_torrent_params const& rd
// , std::vector<std::string> const* links
// , storage_error& error) { return false; }
// virtual boost::int64_t physical_offset(int piece, int offset)
@ -151,6 +151,7 @@ namespace libtorrent
struct cache_status;
namespace aux { struct session_settings; }
struct cached_piece_entry;
struct add_torrent_params;
TORRENT_EXTRA_EXPORT std::vector<std::pair<boost::int64_t, std::time_t> > get_filesizes(
file_storage const& t
@ -309,7 +310,7 @@ namespace libtorrent
// the absolute path to a file identical to the corresponding file in this
// torrent. The storage must create hard links (or copy) those files. If
// any file does not exist or is inaccessible, the disk job must fail.
virtual bool verify_resume_data(bdecode_node const& rd
virtual bool verify_resume_data(add_torrent_params const& rd
, std::vector<std::string> const* links
, storage_error& ec) = 0;
@ -419,7 +420,7 @@ namespace libtorrent
virtual void initialize(storage_error& ec) TORRENT_OVERRIDE;
virtual int move_storage(std::string const& save_path, int flags
, storage_error& ec) TORRENT_OVERRIDE;
virtual bool verify_resume_data(bdecode_node const& rd
virtual bool verify_resume_data(add_torrent_params const& rd
, std::vector<std::string> const* links
, storage_error& error) TORRENT_OVERRIDE;
virtual bool tick() TORRENT_OVERRIDE;
@ -503,7 +504,7 @@ namespace libtorrent
virtual int writev(file::iovec_t const* bufs, int num_bufs, int piece
, int offset, int flags, storage_error& ec) TORRENT_OVERRIDE;
virtual bool verify_resume_data(bdecode_node const&
virtual bool verify_resume_data(add_torrent_params const&
, std::vector<std::string> const*
, storage_error&) TORRENT_OVERRIDE { return false; }
};
@ -524,7 +525,7 @@ namespace libtorrent
, storage_error&) TORRENT_OVERRIDE {}
virtual int move_storage(std::string const& /* save_path */
, int /* flags */, storage_error&) TORRENT_OVERRIDE { return 0; }
virtual bool verify_resume_data(bdecode_node const& /* rd */
virtual bool verify_resume_data(add_torrent_params const& /* rd */
, std::vector<std::string> const* /* links */
, storage_error&) TORRENT_OVERRIDE
{ return false; }
@ -656,7 +657,7 @@ namespace libtorrent
// the error message indicates that the fast resume data was rejected
// if 'fatal_disk_error' is returned, the error message indicates what
// when wrong in the disk access
int check_fastresume(bdecode_node const& rd
int check_fastresume(add_torrent_params const& rd
, std::vector<std::string> const* links
, storage_error& error);

View File

@ -1879,8 +1879,8 @@ namespace libtorrent
add_completed_jobs(completed_jobs);
}
void disk_io_thread::async_check_fastresume(piece_manager* storage
, bdecode_node const* resume_data
void disk_io_thread::async_check_files(piece_manager* storage
, add_torrent_params const* resume_data
, std::vector<std::string>& links
, boost::function<void(disk_io_job const*)> const& handler)
{
@ -2575,8 +2575,8 @@ namespace libtorrent
// if this assert fails, something's wrong with the fence logic
TORRENT_ASSERT(j->storage->num_outstanding_jobs() == 1);
bdecode_node const* rd = j->buffer.check_resume_data;
bdecode_node tmp;
add_torrent_params const* rd = j->buffer.check_resume_data;
add_torrent_params tmp;
if (rd == NULL) rd = &tmp;
boost::scoped_ptr<std::vector<std::string> > links(j->d.links);

View File

@ -203,7 +203,7 @@ namespace libtorrent
if (!resume_data.http_seeds.empty())
{
atp.url_seeds.insert(atp.http_seeds.end()
atp.http_seeds.insert(atp.http_seeds.end()
, resume_data.http_seeds.begin()
, resume_data.http_seeds.end());
if ((resume_data.flags & add_torrent_params::flag_merge_resume_http_seeds) == 0)

View File

@ -820,19 +820,7 @@ namespace libtorrent
#endif
}
namespace
{
bool is_seed(char const* pieces, int const len)
{
for (int i = 0; i < len; ++i)
{
if ((pieces[i] & 1) == 0) return false;
}
return true;
}
}
bool default_storage::verify_resume_data(bdecode_node const& rd
bool default_storage::verify_resume_data(add_torrent_params const& rd
, std::vector<std::string> const* links
, storage_error& ec)
{
@ -873,76 +861,57 @@ namespace libtorrent
}
#endif // TORRENT_DISABLE_MUTABLE_TORRENTS
if (rd && rd.type() == bdecode_node::dict_t)
bool const seed = rd.have_pieces.all_set();
// parse have bitmask. Verify that the files we expect to have
// actually do exist
for (int i = 0; i < rd.have_pieces.size(); ++i)
{
bdecode_node pieces = rd.dict_find_string("pieces");
if (pieces && pieces.type() == bdecode_node::string_t
&& int(pieces.string_length()) == fs.num_pieces())
if (rd.have_pieces.get_bit(i) == false) continue;
std::vector<file_slice> f = fs.map_block(i, 0, 1);
TORRENT_ASSERT(!f.empty());
const int file_index = f[0].file_index;
error_code error;
boost::int64_t const size = m_stat_cache.get_filesize(f[0].file_index
, fs, m_save_path, error);
if (size < 0)
{
char const* pieces_str = pieces.string_ptr();
// TODO: this should just be a std::none_of()
bool const seed = is_seed(pieces_str, pieces.string_length());
// parse have bitmask. Verify that the files we expect to have
// actually do exist
for (int i = 0; i < fs.num_pieces(); ++i)
if (error != boost::system::errc::no_such_file_or_directory)
{
if ((pieces_str[i] & 1) == 0) continue;
std::vector<file_slice> f = fs.map_block(i, 0, 1);
TORRENT_ASSERT(!f.empty());
const int file_index = f[0].file_index;
error_code error;
boost::int64_t size = m_stat_cache.get_filesize(f[0].file_index
, fs, m_save_path, error);
if (size < 0)
{
if (error != boost::system::errc::no_such_file_or_directory)
{
ec.ec = error;
ec.file = i;
ec.operation = storage_error::stat;
return false;
}
else
{
ec.ec = errors::mismatching_file_size;
ec.file = i;
ec.operation = storage_error::stat;
return false;
}
}
if (seed && size != fs.file_size(i))
{
// the resume data indicates we're a seed, but this file has
// the wrong size. Reject the resume data
ec.ec = errors::mismatching_file_size;
ec.file = i;
ec.operation = storage_error::check_resume;
return false;
}
// OK, this file existed, good. Now, skip all remaining pieces in
// this file. We're just sanity-checking whether the files exist
// or not.
peer_request pr = fs.map_file(file_index, 0
, fs.file_size(file_index) + 1);
i = (std::max)(i + 1, pr.piece);
ec.ec = error;
ec.file = i;
ec.operation = storage_error::stat;
return false;
}
else
{
ec.ec = errors::mismatching_file_size;
ec.file = i;
ec.operation = storage_error::stat;
return false;
}
}
else
if (seed && size != fs.file_size(i))
{
ec.ec = errors::missing_pieces;
ec.file = -1;
// the resume data indicates we're a seed, but this file has
// the wrong size. Reject the resume data
ec.ec = errors::mismatching_file_size;
ec.file = i;
ec.operation = storage_error::check_resume;
return false;
}
}
// OK, this file existed, good. Now, skip all remaining pieces in
// this file. We're just sanity-checking whether the files exist
// or not.
peer_request pr = fs.map_file(file_index, 0
, fs.file_size(file_index) + 1);
i = (std::max)(i + 1, pr.piece);
}
return true;
}
@ -1484,29 +1453,14 @@ namespace libtorrent
// torrent. The storage must create hard links (or copy) those files. If
// any file does not exist or is inaccessible, the disk job must fail.
int piece_manager::check_fastresume(
bdecode_node const& rd
add_torrent_params const& rd
, std::vector<std::string> const* links
, storage_error& ec)
{
TORRENT_ASSERT(m_files.piece_length() > 0);
// if we don't have any resume data, return
if (rd.type() == bdecode_node::none_t) return check_no_fastresume(ec);
if (rd.type() != bdecode_node::dict_t)
{
ec.ec = errors::not_a_dictionary;
return check_no_fastresume(ec);
}
int block_size = (std::min)(16 * 1024, m_files.piece_length());
int blocks_per_piece = int(rd.dict_find_int_value("blocks per piece", -1));
if (blocks_per_piece != -1
&& blocks_per_piece != m_files.piece_length() / block_size)
{
ec.ec = errors::invalid_blocks_per_piece;
return check_no_fastresume(ec);
}
if (rd.have_pieces.empty()) return check_no_fastresume(ec);
if (!m_storage->verify_resume_data(rd, links, ec))
return check_no_fastresume(ec);

View File

@ -293,7 +293,7 @@ namespace libtorrent
// if there is resume data already, we don't need to trigger the initial save
// resume data
#error maybe m_need_save_resume_data should be another flag in add_torrent_params
//TODO: 4 maybe m_need_save_resume_data should be another flag in add_torrent_params
if (!p.resume_data.empty() && (p.flags & add_torrent_params::flag_override_resume_data) == 0)
m_need_save_resume_data = false;
@ -2096,15 +2096,14 @@ namespace libtorrent
#endif // TORRENT_DISABLE_MUTABLE_TORRENTS
inc_refcount("check_fastresume");
// async_check_fastresume will gut links
// TODO: 4 we need to at least pass in the have-bitfield here.
// check_fastresume should probably be renamed check_files.
m_ses.disk_thread().async_check_fastresume(
m_storage.get(), m_resume_data ? &m_resume_data->node : NULL
// async_check_files will gut links
// TODO: 4 check_fastresume should probably be renamed check_files.
m_ses.disk_thread().async_check_files(
m_storage.get(), m_add_torrent_params ? m_add_torrent_params.get() : NULL
, links, boost::bind(&torrent::on_resume_data_checked
, shared_from_this(), _1));
#ifndef TORRENT_DISABLE_LOGGING
debug_log("init, async_check_fastresume");
debug_log("init, async_check_files");
#endif
update_want_peers();
@ -2537,7 +2536,7 @@ namespace libtorrent
std::vector<std::string> links;
inc_refcount("force_recheck");
m_ses.disk_thread().async_check_fastresume(m_storage.get(), NULL
m_ses.disk_thread().async_check_files(m_storage.get(), NULL
, links, boost::bind(&torrent::on_force_recheck
, shared_from_this(), _1));
}

View File

@ -47,33 +47,32 @@ using namespace libtorrent;
struct test_storage_impl : storage_interface
{
virtual void initialize(storage_error& ec) {}
virtual void initialize(storage_error& ec) TORRENT_OVERRIDE {}
virtual int readv(file::iovec_t const* bufs, int num_bufs
, int piece, int offset, int flags, storage_error& ec)
, int piece, int offset, int flags, storage_error& ec) TORRENT_OVERRIDE
{
return bufs_size(bufs, num_bufs);
}
virtual int writev(file::iovec_t const* bufs, int num_bufs
, int piece, int offset, int flags, storage_error& ec)
, int piece, int offset, int flags, storage_error& ec) TORRENT_OVERRIDE
{
return bufs_size(bufs, num_bufs);
}
virtual bool has_any_file(storage_error& ec) { return false; }
virtual bool has_any_file(storage_error& ec) TORRENT_OVERRIDE { return false; }
virtual void set_file_priority(std::vector<boost::uint8_t> const& prio
, storage_error& ec) {}
, storage_error& ec) TORRENT_OVERRIDE {}
virtual int move_storage(std::string const& save_path, int flags
, storage_error& ec) { return 0; }
virtual bool verify_resume_data(bdecode_node const& rd
, storage_error& ec) TORRENT_OVERRIDE { return 0; }
virtual bool verify_resume_data(add_torrent_params const& rd
, std::vector<std::string> const* links
, storage_error& ec) { return true; }
virtual void write_resume_data(entry& rd, storage_error& ec) const {}
virtual void release_files(storage_error& ec) {}
, storage_error& ec) TORRENT_OVERRIDE { return true; }
virtual void release_files(storage_error& ec) TORRENT_OVERRIDE {}
virtual void rename_file(int index, std::string const& new_filenamem
, storage_error& ec) {}
virtual void delete_files(storage_error& ec) {}
virtual void finalize_file(int, storage_error&) {}
, storage_error& ec) TORRENT_OVERRIDE {}
virtual void delete_files(storage_error& ec) TORRENT_OVERRIDE {}
virtual void finalize_file(int, storage_error&) TORRENT_OVERRIDE {}
};
static void nop() {}

View File

@ -467,9 +467,9 @@ void test_check_files(std::string const& test_path
libtorrent::mutex lock;
bool done = false;
bdecode_node frd;
add_torrent_params frd;
std::vector<std::string> links;
io.async_check_fastresume(pm.get(), &frd, links
io.async_check_files(pm.get(), &frd, links
, boost::bind(&on_check_resume_data, _1, &done));
io.submit_jobs();
ios.reset();