cleaning up of disk_interface and improving type safety (#1353)
cleaned up disk_interface and improved type safety. removed unused disk status code disk_check_aborted, and removed status code return value for async_hash
This commit is contained in:
parent
5c8e6d6e97
commit
15ab8f387b
|
@ -1,3 +1,4 @@
|
|||
* tweaked storage_interface to have stronger type safety
|
||||
* deprecate relative times in torrent_status, replaced by std::chrono::time_point
|
||||
* refactor in alert types to use more const fields and more clear API
|
||||
* changed session_stats_alert counters type to signed (std::int64_t)
|
||||
|
|
|
@ -45,24 +45,30 @@ namespace libtorrent
|
|||
struct file_pool;
|
||||
struct add_torrent_params;
|
||||
struct cache_status;
|
||||
struct disk_buffer_holder;
|
||||
struct counters;
|
||||
|
||||
enum class status_t : std::uint8_t
|
||||
{
|
||||
// return values from check_fastresume, and move_storage
|
||||
no_error,
|
||||
fatal_disk_error,
|
||||
need_full_check,
|
||||
file_exist
|
||||
};
|
||||
|
||||
struct TORRENT_EXTRA_EXPORT disk_interface
|
||||
{
|
||||
enum return_t
|
||||
{
|
||||
// return values from check_fastresume, and move_storage
|
||||
no_error = 0,
|
||||
fatal_disk_error = -1,
|
||||
need_full_check = -2,
|
||||
disk_check_aborted = -3,
|
||||
file_exist = -4
|
||||
};
|
||||
|
||||
enum flags_t
|
||||
{
|
||||
sequential_access = 0x1,
|
||||
|
||||
// this flag is set on a job when a read operation did
|
||||
// not hit the disk, but found the data in the read cache.
|
||||
cache_hit = 0x2,
|
||||
|
||||
// don't keep the read block in cache
|
||||
volatile_read = 0x10,
|
||||
};
|
||||
|
||||
virtual void async_read(storage_interface* storage, peer_request const& r
|
||||
|
@ -73,15 +79,15 @@ namespace libtorrent
|
|||
, std::function<void(storage_error const&)> handler
|
||||
, std::uint8_t flags = 0) = 0;
|
||||
virtual void async_hash(storage_interface* storage, int piece, std::uint8_t flags
|
||||
, std::function<void(int, int, sha1_hash const&, storage_error const&)> handler, void* requester) = 0;
|
||||
, std::function<void(int, sha1_hash const&, storage_error const&)> handler, void* requester) = 0;
|
||||
virtual void async_move_storage(storage_interface* storage, std::string const& p, std::uint8_t flags
|
||||
, std::function<void(int, std::string const&, storage_error const&)> handler) = 0;
|
||||
, std::function<void(status_t, std::string const&, storage_error const&)> handler) = 0;
|
||||
virtual void async_release_files(storage_interface* storage
|
||||
, std::function<void()> handler = std::function<void()>()) = 0;
|
||||
virtual void async_check_files(storage_interface* storage
|
||||
, add_torrent_params const* resume_data
|
||||
, std::vector<std::string>& links
|
||||
, std::function<void(int, storage_error const&)> handler) = 0;
|
||||
, std::function<void(status_t, storage_error const&)> handler) = 0;
|
||||
virtual void async_flush_piece(storage_interface* storage, int piece
|
||||
, std::function<void()> handler = std::function<void()>()) = 0;
|
||||
virtual void async_stop_torrent(storage_interface* storage
|
||||
|
|
|
@ -38,6 +38,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/peer_request.hpp"
|
||||
#include "libtorrent/aux_/block_cache_reference.hpp"
|
||||
#include "libtorrent/sha1_hash.hpp"
|
||||
#include "libtorrent/disk_interface.hpp"
|
||||
|
||||
#include "libtorrent/aux_/disable_warnings_push.hpp"
|
||||
#include <boost/variant/variant.hpp>
|
||||
|
@ -99,8 +100,6 @@ namespace libtorrent
|
|||
|
||||
enum flags_t
|
||||
{
|
||||
sequential_access = 0x1,
|
||||
|
||||
// force making a copy of the cached block, rather
|
||||
// than getting a reference to the block already in
|
||||
// the cache.
|
||||
|
@ -112,9 +111,6 @@ namespace libtorrent
|
|||
// to lower the fence when the job has completed
|
||||
fence = 0x8,
|
||||
|
||||
// don't keep the read block in cache
|
||||
volatile_read = 0x10,
|
||||
|
||||
// this job is currently being performed, or it's hanging
|
||||
// on a cache piece that may be flushed soon
|
||||
in_progress = 0x20
|
||||
|
@ -151,10 +147,10 @@ namespace libtorrent
|
|||
using read_handler = std::function<void(aux::block_cache_reference ref
|
||||
, char* block, int flags, storage_error const& se)>;
|
||||
using write_handler = std::function<void(storage_error const&)>;
|
||||
using hash_handler = std::function<void(int, int, sha1_hash const&, storage_error const&)>;
|
||||
using move_handler = std::function<void(int, std::string const&, storage_error const&)>;
|
||||
using hash_handler = std::function<void(int, sha1_hash const&, storage_error const&)>;
|
||||
using move_handler = std::function<void(status_t, std::string const&, storage_error const&)>;
|
||||
using release_handler = std::function<void()>;
|
||||
using check_handler = std::function<void(int, storage_error const&)>;
|
||||
using check_handler = std::function<void(status_t, storage_error const&)>;
|
||||
using rename_handler = std::function<void(std::string const&, int, storage_error const&)>;
|
||||
using clear_piece_handler = std::function<void(int)>;
|
||||
|
||||
|
@ -215,10 +211,8 @@ namespace libtorrent
|
|||
// the type of job this is
|
||||
std::uint32_t action:8;
|
||||
|
||||
enum { operation_failed = -1 };
|
||||
|
||||
// return value of operation
|
||||
std::int32_t ret = 0;
|
||||
status_t ret = status_t::no_error;
|
||||
|
||||
// flags controlling this job
|
||||
std::uint8_t flags = 0;
|
||||
|
|
|
@ -299,9 +299,9 @@ namespace libtorrent
|
|||
, std::function<void(storage_error const&)> handler
|
||||
, std::uint8_t flags = 0) override;
|
||||
void async_hash(storage_interface* storage, int piece, std::uint8_t flags
|
||||
, std::function<void(int, int, sha1_hash const&, storage_error const&)> handler, void* requester) override;
|
||||
, std::function<void(int, sha1_hash const&, storage_error const&)> handler, void* requester) override;
|
||||
void async_move_storage(storage_interface* storage, std::string const& p, std::uint8_t flags
|
||||
, std::function<void(int, std::string const&, storage_error const&)> handler) override;
|
||||
, std::function<void(status_t, std::string const&, storage_error const&)> handler) override;
|
||||
void async_release_files(storage_interface* storage
|
||||
, std::function<void()> handler = std::function<void()>()) override;
|
||||
void async_delete_files(storage_interface* storage, int options
|
||||
|
@ -309,7 +309,7 @@ namespace libtorrent
|
|||
void async_check_files(storage_interface* storage
|
||||
, add_torrent_params const* resume_data
|
||||
, std::vector<std::string>& links
|
||||
, std::function<void(int, storage_error const&)> handler) override;
|
||||
, std::function<void(status_t, storage_error const&)> handler) override;
|
||||
void async_rename_file(storage_interface* storage, int index, std::string const& name
|
||||
, std::function<void(std::string const&, int, storage_error const&)> handler) override;
|
||||
void async_stop_torrent(storage_interface* storage
|
||||
|
@ -372,29 +372,29 @@ namespace libtorrent
|
|||
|
||||
void maybe_issue_queued_read_jobs(cached_piece_entry* pe,
|
||||
jobqueue_t& completed_jobs);
|
||||
int do_read(disk_io_job* j, jobqueue_t& completed_jobs);
|
||||
int do_uncached_read(disk_io_job* j);
|
||||
status_t do_read(disk_io_job* j, jobqueue_t& completed_jobs);
|
||||
status_t do_uncached_read(disk_io_job* j);
|
||||
|
||||
int do_write(disk_io_job* j, jobqueue_t& completed_jobs);
|
||||
int do_uncached_write(disk_io_job* j);
|
||||
status_t do_write(disk_io_job* j, jobqueue_t& completed_jobs);
|
||||
status_t do_uncached_write(disk_io_job* j);
|
||||
|
||||
int do_hash(disk_io_job* j, jobqueue_t& completed_jobs);
|
||||
int do_uncached_hash(disk_io_job* j);
|
||||
status_t do_hash(disk_io_job* j, jobqueue_t& completed_jobs);
|
||||
status_t do_uncached_hash(disk_io_job* j);
|
||||
|
||||
int do_move_storage(disk_io_job* j, jobqueue_t& completed_jobs);
|
||||
int do_release_files(disk_io_job* j, jobqueue_t& completed_jobs);
|
||||
int do_delete_files(disk_io_job* j, jobqueue_t& completed_jobs);
|
||||
int do_check_fastresume(disk_io_job* j, jobqueue_t& completed_jobs);
|
||||
int do_rename_file(disk_io_job* j, jobqueue_t& completed_jobs);
|
||||
int do_stop_torrent(disk_io_job* j, jobqueue_t& completed_jobs);
|
||||
int do_read_and_hash(disk_io_job* j, jobqueue_t& completed_jobs);
|
||||
int do_flush_piece(disk_io_job* j, jobqueue_t& completed_jobs);
|
||||
int do_flush_hashed(disk_io_job* j, jobqueue_t& completed_jobs);
|
||||
int do_flush_storage(disk_io_job* j, jobqueue_t& completed_jobs);
|
||||
int do_trim_cache(disk_io_job* j, jobqueue_t& completed_jobs);
|
||||
int do_file_priority(disk_io_job* j, jobqueue_t& completed_jobs);
|
||||
int do_clear_piece(disk_io_job* j, jobqueue_t& completed_jobs);
|
||||
int do_resolve_links(disk_io_job* j, jobqueue_t& completed_jobs);
|
||||
status_t do_move_storage(disk_io_job* j, jobqueue_t& completed_jobs);
|
||||
status_t do_release_files(disk_io_job* j, jobqueue_t& completed_jobs);
|
||||
status_t do_delete_files(disk_io_job* j, jobqueue_t& completed_jobs);
|
||||
status_t do_check_fastresume(disk_io_job* j, jobqueue_t& completed_jobs);
|
||||
status_t do_rename_file(disk_io_job* j, jobqueue_t& completed_jobs);
|
||||
status_t do_stop_torrent(disk_io_job* j, jobqueue_t& completed_jobs);
|
||||
status_t do_read_and_hash(disk_io_job* j, jobqueue_t& completed_jobs);
|
||||
status_t do_flush_piece(disk_io_job* j, jobqueue_t& completed_jobs);
|
||||
status_t do_flush_hashed(disk_io_job* j, jobqueue_t& completed_jobs);
|
||||
status_t do_flush_storage(disk_io_job* j, jobqueue_t& completed_jobs);
|
||||
status_t do_trim_cache(disk_io_job* j, jobqueue_t& completed_jobs);
|
||||
status_t do_file_priority(disk_io_job* j, jobqueue_t& completed_jobs);
|
||||
status_t do_clear_piece(disk_io_job* j, jobqueue_t& completed_jobs);
|
||||
status_t do_resolve_links(disk_io_job* j, jobqueue_t& completed_jobs);
|
||||
|
||||
void call_job_handlers();
|
||||
|
||||
|
@ -425,17 +425,6 @@ namespace libtorrent
|
|||
jobqueue_t m_queued_jobs;
|
||||
};
|
||||
|
||||
enum return_value_t
|
||||
{
|
||||
// the do_* functions can return this to indicate the disk
|
||||
// job did not complete immediately, and shouldn't be posted yet
|
||||
defer_handler = -200,
|
||||
|
||||
// the job cannot be completed right now, put it back in the
|
||||
// queue and try again later
|
||||
retry_job = -201
|
||||
};
|
||||
|
||||
// returns true if the thread should exit
|
||||
static bool wait_for_job(job_queue& jobq, disk_io_thread_pool& threads
|
||||
, std::unique_lock<std::mutex>& l);
|
||||
|
|
|
@ -64,6 +64,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/span.hpp"
|
||||
#include "libtorrent/piece_block.hpp"
|
||||
#include "libtorrent/peer_info.hpp"
|
||||
#include "libtorrent/disk_interface.hpp"
|
||||
|
||||
#include <ctime>
|
||||
#include <algorithm>
|
||||
|
@ -77,8 +78,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
namespace libtorrent
|
||||
{
|
||||
class torrent;
|
||||
struct disk_io_job;
|
||||
struct disk_interface;
|
||||
struct torrent_peer;
|
||||
|
||||
#ifndef TORRENT_DISABLE_EXTENSIONS
|
||||
|
@ -765,7 +764,7 @@ namespace libtorrent
|
|||
, time_point issue_time);
|
||||
void on_disk_write_complete(storage_error const& error
|
||||
, peer_request r, std::shared_ptr<torrent> t);
|
||||
void on_seed_mode_hashed(int status, int piece
|
||||
void on_seed_mode_hashed(int piece
|
||||
, sha1_hash const& piece_hash, storage_error const& error);
|
||||
int request_timeout() const;
|
||||
void check_graceful_pause();
|
||||
|
|
|
@ -101,7 +101,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 status_t move_storage(std::string const& save_path) { return false; }
|
||||
// virtual bool verify_resume_data(add_torrent_params const& rd
|
||||
// , std::vector<std::string> const* links
|
||||
// , storage_error& error) { return false; }
|
||||
|
@ -352,13 +352,7 @@ namespace libtorrent
|
|||
// like ``release_files()``.
|
||||
//
|
||||
//If an error occurs, ``storage_error`` should be set to reflect it.
|
||||
//
|
||||
// returns one of:
|
||||
// | no_error = 0
|
||||
// | fatal_disk_error = -1
|
||||
// | need_full_check = -2
|
||||
// | file_exist = -4
|
||||
virtual int move_storage(std::string const& save_path, int flags
|
||||
virtual status_t move_storage(std::string const& save_path, int flags
|
||||
, storage_error& ec) = 0;
|
||||
|
||||
// This function should verify the resume data ``rd`` with the files
|
||||
|
@ -500,7 +494,7 @@ namespace libtorrent
|
|||
virtual void release_files(storage_error& ec) override;
|
||||
virtual void delete_files(int options, storage_error& ec) override;
|
||||
virtual void initialize(storage_error& ec) override;
|
||||
virtual int move_storage(std::string const& save_path, int flags
|
||||
virtual status_t move_storage(std::string const& save_path, int flags
|
||||
, storage_error& ec) override;
|
||||
virtual bool verify_resume_data(add_torrent_params const& rd
|
||||
, std::vector<std::string> const& links
|
||||
|
|
|
@ -67,6 +67,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/linked_list.hpp"
|
||||
#include "libtorrent/debug.hpp"
|
||||
#include "libtorrent/piece_block.hpp"
|
||||
#include "libtorrent/disk_interface.hpp" // for status_t
|
||||
#include "libtorrent/aux_/file_progress.hpp"
|
||||
#include "libtorrent/aux_/suggest_piece.hpp"
|
||||
|
||||
|
@ -350,9 +351,9 @@ namespace libtorrent
|
|||
bt_peer_connection* find_peer(tcp::endpoint const& ep) const;
|
||||
peer_connection* find_peer(sha1_hash const& pid);
|
||||
|
||||
void on_resume_data_checked(int status, storage_error const& error);
|
||||
void on_force_recheck(int status, storage_error const& error);
|
||||
void on_piece_hashed(int status, int piece, sha1_hash const& piece_hash
|
||||
void on_resume_data_checked(status_t status, storage_error const& error);
|
||||
void on_force_recheck(status_t status, storage_error const& error);
|
||||
void on_piece_hashed(int piece, sha1_hash const& piece_hash
|
||||
, storage_error const& error);
|
||||
void files_checked();
|
||||
void start_checking();
|
||||
|
@ -867,7 +868,7 @@ namespace libtorrent
|
|||
void resume_download();
|
||||
|
||||
void verify_piece(int piece);
|
||||
void on_piece_verified(int const status, int const piece
|
||||
void on_piece_verified(int const piece
|
||||
, sha1_hash const& piece_hash, storage_error const& error);
|
||||
|
||||
// this is called whenever a peer in this swarm becomes interesting
|
||||
|
@ -1116,7 +1117,7 @@ namespace libtorrent
|
|||
|
||||
void on_files_deleted(storage_error const& error);
|
||||
void on_torrent_paused();
|
||||
void on_storage_moved(int status, std::string const& path
|
||||
void on_storage_moved(status_t status, std::string const& path
|
||||
, storage_error const& error);
|
||||
void on_file_renamed(std::string const& filename
|
||||
, int const file_idx
|
||||
|
|
|
@ -369,7 +369,7 @@ int block_cache::try_read(disk_io_job* j, bool expect_no_fail)
|
|||
#if TORRENT_USE_ASSERTS
|
||||
p->piece_log.push_back(piece_log_t(j->action, j->d.io.offset / 0x4000));
|
||||
#endif
|
||||
cache_hit(p, j->requester, (j->flags & disk_io_job::volatile_read) != 0);
|
||||
cache_hit(p, j->requester, (j->flags & disk_interface::volatile_read) != 0);
|
||||
|
||||
ret = copy_from_piece(p, j, expect_no_fail);
|
||||
if (ret < 0) return ret;
|
||||
|
@ -1269,7 +1269,7 @@ void block_cache::insert_blocks(cached_piece_entry* pe, int block, span<file::io
|
|||
TORRENT_ASSERT(pe->in_use);
|
||||
TORRENT_PIECE_ASSERT(iov.size() > 0, pe);
|
||||
|
||||
cache_hit(pe, j->requester, (j->flags & disk_io_job::volatile_read) != 0);
|
||||
cache_hit(pe, j->requester, (j->flags & disk_interface::volatile_read) != 0);
|
||||
|
||||
TORRENT_ASSERT(pe->in_use);
|
||||
|
||||
|
@ -1304,7 +1304,7 @@ void block_cache::insert_blocks(cached_piece_entry* pe, int block, span<file::io
|
|||
TORRENT_PIECE_ASSERT(pe->blocks[block].dirty == false, pe);
|
||||
++pe->num_blocks;
|
||||
++m_read_cache_size;
|
||||
if (j->flags & disk_io_job::volatile_read) ++m_volatile_size;
|
||||
if (j->flags & disk_interface::volatile_read) ++m_volatile_size;
|
||||
|
||||
if (flags & blocks_inc_refcount)
|
||||
{
|
||||
|
|
|
@ -169,10 +169,10 @@ namespace libtorrent
|
|||
error_code& ec;
|
||||
};
|
||||
|
||||
void on_hash(int const status, int const piece, sha1_hash const& piece_hash
|
||||
void on_hash(int const piece, sha1_hash const& piece_hash
|
||||
, storage_error const& error, hash_state* st)
|
||||
{
|
||||
if (status != 0)
|
||||
if (error)
|
||||
{
|
||||
// on error
|
||||
st->ec = error.ec;
|
||||
|
@ -185,8 +185,8 @@ namespace libtorrent
|
|||
if (st->piece_counter < st->ct.num_pieces())
|
||||
{
|
||||
st->iothread.async_hash(st->storage.get(), st->piece_counter
|
||||
, disk_io_job::sequential_access
|
||||
, std::bind(&on_hash, _1, _2, _3, _4, st), nullptr);
|
||||
, disk_interface::sequential_access
|
||||
, std::bind(&on_hash, _1, _2, _3, st), nullptr);
|
||||
++st->piece_counter;
|
||||
}
|
||||
else
|
||||
|
@ -297,8 +297,8 @@ namespace libtorrent
|
|||
hash_state st = { t, storage, disk_thread, 0, 0, f, ec };
|
||||
for (int i = 0; i < piece_read_ahead; ++i)
|
||||
{
|
||||
disk_thread.async_hash(storage.get(), i, disk_io_job::sequential_access
|
||||
, std::bind(&on_hash, _1, _2, _3, _4, &st), nullptr);
|
||||
disk_thread.async_hash(storage.get(), i, disk_interface::sequential_access
|
||||
, std::bind(&on_hash, _1, _2, _3, &st), nullptr);
|
||||
++st.piece_counter;
|
||||
if (st.piece_counter >= t.num_pieces()) break;
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@ namespace libtorrent
|
|||
void operator()(disk_io_job::hash_handler& h) const
|
||||
{
|
||||
if (!h) return;
|
||||
h(m_job.ret, m_job.piece, sha1_hash(m_job.d.piece_hash), m_job.error);
|
||||
h(m_job.piece, sha1_hash(m_job.d.piece_hash), m_job.error);
|
||||
}
|
||||
|
||||
void operator()(disk_io_job::move_handler& h) const
|
||||
|
|
|
@ -119,11 +119,20 @@ namespace libtorrent
|
|||
, bool const coalesce_buffers)
|
||||
{
|
||||
int ret = 0;
|
||||
if (!(j->flags & disk_io_job::sequential_access)) ret |= file::random_access;
|
||||
if (!(j->flags & disk_interface::sequential_access)) ret |= file::random_access;
|
||||
if (coalesce_buffers) ret |= file::coalesce_buffers;
|
||||
return ret;
|
||||
}
|
||||
|
||||
// the do_* functions can return this to indicate the disk
|
||||
// job did not complete immediately, and shouldn't be posted yet
|
||||
constexpr status_t defer_handler = static_cast<status_t>(200);
|
||||
|
||||
// the job cannot be completed right now, put it back in the
|
||||
// queue and try again later
|
||||
constexpr status_t retry_job = static_cast<status_t>(201);
|
||||
|
||||
|
||||
struct piece_refcount_holder
|
||||
{
|
||||
explicit piece_refcount_holder(cached_piece_entry* p) : m_pe(p)
|
||||
|
@ -705,7 +714,7 @@ namespace libtorrent
|
|||
TORRENT_PIECE_ASSERT(j->piece == pe->piece, pe);
|
||||
if (j->completed(pe, block_size))
|
||||
{
|
||||
j->ret = j->d.io.buffer_size;
|
||||
j->ret = status_t::no_error;
|
||||
j->error = error;
|
||||
completed_jobs.push_back(j);
|
||||
}
|
||||
|
@ -773,7 +782,7 @@ namespace libtorrent
|
|||
{
|
||||
disk_io_job* j = src.pop_front();
|
||||
TORRENT_ASSERT((j->flags & disk_io_job::in_progress) || !j->storage);
|
||||
j->ret = disk_interface::fatal_disk_error;
|
||||
j->ret = status_t::fatal_disk_error;
|
||||
j->error = e;
|
||||
dst.push_back(j);
|
||||
}
|
||||
|
@ -1003,7 +1012,7 @@ namespace libtorrent
|
|||
|
||||
namespace {
|
||||
|
||||
typedef int (disk_io_thread::*disk_io_fun_t)(disk_io_job* j, jobqueue_t& completed_jobs);
|
||||
typedef status_t (disk_io_thread::*disk_io_fun_t)(disk_io_job* j, jobqueue_t& completed_jobs);
|
||||
|
||||
// this is a jump-table for disk I/O jobs
|
||||
const disk_io_fun_t job_functions[] =
|
||||
|
@ -1094,32 +1103,32 @@ namespace libtorrent
|
|||
|
||||
// call disk function
|
||||
// TODO: in the future, propagate exceptions back to the handlers
|
||||
int ret = 0;
|
||||
status_t ret = status_t::no_error;
|
||||
try
|
||||
{
|
||||
ret = (this->*(job_functions[j->action]))(j, completed_jobs);
|
||||
}
|
||||
catch (boost::system::system_error const& err)
|
||||
{
|
||||
ret = disk_interface::fatal_disk_error;
|
||||
ret = status_t::fatal_disk_error;
|
||||
j->error.ec = err.code();
|
||||
j->error.operation = storage_error::exception;
|
||||
}
|
||||
catch (std::bad_alloc const&)
|
||||
{
|
||||
ret = disk_interface::fatal_disk_error;
|
||||
ret = status_t::fatal_disk_error;
|
||||
j->error.ec = errors::no_memory;
|
||||
j->error.operation = storage_error::exception;
|
||||
}
|
||||
catch (std::exception const&)
|
||||
{
|
||||
ret = disk_interface::fatal_disk_error;
|
||||
ret = status_t::fatal_disk_error;
|
||||
j->error.ec = boost::asio::error::fault;
|
||||
j->error.operation = storage_error::exception;
|
||||
}
|
||||
|
||||
// note that -2 errors are OK
|
||||
TORRENT_ASSERT(ret != disk_interface::fatal_disk_error
|
||||
TORRENT_ASSERT(ret != status_t::fatal_disk_error
|
||||
|| (j->error.ec && j->error.operation != 0));
|
||||
|
||||
m_stats_counters.inc_stats_counter(counters::num_running_disk_jobs, -1);
|
||||
|
@ -1172,14 +1181,14 @@ namespace libtorrent
|
|||
completed_jobs.push_back(j);
|
||||
}
|
||||
|
||||
int disk_io_thread::do_uncached_read(disk_io_job* j)
|
||||
status_t disk_io_thread::do_uncached_read(disk_io_job* j)
|
||||
{
|
||||
j->buffer.disk_block = m_disk_cache.allocate_buffer("send buffer");
|
||||
if (j->buffer.disk_block == nullptr)
|
||||
{
|
||||
j->error.ec = error::no_memory;
|
||||
j->error.operation = storage_error::alloc_cache_piece;
|
||||
return disk_interface::fatal_disk_error;
|
||||
return status_t::fatal_disk_error;
|
||||
}
|
||||
|
||||
time_point start_time = clock_type::now();
|
||||
|
@ -1204,10 +1213,10 @@ namespace libtorrent
|
|||
m_stats_counters.inc_stats_counter(counters::disk_read_time, read_time);
|
||||
m_stats_counters.inc_stats_counter(counters::disk_job_time, read_time);
|
||||
}
|
||||
return ret;
|
||||
return status_t::no_error;
|
||||
}
|
||||
|
||||
int disk_io_thread::do_read(disk_io_job* j, jobqueue_t& completed_jobs)
|
||||
status_t disk_io_thread::do_read(disk_io_job* j, jobqueue_t& completed_jobs)
|
||||
{
|
||||
int const block_size = m_disk_cache.block_size();
|
||||
int const piece_size = j->storage->files()->piece_size(j->piece);
|
||||
|
@ -1237,12 +1246,12 @@ namespace libtorrent
|
|||
|
||||
if (ret < 0)
|
||||
{
|
||||
ret = do_uncached_read(j);
|
||||
status_t const s = do_uncached_read(j);
|
||||
|
||||
std::unique_lock<std::mutex> l2(m_cache_mutex);
|
||||
pe = m_disk_cache.find_piece(j);
|
||||
if (pe) maybe_issue_queued_read_jobs(pe, completed_jobs);
|
||||
return ret;
|
||||
return s;
|
||||
}
|
||||
|
||||
// this is the offset that's aligned to block boundaries
|
||||
|
@ -1290,7 +1299,7 @@ namespace libtorrent
|
|||
// the piece is supposed to be allocated when the
|
||||
// disk job is allocated
|
||||
TORRENT_ASSERT_FAIL();
|
||||
return ret;
|
||||
return status_t::fatal_disk_error;
|
||||
}
|
||||
TORRENT_PIECE_ASSERT(pe->outstanding_read == 1, pe);
|
||||
|
||||
|
@ -1302,7 +1311,7 @@ namespace libtorrent
|
|||
pe->piece_log.push_back(piece_log_t(piece_log_t::clear_outstanding_jobs));
|
||||
#endif
|
||||
m_disk_cache.maybe_free_piece(pe);
|
||||
return ret;
|
||||
return status_t::fatal_disk_error;
|
||||
}
|
||||
|
||||
int block = j->d.io.offset / block_size;
|
||||
|
@ -1328,7 +1337,7 @@ namespace libtorrent
|
|||
for (int i = 0; i < iov_len; ++i, ++block)
|
||||
m_disk_cache.dec_block_refcount(pe, block, block_cache::ref_reading);
|
||||
|
||||
return j->d.io.buffer_size;
|
||||
return status_t::no_error;
|
||||
}
|
||||
|
||||
void disk_io_thread::maybe_issue_queued_read_jobs(cached_piece_entry* pe
|
||||
|
@ -1373,13 +1382,13 @@ namespace libtorrent
|
|||
m_stats_counters.inc_stats_counter(counters::num_blocks_cache_hits);
|
||||
DLOG("do_read: cache hit\n");
|
||||
j->flags |= disk_interface::cache_hit;
|
||||
j->ret = ret;
|
||||
j->ret = status_t::no_error;
|
||||
completed_jobs.push_back(j);
|
||||
}
|
||||
else if (ret == -2)
|
||||
{
|
||||
// error
|
||||
j->ret = disk_io_job::operation_failed;
|
||||
j->ret = status_t::fatal_disk_error;
|
||||
completed_jobs.push_back(j);
|
||||
}
|
||||
else
|
||||
|
@ -1413,7 +1422,7 @@ namespace libtorrent
|
|||
}
|
||||
}
|
||||
|
||||
int disk_io_thread::do_uncached_write(disk_io_job* j)
|
||||
status_t disk_io_thread::do_uncached_write(disk_io_job* j)
|
||||
{
|
||||
time_point start_time = clock_type::now();
|
||||
|
||||
|
@ -1446,10 +1455,11 @@ namespace libtorrent
|
|||
m_disk_cache.free_buffer(j->buffer.disk_block);
|
||||
j->buffer.disk_block = nullptr;
|
||||
|
||||
return ret;
|
||||
return ret != j->d.io.buffer_size
|
||||
? status_t::fatal_disk_error : status_t::no_error;
|
||||
}
|
||||
|
||||
int disk_io_thread::do_write(disk_io_job* j, jobqueue_t& completed_jobs)
|
||||
status_t disk_io_thread::do_write(disk_io_job* j, jobqueue_t& completed_jobs)
|
||||
{
|
||||
TORRENT_ASSERT(j->d.io.buffer_size <= m_disk_cache.block_size());
|
||||
|
||||
|
@ -1465,7 +1475,7 @@ namespace libtorrent
|
|||
TORRENT_ASSERT(pe->blocks[j->d.io.offset / 16 / 1024].buf != nullptr);
|
||||
j->error.ec = error::operation_aborted;
|
||||
j->error.operation = storage_error::write;
|
||||
return disk_interface::fatal_disk_error;
|
||||
return status_t::fatal_disk_error;
|
||||
}
|
||||
|
||||
pe = m_disk_cache.add_dirty_block(j);
|
||||
|
@ -1563,14 +1573,14 @@ namespace libtorrent
|
|||
m_stats_counters.inc_stats_counter(counters::num_blocks_cache_hits);
|
||||
DLOG("do_read: cache hit\n");
|
||||
j->flags |= disk_interface::cache_hit;
|
||||
j->ret = ret;
|
||||
j->ret = status_t::no_error;
|
||||
return 0;
|
||||
}
|
||||
else if (ret == -2)
|
||||
{
|
||||
j->error.ec = error::no_memory;
|
||||
j->error.operation = storage_error::alloc_cache_piece;
|
||||
j->ret = disk_io_job::operation_failed;
|
||||
j->ret = status_t::fatal_disk_error;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1599,7 +1609,7 @@ namespace libtorrent
|
|||
|
||||
if (pe == nullptr)
|
||||
{
|
||||
j->ret = disk_interface::fatal_disk_error;
|
||||
j->ret = status_t::fatal_disk_error;
|
||||
j->error.ec = error::no_memory;
|
||||
j->error.operation = storage_error::read;
|
||||
return 0;
|
||||
|
@ -1723,7 +1733,7 @@ namespace libtorrent
|
|||
}
|
||||
|
||||
void disk_io_thread::async_hash(storage_interface* storage, int piece, std::uint8_t flags
|
||||
, std::function<void(int, int, sha1_hash const&, storage_error const&)> handler, void* requester)
|
||||
, std::function<void(int, sha1_hash const&, storage_error const&)> handler, void* requester)
|
||||
{
|
||||
disk_io_job* j = allocate_job(disk_io_job::hash);
|
||||
j->storage = storage->shared_from_this();
|
||||
|
@ -1761,7 +1771,7 @@ namespace libtorrent
|
|||
}
|
||||
|
||||
void disk_io_thread::async_move_storage(storage_interface* storage, std::string const& p, std::uint8_t const flags
|
||||
, std::function<void(int, std::string const&, storage_error const&)> handler)
|
||||
, std::function<void(status_t, std::string const&, storage_error const&)> handler)
|
||||
{
|
||||
disk_io_job* j = allocate_job(disk_io_job::move_storage);
|
||||
j->storage = storage->shared_from_this();
|
||||
|
@ -1831,7 +1841,7 @@ namespace libtorrent
|
|||
void disk_io_thread::async_check_files(storage_interface* storage
|
||||
, add_torrent_params const* resume_data
|
||||
, std::vector<std::string>& links
|
||||
, std::function<void(int, storage_error const&)> handler)
|
||||
, std::function<void(status_t, storage_error const&)> handler)
|
||||
{
|
||||
std::vector<std::string>* links_vector
|
||||
= new std::vector<std::string>();
|
||||
|
@ -2066,7 +2076,7 @@ namespace libtorrent
|
|||
{
|
||||
disk_io_job* hj = i.get();
|
||||
std::memcpy(hj->d.piece_hash, result.data(), 20);
|
||||
hj->ret = 0;
|
||||
hj->ret = status_t::no_error;
|
||||
}
|
||||
|
||||
pe->hash.reset();
|
||||
|
@ -2079,7 +2089,7 @@ namespace libtorrent
|
|||
}
|
||||
}
|
||||
|
||||
int disk_io_thread::do_uncached_hash(disk_io_job* j)
|
||||
status_t disk_io_thread::do_uncached_hash(disk_io_job* j)
|
||||
{
|
||||
// we're not using a cache. This is the simple path
|
||||
// just read straight from the file
|
||||
|
@ -2127,10 +2137,10 @@ namespace libtorrent
|
|||
|
||||
sha1_hash piece_hash = h.final();
|
||||
std::memcpy(j->d.piece_hash, piece_hash.data(), 20);
|
||||
return ret >= 0 ? 0 : disk_interface::fatal_disk_error;
|
||||
return ret >= 0 ? status_t::no_error : status_t::fatal_disk_error;
|
||||
}
|
||||
|
||||
int disk_io_thread::do_hash(disk_io_job* j, jobqueue_t& /* completed_jobs */ )
|
||||
status_t disk_io_thread::do_hash(disk_io_job* j, jobqueue_t& /* completed_jobs */ )
|
||||
{
|
||||
int const piece_size = j->storage->files()->piece_size(j->piece);
|
||||
int const file_flags = file_flags_for_job(j
|
||||
|
@ -2145,7 +2155,7 @@ namespace libtorrent
|
|||
#if TORRENT_USE_ASSERTS
|
||||
pe->piece_log.push_back(piece_log_t(j->action));
|
||||
#endif
|
||||
m_disk_cache.cache_hit(pe, j->requester, (j->flags & disk_io_job::volatile_read) != 0);
|
||||
m_disk_cache.cache_hit(pe, j->requester, (j->flags & disk_interface::volatile_read) != 0);
|
||||
|
||||
TORRENT_PIECE_ASSERT(pe->cache_state <= cached_piece_entry::read_lru1 || pe->cache_state == cached_piece_entry::read_lru2, pe);
|
||||
{
|
||||
|
@ -2169,7 +2179,7 @@ namespace libtorrent
|
|||
#endif
|
||||
m_disk_cache.update_cache_state(pe);
|
||||
m_disk_cache.maybe_free_piece(pe);
|
||||
return 0;
|
||||
return status_t::no_error;
|
||||
}
|
||||
}
|
||||
else if (m_settings.get_bool(settings_pack::use_read_cache) == false)
|
||||
|
@ -2179,7 +2189,7 @@ namespace libtorrent
|
|||
|
||||
if (pe == nullptr)
|
||||
{
|
||||
std::uint16_t const cache_state = (j->flags & disk_io_job::volatile_read)
|
||||
std::uint16_t const cache_state = (j->flags & disk_interface::volatile_read)
|
||||
? cached_piece_entry::volatile_read_lru
|
||||
: cached_piece_entry::read_lru1;
|
||||
pe = m_disk_cache.allocate_piece(j, cache_state);
|
||||
|
@ -2188,7 +2198,7 @@ namespace libtorrent
|
|||
{
|
||||
j->error.ec = error::no_memory;
|
||||
j->error.operation = storage_error::alloc_cache_piece;
|
||||
return disk_interface::fatal_disk_error;
|
||||
return status_t::fatal_disk_error;
|
||||
}
|
||||
|
||||
if (pe->hashing)
|
||||
|
@ -2251,7 +2261,7 @@ namespace libtorrent
|
|||
|
||||
l.unlock();
|
||||
|
||||
int ret = 0;
|
||||
status_t ret = status_t::no_error;
|
||||
int next_locked_block = 0;
|
||||
for (int i = offset / block_size; i < blocks_in_piece; ++i)
|
||||
{
|
||||
|
@ -2287,7 +2297,7 @@ namespace libtorrent
|
|||
|
||||
j->error.ec = errors::no_memory;
|
||||
j->error.operation = storage_error::alloc_cache_piece;
|
||||
return disk_interface::fatal_disk_error;
|
||||
return status_t::fatal_disk_error;
|
||||
}
|
||||
|
||||
DLOG("do_hash: reading (piece: %d block: %d)\n", int(pe->piece), i);
|
||||
|
@ -2295,11 +2305,12 @@ namespace libtorrent
|
|||
time_point start_time = clock_type::now();
|
||||
|
||||
TORRENT_PIECE_ASSERT(offset == i * block_size, pe);
|
||||
ret = j->storage->readv(iov, j->piece
|
||||
int read_ret = j->storage->readv(iov, j->piece
|
||||
, offset, file_flags, j->error);
|
||||
|
||||
if (ret < 0)
|
||||
if (read_ret < 0)
|
||||
{
|
||||
ret = status_t::fatal_disk_error;
|
||||
TORRENT_ASSERT(j->error.ec && j->error.operation != 0);
|
||||
m_disk_cache.free_buffer(static_cast<char*>(iov.iov_base));
|
||||
break;
|
||||
|
@ -2308,9 +2319,9 @@ namespace libtorrent
|
|||
// treat a short read as an error. The hash will be invalid, the
|
||||
// block cannot be cached and the main thread should skip the rest
|
||||
// of this file
|
||||
if (ret != iov.iov_len)
|
||||
if (read_ret != iov.iov_len)
|
||||
{
|
||||
ret = disk_interface::fatal_disk_error;
|
||||
ret = status_t::fatal_disk_error;
|
||||
j->error.ec = boost::asio::error::eof;
|
||||
j->error.operation = storage_error::read;
|
||||
m_disk_cache.free_buffer(static_cast<char*>(iov.iov_base));
|
||||
|
@ -2352,7 +2363,7 @@ namespace libtorrent
|
|||
|
||||
pe->hashing = 0;
|
||||
|
||||
if (ret >= 0)
|
||||
if (ret == status_t::no_error)
|
||||
{
|
||||
sha1_hash piece_hash = ph->h.final();
|
||||
std::memcpy(j->d.piece_hash, piece_hash.data(), 20);
|
||||
|
@ -2368,12 +2379,12 @@ namespace libtorrent
|
|||
|
||||
m_disk_cache.maybe_free_piece(pe);
|
||||
|
||||
TORRENT_ASSERT(ret >= 0 || (j->error.ec && j->error.operation != 0));
|
||||
TORRENT_ASSERT(ret == status_t::no_error || (j->error.ec && j->error.operation != 0));
|
||||
|
||||
return ret < 0 ? ret : 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int disk_io_thread::do_move_storage(disk_io_job* j, jobqueue_t& /* completed_jobs */ )
|
||||
status_t disk_io_thread::do_move_storage(disk_io_job* j, jobqueue_t& /* completed_jobs */ )
|
||||
{
|
||||
// if this assert fails, something's wrong with the fence logic
|
||||
TORRENT_ASSERT(j->storage->num_outstanding_jobs() == 1);
|
||||
|
@ -2383,7 +2394,7 @@ namespace libtorrent
|
|||
, j->flags, j->error);
|
||||
}
|
||||
|
||||
int disk_io_thread::do_release_files(disk_io_job* j, jobqueue_t& completed_jobs)
|
||||
status_t disk_io_thread::do_release_files(disk_io_job* j, jobqueue_t& completed_jobs)
|
||||
{
|
||||
// if this assert fails, something's wrong with the fence logic
|
||||
TORRENT_ASSERT(j->storage->num_outstanding_jobs() == 1);
|
||||
|
@ -2393,10 +2404,10 @@ namespace libtorrent
|
|||
l.unlock();
|
||||
|
||||
j->storage->release_files(j->error);
|
||||
return j->error ? disk_interface::fatal_disk_error : 0;
|
||||
return j->error ? status_t::fatal_disk_error : status_t::no_error;
|
||||
}
|
||||
|
||||
int disk_io_thread::do_delete_files(disk_io_job* j, jobqueue_t& completed_jobs)
|
||||
status_t disk_io_thread::do_delete_files(disk_io_job* j, jobqueue_t& completed_jobs)
|
||||
{
|
||||
TORRENT_ASSERT(j->buffer.delete_options != 0);
|
||||
|
||||
|
@ -2410,10 +2421,10 @@ namespace libtorrent
|
|||
l.unlock();
|
||||
|
||||
j->storage->delete_files(j->buffer.delete_options, j->error);
|
||||
return j->error ? disk_interface::fatal_disk_error : 0;
|
||||
return j->error ? status_t::fatal_disk_error : status_t::no_error;
|
||||
}
|
||||
|
||||
int disk_io_thread::do_check_fastresume(disk_io_job* j, jobqueue_t& /* completed_jobs */ )
|
||||
status_t disk_io_thread::do_check_fastresume(disk_io_job* j, jobqueue_t& /* completed_jobs */ )
|
||||
{
|
||||
// if this assert fails, something's wrong with the fence logic
|
||||
TORRENT_ASSERT(j->storage->num_outstanding_jobs() == 1);
|
||||
|
@ -2453,7 +2464,7 @@ namespace libtorrent
|
|||
if (se)
|
||||
{
|
||||
j->error = se;
|
||||
return disk_interface::fatal_disk_error;
|
||||
return status_t::fatal_disk_error;
|
||||
}
|
||||
|
||||
if (has_files)
|
||||
|
@ -2463,9 +2474,9 @@ namespace libtorrent
|
|||
if (se)
|
||||
{
|
||||
j->error = se;
|
||||
return disk_interface::fatal_disk_error;
|
||||
return status_t::fatal_disk_error;
|
||||
}
|
||||
return disk_interface::need_full_check;
|
||||
return status_t::need_full_check;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2473,12 +2484,12 @@ namespace libtorrent
|
|||
if (se)
|
||||
{
|
||||
j->error = se;
|
||||
return disk_interface::fatal_disk_error;
|
||||
return status_t::fatal_disk_error;
|
||||
}
|
||||
return disk_interface::no_error;
|
||||
return status_t::no_error;
|
||||
}
|
||||
|
||||
int disk_io_thread::do_rename_file(disk_io_job* j, jobqueue_t& /* completed_jobs */ )
|
||||
status_t disk_io_thread::do_rename_file(disk_io_job* j, jobqueue_t& /* completed_jobs */ )
|
||||
{
|
||||
// if this assert fails, something's wrong with the fence logic
|
||||
TORRENT_ASSERT(j->storage->num_outstanding_jobs() == 1);
|
||||
|
@ -2486,10 +2497,10 @@ namespace libtorrent
|
|||
// if files need to be closed, that's the storage's responsibility
|
||||
j->storage->rename_file(j->piece, j->buffer.string
|
||||
, j->error);
|
||||
return j->error ? disk_interface::fatal_disk_error : disk_interface::no_error;
|
||||
return j->error ? status_t::fatal_disk_error : status_t::no_error;
|
||||
}
|
||||
|
||||
int disk_io_thread::do_stop_torrent(disk_io_job* j, jobqueue_t& completed_jobs)
|
||||
status_t disk_io_thread::do_stop_torrent(disk_io_job* j, jobqueue_t& completed_jobs)
|
||||
{
|
||||
// if this assert fails, something's wrong with the fence logic
|
||||
TORRENT_ASSERT(j->storage->num_outstanding_jobs() == 1);
|
||||
|
@ -2504,7 +2515,7 @@ namespace libtorrent
|
|||
m_disk_cache.release_memory();
|
||||
|
||||
j->storage->release_files(j->error);
|
||||
return j->error ? disk_interface::fatal_disk_error : disk_interface::no_error;
|
||||
return j->error ? status_t::fatal_disk_error : status_t::no_error;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
@ -2646,12 +2657,12 @@ namespace libtorrent
|
|||
#endif
|
||||
}
|
||||
|
||||
int disk_io_thread::do_flush_piece(disk_io_job* j, jobqueue_t& completed_jobs)
|
||||
status_t disk_io_thread::do_flush_piece(disk_io_job* j, jobqueue_t& completed_jobs)
|
||||
{
|
||||
std::unique_lock<std::mutex> l(m_cache_mutex);
|
||||
|
||||
cached_piece_entry* pe = m_disk_cache.find_piece(j);
|
||||
if (pe == nullptr) return 0;
|
||||
if (pe == nullptr) return status_t::no_error;
|
||||
|
||||
#if TORRENT_USE_ASSERTS
|
||||
pe->piece_log.push_back(piece_log_t(j->action));
|
||||
|
@ -2659,23 +2670,23 @@ namespace libtorrent
|
|||
try_flush_hashed(pe, m_settings.get_int(
|
||||
settings_pack::write_cache_line_size), completed_jobs, l);
|
||||
|
||||
return 0;
|
||||
return status_t::no_error;
|
||||
}
|
||||
|
||||
// this is triggered every time we insert a new dirty block in a piece
|
||||
// by the time this gets executed, the block may already have been flushed
|
||||
// triggered by another mechanism.
|
||||
int disk_io_thread::do_flush_hashed(disk_io_job* j, jobqueue_t& completed_jobs)
|
||||
status_t disk_io_thread::do_flush_hashed(disk_io_job* j, jobqueue_t& completed_jobs)
|
||||
{
|
||||
std::unique_lock<std::mutex> l(m_cache_mutex);
|
||||
|
||||
cached_piece_entry* pe = m_disk_cache.find_piece(j);
|
||||
|
||||
if (pe == nullptr) return 0;
|
||||
if (pe == nullptr) return status_t::no_error;
|
||||
|
||||
pe->outstanding_flush = 0;
|
||||
|
||||
if (pe->num_dirty == 0) return 0;
|
||||
if (pe->num_dirty == 0) return status_t::no_error;
|
||||
|
||||
// if multiple threads are flushing this piece, this assert may fire
|
||||
// this happens if the cache is running full and pieces are started to
|
||||
|
@ -2717,38 +2728,38 @@ namespace libtorrent
|
|||
|
||||
m_disk_cache.maybe_free_piece(pe);
|
||||
|
||||
return 0;
|
||||
return status_t::no_error;
|
||||
}
|
||||
|
||||
int disk_io_thread::do_flush_storage(disk_io_job* j, jobqueue_t& completed_jobs)
|
||||
status_t disk_io_thread::do_flush_storage(disk_io_job* j, jobqueue_t& completed_jobs)
|
||||
{
|
||||
std::unique_lock<std::mutex> l(m_cache_mutex);
|
||||
flush_cache(j->storage.get(), flush_write_cache, completed_jobs, l);
|
||||
return 0;
|
||||
return status_t::no_error;
|
||||
}
|
||||
|
||||
int disk_io_thread::do_trim_cache(disk_io_job*, jobqueue_t& /* completed_jobs */)
|
||||
status_t disk_io_thread::do_trim_cache(disk_io_job*, jobqueue_t& /* completed_jobs */)
|
||||
{
|
||||
//#error implement
|
||||
return 0;
|
||||
return status_t::no_error;
|
||||
}
|
||||
|
||||
int disk_io_thread::do_file_priority(disk_io_job* j, jobqueue_t& /* completed_jobs */ )
|
||||
status_t disk_io_thread::do_file_priority(disk_io_job* j, jobqueue_t& /* completed_jobs */ )
|
||||
{
|
||||
std::unique_ptr<std::vector<std::uint8_t>> p(j->buffer.priorities);
|
||||
j->storage->set_file_priority(*p, j->error);
|
||||
return 0;
|
||||
return status_t::no_error;
|
||||
}
|
||||
|
||||
// this job won't return until all outstanding jobs on this
|
||||
// piece are completed or cancelled and the buffers for it
|
||||
// have been evicted
|
||||
int disk_io_thread::do_clear_piece(disk_io_job* j, jobqueue_t& completed_jobs)
|
||||
status_t disk_io_thread::do_clear_piece(disk_io_job* j, jobqueue_t& completed_jobs)
|
||||
{
|
||||
std::unique_lock<std::mutex> l(m_cache_mutex);
|
||||
|
||||
cached_piece_entry* pe = m_disk_cache.find_piece(j);
|
||||
if (pe == nullptr) return 0;
|
||||
if (pe == nullptr) return status_t::no_error;
|
||||
TORRENT_PIECE_ASSERT(pe->hashing == false, pe);
|
||||
pe->hashing_done = 0;
|
||||
pe->hash.reset();
|
||||
|
@ -2767,11 +2778,11 @@ namespace libtorrent
|
|||
{
|
||||
fail_jobs_impl(storage_error(boost::asio::error::operation_aborted)
|
||||
, jobs, completed_jobs);
|
||||
return 0;
|
||||
return status_t::no_error;
|
||||
}
|
||||
|
||||
m_disk_cache.mark_for_deletion(pe);
|
||||
if (pe->num_blocks == 0) return 0;
|
||||
if (pe->num_blocks == 0) return status_t::no_error;
|
||||
|
||||
// we should always be able to evict the piece, since
|
||||
// this is a fence job
|
||||
|
|
|
@ -5110,7 +5110,7 @@ namespace libtorrent
|
|||
// verified this piece (r.piece)
|
||||
m_disk_thread.async_hash(&t->storage(), r.piece, 0
|
||||
, std::bind(&peer_connection::on_seed_mode_hashed, self()
|
||||
, _1, _2, _3, _4), this);
|
||||
, _1, _2, _3), this);
|
||||
t->verifying(r.piece);
|
||||
continue;
|
||||
}
|
||||
|
@ -5163,8 +5163,8 @@ namespace libtorrent
|
|||
|
||||
// this is called when a previously unchecked piece has been
|
||||
// checked, while in seed-mode
|
||||
void peer_connection::on_seed_mode_hashed(int const
|
||||
, int const piece, sha1_hash const& piece_hash, storage_error const& error)
|
||||
void peer_connection::on_seed_mode_hashed(int const piece
|
||||
, sha1_hash const& piece_hash, storage_error const& error)
|
||||
{
|
||||
TORRENT_ASSERT(is_single_thread());
|
||||
INVARIANT_CHECK;
|
||||
|
|
|
@ -922,10 +922,10 @@ namespace libtorrent
|
|||
return true;
|
||||
}
|
||||
|
||||
int default_storage::move_storage(std::string const& sp, int const flags
|
||||
status_t default_storage::move_storage(std::string const& sp, int const flags
|
||||
, storage_error& ec)
|
||||
{
|
||||
int ret = disk_interface::no_error;
|
||||
status_t ret = status_t::no_error;
|
||||
std::string const save_path = complete(sp);
|
||||
|
||||
// check to see if any of the files exist
|
||||
|
@ -950,7 +950,7 @@ namespace libtorrent
|
|||
ec.ec = err;
|
||||
ec.file = i;
|
||||
ec.operation = storage_error::stat;
|
||||
return disk_interface::file_exist;
|
||||
return status_t::file_exist;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -969,7 +969,7 @@ namespace libtorrent
|
|||
ec.ec = err;
|
||||
ec.file = -1;
|
||||
ec.operation = storage_error::mkdir;
|
||||
return disk_interface::fatal_disk_error;
|
||||
return status_t::fatal_disk_error;
|
||||
}
|
||||
}
|
||||
else if (err)
|
||||
|
@ -977,7 +977,7 @@ namespace libtorrent
|
|||
ec.ec = err;
|
||||
ec.file = -1;
|
||||
ec.operation = storage_error::stat;
|
||||
return disk_interface::fatal_disk_error;
|
||||
return status_t::fatal_disk_error;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -999,7 +999,7 @@ namespace libtorrent
|
|||
|
||||
if (flags == dont_replace && exists(new_path))
|
||||
{
|
||||
if (ret == disk_interface::no_error) ret = disk_interface::need_full_check;
|
||||
if (ret == status_t::no_error) ret = status_t::need_full_check;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1051,7 +1051,7 @@ namespace libtorrent
|
|||
}
|
||||
}
|
||||
|
||||
return disk_interface::fatal_disk_error;
|
||||
return status_t::fatal_disk_error;
|
||||
}
|
||||
|
||||
std::string const old_save_path = m_save_path;
|
||||
|
@ -1363,7 +1363,7 @@ namespace libtorrent
|
|||
void release_files(storage_error&) override {}
|
||||
void delete_files(int, storage_error&) override {}
|
||||
void initialize(storage_error&) override {}
|
||||
int move_storage(std::string const&, int, storage_error&) override { return 0; }
|
||||
status_t move_storage(std::string const&, int, storage_error&) override { return status_t::no_error; }
|
||||
|
||||
int readv(span<file::iovec_t const> bufs
|
||||
, int, int, int, storage_error&) override
|
||||
|
@ -1421,8 +1421,8 @@ namespace libtorrent
|
|||
bool has_any_file(storage_error&) override { return false; }
|
||||
void set_file_priority(std::vector<std::uint8_t> const& /* prio */
|
||||
, storage_error&) override {}
|
||||
int move_storage(std::string const& /* save_path */
|
||||
, int /* flags */, storage_error&) override { return 0; }
|
||||
status_t move_storage(std::string const& /* save_path */
|
||||
, int /* flags */, storage_error&) override { return status_t::no_error; }
|
||||
bool verify_resume_data(add_torrent_params const& /* rd */
|
||||
, std::vector<std::string> const& /* links */
|
||||
, storage_error&) override
|
||||
|
|
|
@ -1926,7 +1926,7 @@ namespace libtorrent
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
void torrent::on_resume_data_checked(int const status
|
||||
void torrent::on_resume_data_checked(status_t const status
|
||||
, storage_error const& error) try
|
||||
{
|
||||
// hold a reference until this function returns
|
||||
|
@ -1946,7 +1946,7 @@ namespace libtorrent
|
|||
|
||||
TORRENT_ASSERT(is_single_thread());
|
||||
|
||||
if (status == disk_interface::fatal_disk_error)
|
||||
if (status == status_t::fatal_disk_error)
|
||||
{
|
||||
TORRENT_ASSERT(m_outstanding_check_files == false);
|
||||
m_add_torrent_params.reset();
|
||||
|
@ -1991,7 +1991,7 @@ namespace libtorrent
|
|||
|
||||
// only report this error if the user actually provided resume data
|
||||
// (i.e. m_add_torrent_params->have_pieces)
|
||||
if ((error || status != 0)
|
||||
if ((error || status != status_t::no_error)
|
||||
&& m_add_torrent_params
|
||||
&& !m_add_torrent_params->have_pieces.empty()
|
||||
&& m_ses.alerts().should_post<fastresume_rejected_alert>())
|
||||
|
@ -2005,10 +2005,10 @@ namespace libtorrent
|
|||
#ifndef TORRENT_DISABLE_LOGGING
|
||||
if (should_log())
|
||||
{
|
||||
if (status != 0)
|
||||
if (status != status_t::no_error)
|
||||
{
|
||||
debug_log("fastresume data rejected: ret: %d (%d) %s"
|
||||
, status, error.ec.value(), error.ec.message().c_str());
|
||||
, static_cast<int>(status), error.ec.value(), error.ec.message().c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2017,7 +2017,7 @@ namespace libtorrent
|
|||
}
|
||||
#endif
|
||||
|
||||
bool should_start_full_check = status != 0;
|
||||
bool should_start_full_check = status != status_t::no_error;
|
||||
|
||||
// if we got a partial pieces bitfield, it means we were in the middle of
|
||||
// checking this torrent. pick it up where we left off
|
||||
|
@ -2035,7 +2035,7 @@ namespace libtorrent
|
|||
// that when the resume data check fails. For instance, if the resume data
|
||||
// is incorrect, but we don't have any files, we skip the check and initialize
|
||||
// the storage to not have anything.
|
||||
if (status == 0)
|
||||
if (status == status_t::no_error)
|
||||
{
|
||||
// there are either no files for this torrent
|
||||
// or the resume_data was accepted
|
||||
|
@ -2190,7 +2190,7 @@ namespace libtorrent
|
|||
, shared_from_this(), _1, _2));
|
||||
}
|
||||
|
||||
void torrent::on_force_recheck(int const status, storage_error const& error) try
|
||||
void torrent::on_force_recheck(status_t const status, storage_error const& error) try
|
||||
{
|
||||
TORRENT_ASSERT(is_single_thread());
|
||||
|
||||
|
@ -2204,7 +2204,7 @@ namespace libtorrent
|
|||
handle_disk_error("force_recheck", error);
|
||||
return;
|
||||
}
|
||||
if (status == 0)
|
||||
if (status == status_t::no_error)
|
||||
{
|
||||
// if there are no files, just start
|
||||
files_checked();
|
||||
|
@ -2252,9 +2252,9 @@ namespace libtorrent
|
|||
for (int i = 0; i < num_outstanding; ++i)
|
||||
{
|
||||
m_ses.disk_thread().async_hash(m_storage.get(), m_checking_piece++
|
||||
, disk_io_job::sequential_access | disk_io_job::volatile_read
|
||||
, disk_interface::sequential_access | disk_interface::volatile_read
|
||||
, std::bind(&torrent::on_piece_hashed
|
||||
, shared_from_this(), _1, _2, _3, _4), reinterpret_cast<void*>(1));
|
||||
, shared_from_this(), _1, _2, _3), reinterpret_cast<void*>(1));
|
||||
if (m_checking_piece >= m_torrent_file->num_pieces()) break;
|
||||
}
|
||||
#ifndef TORRENT_DISABLE_LOGGING
|
||||
|
@ -2264,7 +2264,7 @@ namespace libtorrent
|
|||
|
||||
// This is only used for checking of torrents. i.e. force-recheck or initial checking
|
||||
// of existing files
|
||||
void torrent::on_piece_hashed(int const status, int const piece
|
||||
void torrent::on_piece_hashed(int const piece
|
||||
, sha1_hash const& piece_hash, storage_error const& error) try
|
||||
{
|
||||
TORRENT_ASSERT(is_single_thread());
|
||||
|
@ -2272,22 +2272,11 @@ namespace libtorrent
|
|||
|
||||
if (m_abort) return;
|
||||
|
||||
if (status == disk_interface::disk_check_aborted)
|
||||
{
|
||||
m_checking_piece = 0;
|
||||
m_num_checked_pieces = 0;
|
||||
#ifndef TORRENT_DISABLE_LOGGING
|
||||
debug_log("on_piece_hashed, disk_check_aborted");
|
||||
#endif
|
||||
pause();
|
||||
return;
|
||||
}
|
||||
|
||||
state_updated();
|
||||
|
||||
++m_num_checked_pieces;
|
||||
|
||||
if (status < 0)
|
||||
if (error)
|
||||
{
|
||||
if (error.ec == boost::system::errc::no_such_file_or_directory
|
||||
|| error.ec == boost::asio::error::eof
|
||||
|
@ -2383,9 +2372,9 @@ namespace libtorrent
|
|||
}
|
||||
|
||||
m_ses.disk_thread().async_hash(m_storage.get(), m_checking_piece++
|
||||
, disk_io_job::sequential_access | disk_io_job::volatile_read
|
||||
, disk_interface::sequential_access | disk_interface::volatile_read
|
||||
, std::bind(&torrent::on_piece_hashed
|
||||
, shared_from_this(), _1, _2, _3, _4), reinterpret_cast<void*>(1));
|
||||
, shared_from_this(), _1, _2, _3), reinterpret_cast<void*>(1));
|
||||
#ifndef TORRENT_DISABLE_LOGGING
|
||||
debug_log("on_piece_hashed, m_checking_piece: %d", m_checking_piece);
|
||||
#endif
|
||||
|
@ -3660,39 +3649,25 @@ namespace libtorrent
|
|||
TORRENT_ASSERT(st.total_done >= st.total_wanted_done);
|
||||
}
|
||||
|
||||
void torrent::on_piece_verified(int const status, int const piece
|
||||
void torrent::on_piece_verified(int const piece
|
||||
, sha1_hash const& piece_hash, storage_error const& error) try
|
||||
{
|
||||
TORRENT_ASSERT(is_single_thread());
|
||||
|
||||
if (m_abort) return;
|
||||
|
||||
int ret = status;
|
||||
if (settings().get_bool(settings_pack::disable_hash_checks))
|
||||
{
|
||||
ret = 0;
|
||||
}
|
||||
else if (ret == -1)
|
||||
{
|
||||
handle_disk_error("piece_verified", error);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sha1_hash(piece_hash) != m_torrent_file->hash_for_piece(piece))
|
||||
ret = -2;
|
||||
}
|
||||
bool const passed = settings().get_bool(settings_pack::disable_hash_checks)
|
||||
|| (!error && sha1_hash(piece_hash) == m_torrent_file->hash_for_piece(piece));
|
||||
|
||||
// 0: success, piece passed check
|
||||
// -1: disk failure
|
||||
// -2: piece failed check
|
||||
bool const disk_error = !passed && error;
|
||||
|
||||
if (disk_error) handle_disk_error("piece_verified", error);
|
||||
|
||||
#ifndef TORRENT_DISABLE_LOGGING
|
||||
if (should_log())
|
||||
{
|
||||
debug_log("*** PIECE_FINISHED [ p: %d | chk: %s | size: %d ]"
|
||||
, piece, ((ret == 0)
|
||||
?"passed":ret == -1
|
||||
?"disk failed":"failed")
|
||||
, piece, passed ? "passed" : disk_error ? "disk failed" : "failed"
|
||||
, m_torrent_file->piece_size(piece));
|
||||
}
|
||||
#endif
|
||||
|
@ -3717,7 +3692,11 @@ namespace libtorrent
|
|||
// it passed the check
|
||||
if (!m_picker->is_piece_finished(piece)) return;
|
||||
|
||||
if (ret == 0)
|
||||
if (disk_error)
|
||||
{
|
||||
update_gauge();
|
||||
}
|
||||
else if (passed)
|
||||
{
|
||||
// the following call may cause picker to become invalid
|
||||
// in case we just became a seed
|
||||
|
@ -3726,16 +3705,11 @@ namespace libtorrent
|
|||
// mark it as verified
|
||||
if (m_seed_mode) verified(piece);
|
||||
}
|
||||
else if (ret == -2)
|
||||
else
|
||||
{
|
||||
// piece_failed() will restore the piece
|
||||
piece_failed(piece);
|
||||
}
|
||||
else
|
||||
{
|
||||
TORRENT_ASSERT(ret == -1);
|
||||
update_gauge();
|
||||
}
|
||||
}
|
||||
catch (...) { handle_exception(); }
|
||||
|
||||
|
@ -7778,20 +7752,20 @@ namespace libtorrent
|
|||
}
|
||||
}
|
||||
|
||||
void torrent::on_storage_moved(int const status, std::string const& path
|
||||
void torrent::on_storage_moved(status_t const status, std::string const& path
|
||||
, storage_error const& error) try
|
||||
{
|
||||
TORRENT_ASSERT(is_single_thread());
|
||||
|
||||
m_moving_storage = false;
|
||||
if (status == disk_interface::no_error
|
||||
|| status == disk_interface::need_full_check)
|
||||
if (status == status_t::no_error
|
||||
|| status == status_t::need_full_check)
|
||||
{
|
||||
if (alerts().should_post<storage_moved_alert>())
|
||||
alerts().emplace_alert<storage_moved_alert>(get_handle(), path);
|
||||
m_save_path = path;
|
||||
set_need_save_resume();
|
||||
if (status == disk_interface::need_full_check)
|
||||
if (status == status_t::need_full_check)
|
||||
force_recheck();
|
||||
}
|
||||
else
|
||||
|
@ -10261,7 +10235,7 @@ namespace libtorrent
|
|||
TORRENT_ASSERT(m_storage.get());
|
||||
|
||||
m_ses.disk_thread().async_hash(m_storage.get(), piece, 0
|
||||
, std::bind(&torrent::on_piece_verified, shared_from_this(), _1, _2, _3, _4)
|
||||
, std::bind(&torrent::on_piece_verified, shared_from_this(), _1, _2, _3)
|
||||
, reinterpret_cast<void*>(1));
|
||||
}
|
||||
|
||||
|
|
|
@ -62,8 +62,8 @@ struct test_storage_impl : storage_interface
|
|||
bool has_any_file(storage_error& ec) override { return false; }
|
||||
void set_file_priority(std::vector<std::uint8_t> const& prio
|
||||
, storage_error& ec) override {}
|
||||
int move_storage(std::string const& save_path, int flags
|
||||
, storage_error& ec) override { return 0; }
|
||||
status_t move_storage(std::string const& save_path, int flags
|
||||
, storage_error& ec) override { return status_t::no_error; }
|
||||
bool verify_resume_data(add_torrent_params const& rd
|
||||
, std::vector<std::string> const& links
|
||||
, storage_error& ec) override { return true; }
|
||||
|
|
|
@ -68,23 +68,24 @@ void on_read_piece(int ret, disk_io_job const& j, char const* data, int size)
|
|||
if (ret > 0) TEST_CHECK(std::equal(j.buffer.disk_block, j.buffer.disk_block + ret, data));
|
||||
}
|
||||
|
||||
void on_check_resume_data(int const status, storage_error const& error, bool* done)
|
||||
void on_check_resume_data(status_t const status, storage_error const& error, bool* done)
|
||||
{
|
||||
std::cerr << time_now_string() << " on_check_resume_data ret: " << status;
|
||||
std::cerr << time_now_string() << " on_check_resume_data ret: "
|
||||
<< static_cast<int>(status);
|
||||
switch (status)
|
||||
{
|
||||
case disk_interface::no_error:
|
||||
case status_t::no_error:
|
||||
std::cerr << time_now_string() << " success" << std::endl;
|
||||
break;
|
||||
case disk_interface::fatal_disk_error:
|
||||
case status_t::fatal_disk_error:
|
||||
std::cerr << time_now_string() << " disk error: " << error.ec.message()
|
||||
<< " file: " << error.file << std::endl;
|
||||
break;
|
||||
case disk_interface::need_full_check:
|
||||
case status_t::need_full_check:
|
||||
std::cerr << time_now_string() << " need full check" << std::endl;
|
||||
break;
|
||||
case disk_interface::disk_check_aborted:
|
||||
std::cerr << time_now_string() << " aborted" << std::endl;
|
||||
case status_t::file_exist:
|
||||
std::cerr << time_now_string() << " file exist" << std::endl;
|
||||
break;
|
||||
}
|
||||
std::cerr << std::endl;
|
||||
|
|
Loading…
Reference in New Issue