diff --git a/include/libtorrent/disk_interface.hpp b/include/libtorrent/disk_interface.hpp index 7b3b03f08..bd6b55fdb 100644 --- a/include/libtorrent/disk_interface.hpp +++ b/include/libtorrent/disk_interface.hpp @@ -123,19 +123,26 @@ namespace libtorrent { using pool_file_status = open_file_state; #endif + struct disk_job_flags_tag; + using disk_job_flags_t = flags::bitfield_flag; + struct TORRENT_EXTRA_EXPORT disk_interface { - enum flags_t : std::uint8_t - { - sequential_access = 0x1, + // force making a copy of the cached block, rather + // than getting a reference to the block already in + // the cache. + static constexpr disk_job_flags_t force_copy = 0_bit; - // 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, + // hint that there may be more disk operations with sequential access to + // the file + static constexpr disk_job_flags_t sequential_access = 3_bit; - // don't keep the read block in cache - volatile_read = 0x10, - }; + // don't keep the read block in cache + static constexpr disk_job_flags_t volatile_read = 4_bit; + + // this flag is set on a job when a read operation did + // not hit the disk, but found the data in the read cache. + static constexpr disk_job_flags_t cache_hit = 5_bit; virtual storage_holder new_torrent(storage_constructor_type sc , storage_params p, std::shared_ptr const&) = 0; @@ -143,13 +150,13 @@ namespace libtorrent { virtual storage_interface* get_torrent(storage_index_t) = 0; virtual void async_read(storage_index_t storage, peer_request const& r - , std::function handler - , std::uint8_t flags = 0) = 0; + , std::function handler + , disk_job_flags_t flags = {}) = 0; virtual bool async_write(storage_index_t storage, peer_request const& r , char const* buf, std::shared_ptr o , std::function handler - , std::uint8_t flags = 0) = 0; - virtual void async_hash(storage_index_t storage, piece_index_t piece, std::uint8_t flags + , disk_job_flags_t flags = {}) = 0; + virtual void async_hash(storage_index_t storage, piece_index_t piece, disk_job_flags_t flags , std::function handler) = 0; virtual void async_move_storage(storage_index_t storage, std::string p, move_flags_t flags , std::function handler) = 0; diff --git a/include/libtorrent/disk_io_job.hpp b/include/libtorrent/disk_io_job.hpp index a524b302a..ab23f5015 100644 --- a/include/libtorrent/disk_io_job.hpp +++ b/include/libtorrent/disk_io_job.hpp @@ -42,6 +42,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/aux_/vector.hpp" #include "libtorrent/units.hpp" #include "libtorrent/session_types.hpp" +#include "libtorrent/flags.hpp" #include "libtorrent/aux_/disable_warnings_push.hpp" #include @@ -99,23 +100,15 @@ namespace libtorrent { void call_callback(); - enum flags_t - { - // force making a copy of the cached block, rather - // than getting a reference to the block already in - // the cache. - force_copy = 0x4, + // this is set by the storage object when a fence is raised + // for this job. It means that this no other jobs on the same + // storage will execute in parallel with this one. It's used + // to lower the fence when the job has completed + static constexpr disk_job_flags_t fence = 1_bit; - // this is set by the storage object when a fence is raised - // for this job. It means that this no other jobs on the same - // storage will execute in parallel with this one. It's used - // to lower the fence when the job has completed - fence = 0x8, - - // this job is currently being performed, or it's hanging - // on a cache piece that may be flushed soon - in_progress = 0x20 - }; + // this job is currently being performed, or it's hanging + // on a cache piece that may be flushed soon + static constexpr disk_job_flags_t in_progress = 2_bit; // for write jobs, returns true if its block // is not dirty anymore @@ -136,7 +129,7 @@ namespace libtorrent { // this is called when operation completes - using read_handler = std::function; + using read_handler = std::function; using write_handler = std::function; using hash_handler = std::function; using move_handler = std::function; @@ -200,7 +193,7 @@ namespace libtorrent { status_t ret = status_t::no_error; // flags controlling this job - std::uint8_t flags = 0; + disk_job_flags_t flags{}; move_flags_t move_flags = move_flags_t::always_replace_files; diff --git a/include/libtorrent/disk_io_thread.hpp b/include/libtorrent/disk_io_thread.hpp index 28eabd2fa..99883d294 100644 --- a/include/libtorrent/disk_io_thread.hpp +++ b/include/libtorrent/disk_io_thread.hpp @@ -300,12 +300,12 @@ namespace aux { void async_read(storage_index_t storage, peer_request const& r , std::function handler, std::uint8_t flags = 0) override; + , disk_job_flags_t flags, storage_error const& se)> handler, disk_job_flags_t flags = {}) override; bool async_write(storage_index_t storage, peer_request const& r , char const* buf, std::shared_ptr o , std::function handler - , std::uint8_t flags = 0) override; - void async_hash(storage_index_t storage, piece_index_t piece, std::uint8_t flags + , disk_job_flags_t flags = {}) override; + void async_hash(storage_index_t storage, piece_index_t piece, disk_job_flags_t flags , std::function handler) override; void async_move_storage(storage_index_t storage, std::string p, move_flags_t flags , std::function handler) override; diff --git a/include/libtorrent/peer_connection.hpp b/include/libtorrent/peer_connection.hpp index a86e17485..90310db88 100644 --- a/include/libtorrent/peer_connection.hpp +++ b/include/libtorrent/peer_connection.hpp @@ -65,6 +65,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/piece_block.hpp" #include "libtorrent/peer_info.hpp" #include "libtorrent/aux_/vector.hpp" +#include "libtorrent/disk_interface.hpp" #include #include @@ -758,7 +759,7 @@ namespace aux { void do_update_interest(); void fill_send_buffer(); - void on_disk_read_complete(disk_buffer_holder disk_block, int flags + void on_disk_read_complete(disk_buffer_holder disk_block, disk_job_flags_t flags , storage_error const& error, peer_request const& r, time_point issue_time); void on_disk_write_complete(storage_error const& error , peer_request const &r, std::shared_ptr t); diff --git a/include/libtorrent/torrent.hpp b/include/libtorrent/torrent.hpp index 52f4384b3..89c687de2 100644 --- a/include/libtorrent/torrent.hpp +++ b/include/libtorrent/torrent.hpp @@ -424,7 +424,7 @@ namespace libtorrent { error_code error; }; void read_piece(piece_index_t piece); - void on_disk_read_complete(disk_buffer_holder block, int flags, storage_error const& se + void on_disk_read_complete(disk_buffer_holder block, disk_job_flags_t, storage_error const& se , peer_request const& r, std::shared_ptr rp); storage_mode_t storage_mode() const; diff --git a/src/block_cache.cpp b/src/block_cache.cpp index 3aaf042dd..492ebf5c0 100644 --- a/src/block_cache.cpp +++ b/src/block_cache.cpp @@ -373,7 +373,7 @@ int block_cache::try_read(disk_io_job* j, buffer_allocator_interface& allocator #if TORRENT_USE_ASSERTS p->piece_log.push_back(piece_log_t(j->action, j->d.io.offset / 0x4000)); #endif - cache_hit(p, j->d.io.offset / block_size(), (j->flags & disk_interface::volatile_read) != 0); + cache_hit(p, j->d.io.offset / block_size(), bool(j->flags & disk_interface::volatile_read)); ret = copy_from_piece(p, j, allocator, expect_no_fail); if (ret < 0) return ret; @@ -1253,7 +1253,7 @@ void block_cache::insert_blocks(cached_piece_entry* pe, int block, spanin_use); TORRENT_PIECE_ASSERT(iov.size() > 0, pe); - cache_hit(pe, j->d.io.offset / block_size(), (j->flags & disk_interface::volatile_read) != 0); + cache_hit(pe, j->d.io.offset / block_size(), bool(j->flags & disk_interface::volatile_read)); TORRENT_ASSERT(pe->in_use); @@ -1694,7 +1694,7 @@ int block_cache::copy_from_piece(cached_piece_entry* const pe // if block_offset > 0, we need to read two blocks, and then // copy parts of both, because it's not aligned to the block // boundaries - if (blocks_to_read == 1 && (j->flags & disk_io_job::force_copy) == 0) + if (blocks_to_read == 1 && !(j->flags & disk_interface::force_copy)) { // special case for block aligned request // don't actually copy the buffer, just reference diff --git a/src/disk_io_job.cpp b/src/disk_io_job.cpp index 8bbc626cc..f1ffd10da 100644 --- a/src/disk_io_job.cpp +++ b/src/disk_io_job.cpp @@ -100,6 +100,9 @@ namespace libtorrent { }; } + constexpr disk_job_flags_t disk_io_job::fence; + constexpr disk_job_flags_t disk_io_job::in_progress; + disk_io_job::disk_io_job() : argument(remove_flags_t{}) , piece(0) diff --git a/src/disk_io_thread.cpp b/src/disk_io_thread.cpp index 819949854..ffea93fd7 100644 --- a/src/disk_io_thread.cpp +++ b/src/disk_io_thread.cpp @@ -185,6 +185,11 @@ namespace libtorrent { } // anonymous namespace +constexpr disk_job_flags_t disk_interface::force_copy; +constexpr disk_job_flags_t disk_interface::sequential_access; +constexpr disk_job_flags_t disk_interface::volatile_read; +constexpr disk_job_flags_t disk_interface::cache_hit; + // ------- disk_io_thread ------ disk_io_thread::disk_io_thread(io_service& ios @@ -1559,8 +1564,8 @@ namespace libtorrent { } void disk_io_thread::async_read(storage_index_t storage, peer_request const& r - , std::function handler, std::uint8_t const flags) + , std::function handler, disk_job_flags_t const flags) { TORRENT_ASSERT(r.length <= m_disk_cache.block_size()); TORRENT_ASSERT(r.length <= 16 * 1024); @@ -1672,7 +1677,7 @@ namespace libtorrent { bool disk_io_thread::async_write(storage_index_t const storage, peer_request const& r , char const* buf, std::shared_ptr o , std::function handler - , std::uint8_t const flags) + , disk_job_flags_t const flags) { TORRENT_ASSERT(r.length <= m_disk_cache.block_size()); TORRENT_ASSERT(r.length <= 16 * 1024); @@ -1765,7 +1770,7 @@ namespace libtorrent { } void disk_io_thread::async_hash(storage_index_t const storage - , piece_index_t piece, std::uint8_t flags + , piece_index_t piece, disk_job_flags_t const flags , std::function handler) { disk_io_job* j = allocate_job(job_action_t::hash); @@ -2212,7 +2217,7 @@ namespace libtorrent { #endif int const block_size = m_disk_cache.block_size(); m_disk_cache.cache_hit(pe, j->d.io.offset / block_size - , (j->flags & disk_interface::volatile_read) != 0); + , bool(j->flags & disk_interface::volatile_read)); TORRENT_PIECE_ASSERT(pe->cache_state <= cached_piece_entry::read_lru1 || pe->cache_state == cached_piece_entry::read_lru2, pe); { @@ -2893,7 +2898,7 @@ namespace libtorrent { } else { - TORRENT_ASSERT((fj->flags & disk_io_job::in_progress) == 0); + TORRENT_ASSERT(!(fj->flags & disk_io_job::in_progress)); TORRENT_ASSERT(fj->blocked); } @@ -3270,7 +3275,7 @@ namespace libtorrent { ret += j->storage->job_complete(j, new_jobs); } TORRENT_ASSERT(ret == new_jobs.size()); - TORRENT_ASSERT((j->flags & disk_io_job::in_progress) == 0); + TORRENT_ASSERT(!(j->flags & disk_io_job::in_progress)); #if TORRENT_USE_ASSERTS TORRENT_ASSERT(j->job_posted == false); j->job_posted = true; diff --git a/src/disk_job_fence.cpp b/src/disk_job_fence.cpp index 9946e2774..fc6d68f68 100644 --- a/src/disk_job_fence.cpp +++ b/src/disk_job_fence.cpp @@ -81,7 +81,7 @@ namespace libtorrent { namespace aux { // executing currently, we should add the fence job. if (m_outstanding_jobs == 0 && jobs.empty()) { - TORRENT_ASSERT((bj->flags & disk_io_job::in_progress) == 0); + TORRENT_ASSERT(!(bj->flags & disk_io_job::in_progress)); bj->flags |= disk_io_job::in_progress; ++m_outstanding_jobs; ++ret; @@ -98,7 +98,7 @@ namespace libtorrent { namespace aux { } return ret; } - TORRENT_ASSERT((bj->flags & disk_io_job::in_progress) == 0); + TORRENT_ASSERT(!(bj->flags & disk_io_job::in_progress)); bj->flags |= disk_io_job::in_progress; ++m_outstanding_jobs; @@ -125,7 +125,7 @@ namespace libtorrent { namespace aux { disk_io_job *bj = static_cast(m_blocked_jobs.pop_front()); TORRENT_ASSERT(bj->flags & disk_io_job::fence); - TORRENT_ASSERT((bj->flags & disk_io_job::in_progress) == 0); + TORRENT_ASSERT(!(bj->flags & disk_io_job::in_progress)); bj->flags |= disk_io_job::in_progress; ++m_outstanding_jobs; @@ -149,7 +149,7 @@ namespace libtorrent { namespace aux { // this job still needs to get queued up if (m_has_fence == 0) { - TORRENT_ASSERT((j->flags & disk_io_job::in_progress) == 0); + TORRENT_ASSERT(!(j->flags & disk_io_job::in_progress)); j->flags |= disk_io_job::in_progress; ++m_outstanding_jobs; return false; @@ -183,7 +183,7 @@ namespace libtorrent { namespace aux { int disk_job_fence::raise_fence(disk_io_job* j, disk_io_job* fj , counters& cnt) { - TORRENT_ASSERT((j->flags & disk_io_job::fence) == 0); + TORRENT_ASSERT(!(j->flags & disk_io_job::fence)); j->flags |= disk_io_job::fence; std::lock_guard l(m_mutex); diff --git a/src/peer_connection.cpp b/src/peer_connection.cpp index fd9dc887e..d74e476d8 100644 --- a/src/peer_connection.cpp +++ b/src/peer_connection.cpp @@ -5121,7 +5121,7 @@ namespace libtorrent { #endif // this means we're in seed mode and we haven't yet // verified this piece (r.piece) - m_disk_thread.async_hash(t->storage(), r.piece, 0 + m_disk_thread.async_hash(t->storage(), r.piece, {} , std::bind(&peer_connection::on_seed_mode_hashed, self() , _1, _2, _3)); t->verifying(r.piece); @@ -5232,7 +5232,7 @@ namespace libtorrent { } void peer_connection::on_disk_read_complete(disk_buffer_holder buffer - , int const flags, storage_error const& error + , disk_job_flags_t const flags, storage_error const& error , peer_request const& r, time_point issue_time) { TORRENT_ASSERT(is_single_thread()); @@ -5312,7 +5312,7 @@ namespace libtorrent { // if it's rare enough to make it into the suggested piece // push another piece out if (m_settings.get_int(settings_pack::suggest_mode) == settings_pack::suggest_read_cache - && (flags & disk_interface::cache_hit) == 0) + && !(flags & disk_interface::cache_hit)) { t->add_suggest_piece(r.piece); } diff --git a/src/smart_ban.cpp b/src/smart_ban.cpp index cb99c916f..254afdf31 100644 --- a/src/smart_ban.cpp +++ b/src/smart_ban.cpp @@ -151,7 +151,7 @@ namespace { m_torrent.session().disk_thread().async_read(m_torrent.storage(), r , std::bind(&smart_ban_plugin::on_read_failed_block , shared_from_this(), pb, i->address(), _1, r.length, _2, _3) - , disk_io_job::force_copy); + , disk_interface::force_copy); } r.start += 16*1024; @@ -173,7 +173,7 @@ namespace { }; void on_read_failed_block(piece_block b, address a - , disk_buffer_holder buffer, int const block_size, int + , disk_buffer_holder buffer, int const block_size, disk_job_flags_t , storage_error const& error) { TORRENT_ASSERT(m_torrent.session().is_single_thread()); @@ -255,7 +255,7 @@ namespace { } void on_read_ok_block(std::pair b, address a - , disk_buffer_holder buffer, int const block_size, int + , disk_buffer_holder buffer, int const block_size, disk_job_flags_t , storage_error const& error) { TORRENT_ASSERT(m_torrent.session().is_single_thread()); diff --git a/src/torrent.cpp b/src/torrent.cpp index fcc61fade..5a05050a5 100644 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -1162,7 +1162,7 @@ namespace libtorrent { catch (...) { handle_exception(); } void torrent::on_disk_read_complete(disk_buffer_holder buffer - , int, storage_error const& se + , disk_job_flags_t, storage_error const& se , peer_request const& r, std::shared_ptr rp) try { // hold a reference until this function returns @@ -10185,7 +10185,7 @@ namespace libtorrent { TORRENT_ASSERT(m_storage); - m_ses.disk_thread().async_hash(m_storage, piece, 0 + m_ses.disk_thread().async_hash(m_storage, piece, {} , std::bind(&torrent::on_piece_verified, shared_from_this(), _1, _2, _3)); }