diff options
author | Niall Douglas (s [underscore] sourceforge {at} nedprod [dot] com) <spamtrap@nedprod.com> | 2020-04-09 13:07:17 +0300 |
---|---|---|
committer | Niall Douglas (s [underscore] sourceforge {at} nedprod [dot] com) <spamtrap@nedprod.com> | 2020-04-09 13:07:17 +0300 |
commit | 62fd7f4f4059cba9aed1962609e75d0a1ea46c7d (patch) | |
tree | c732755c1f80c094ea76f98377a163f1896e90de | |
parent | 44f0a6d7b7f2c2de8215b20b541ef27a3a367c56 (diff) |
More progress on merging resumable_io branch.
25 files changed, 239 insertions, 84 deletions
diff --git a/cmake/headers.cmake b/cmake/headers.cmake index 8d7eda08..116cc3a9 100644 --- a/cmake/headers.cmake +++ b/cmake/headers.cmake @@ -19,22 +19,20 @@ set(llfio_HEADERS "include/llfio/v2.0/algorithm/shared_fs_mutex/memory_map.hpp" "include/llfio/v2.0/algorithm/shared_fs_mutex/safe_byte_ranges.hpp" "include/llfio/v2.0/algorithm/trivial_vector.hpp" - "include/llfio/v2.0/async_file_handle.hpp" "include/llfio/v2.0/config.hpp" "include/llfio/v2.0/deadline.h" "include/llfio/v2.0/detail/impl/cached_parent_handle_adapter.ipp" "include/llfio/v2.0/detail/impl/config.ipp" "include/llfio/v2.0/detail/impl/fast_random_file_handle.ipp" + "include/llfio/v2.0/detail/impl/io_multiplexer.ipp" "include/llfio/v2.0/detail/impl/path_discovery.ipp" "include/llfio/v2.0/detail/impl/path_view.ipp" - "include/llfio/v2.0/detail/impl/posix/async_file_handle.ipp" "include/llfio/v2.0/detail/impl/posix/directory_handle.ipp" "include/llfio/v2.0/detail/impl/posix/file_handle.ipp" "include/llfio/v2.0/detail/impl/posix/fs_handle.ipp" "include/llfio/v2.0/detail/impl/posix/handle.ipp" "include/llfio/v2.0/detail/impl/posix/import.hpp" "include/llfio/v2.0/detail/impl/posix/io_handle.ipp" - "include/llfio/v2.0/detail/impl/posix/io_service.ipp" "include/llfio/v2.0/detail/impl/posix/lockable_io_handle.ipp" "include/llfio/v2.0/detail/impl/posix/map_handle.ipp" "include/llfio/v2.0/detail/impl/posix/mapped_file_handle.ipp" @@ -49,14 +47,12 @@ set(llfio_HEADERS "include/llfio/v2.0/detail/impl/remove_all.ipp" "include/llfio/v2.0/detail/impl/safe_byte_ranges.ipp" "include/llfio/v2.0/detail/impl/storage_profile.ipp" - "include/llfio/v2.0/detail/impl/windows/async_file_handle.ipp" "include/llfio/v2.0/detail/impl/windows/directory_handle.ipp" "include/llfio/v2.0/detail/impl/windows/file_handle.ipp" "include/llfio/v2.0/detail/impl/windows/fs_handle.ipp" "include/llfio/v2.0/detail/impl/windows/handle.ipp" "include/llfio/v2.0/detail/impl/windows/import.hpp" "include/llfio/v2.0/detail/impl/windows/io_handle.ipp" - "include/llfio/v2.0/detail/impl/windows/io_service.ipp" "include/llfio/v2.0/detail/impl/windows/lockable_io_handle.ipp" "include/llfio/v2.0/detail/impl/windows/map_handle.ipp" "include/llfio/v2.0/detail/impl/windows/mapped_file_handle.ipp" @@ -74,7 +70,7 @@ set(llfio_HEADERS "include/llfio/v2.0/fs_handle.hpp" "include/llfio/v2.0/handle.hpp" "include/llfio/v2.0/io_handle.hpp" - "include/llfio/v2.0/io_service.hpp" + "include/llfio/v2.0/io_multiplexer.hpp" "include/llfio/v2.0/llfio.hpp" "include/llfio/v2.0/lockable_io_handle.hpp" "include/llfio/v2.0/logging.hpp" diff --git a/include/llfio/revision.hpp b/include/llfio/revision.hpp index e5dfaad6..d9be1575 100644 --- a/include/llfio/revision.hpp +++ b/include/llfio/revision.hpp @@ -1,4 +1,4 @@ // Note the second line of this file must ALWAYS be the git SHA, third line ALWAYS the git SHA update time -#define LLFIO_PREVIOUS_COMMIT_REF c029e57e5c0619190fce55bd8d072cf6ca1155cf -#define LLFIO_PREVIOUS_COMMIT_DATE "2020-04-07 17:13:49 +00:00" -#define LLFIO_PREVIOUS_COMMIT_UNIQUE c029e57e +#define LLFIO_PREVIOUS_COMMIT_REF 44f0a6d7b7f2c2de8215b20b541ef27a3a367c56 +#define LLFIO_PREVIOUS_COMMIT_DATE "2020-04-07 20:36:05 +00:00" +#define LLFIO_PREVIOUS_COMMIT_UNIQUE 44f0a6d7 diff --git a/include/llfio/v2.0/algorithm/handle_adapter/combining.hpp b/include/llfio/v2.0/algorithm/handle_adapter/combining.hpp index 4feff29e..33c66199 100644 --- a/include/llfio/v2.0/algorithm/handle_adapter/combining.hpp +++ b/include/llfio/v2.0/algorithm/handle_adapter/combining.hpp @@ -40,8 +40,8 @@ namespace algorithm { file_handle_wrapper() = default; using file_handle::file_handle; - file_handle_wrapper(native_handle_type nativeh, io_handle::caching _caching, io_handle::flag flags) - : file_handle(nativeh, 0, 0, _caching, flags) + file_handle_wrapper(native_handle_type nativeh, io_handle::caching _caching, io_handle::flag flags, io_multiplexer *ctx) + : file_handle(nativeh, 0, 0, _caching, flags, ctx) { } }; diff --git a/include/llfio/v2.0/detail/impl/path_view.ipp b/include/llfio/v2.0/detail/impl/path_view.ipp index 4e34b948..0ae773ac 100644 --- a/include/llfio/v2.0/detail/impl/path_view.ipp +++ b/include/llfio/v2.0/detail/impl/path_view.ipp @@ -235,7 +235,14 @@ namespace detail abort(); #endif } - char *reencode_path_to(size_t &toallocate, char *dest_buffer, size_t dest_buffer_length, const char16_t *src_buffer, size_t src_buffer_length) { return _reencode_path_to(toallocate, dest_buffer, dest_buffer_length, src_buffer, src_buffer_length); } + char *reencode_path_to(size_t &toallocate, char *dest_buffer, size_t dest_buffer_length, const char16_t *src_buffer, size_t src_buffer_length) + { +#if __cplusplus >= 202000 || _HAS_CXX20 + return (char *) _reencode_path_to(toallocate, (char8_t *) dest_buffer, dest_buffer_length, src_buffer, src_buffer_length); +#else + return _reencode_path_to(toallocate, dest_buffer, dest_buffer_length, src_buffer, src_buffer_length); +#endif + } wchar_t *reencode_path_to(size_t & /*unused*/, wchar_t * /*unused*/, size_t /*unused*/, const LLFIO_V2_NAMESPACE::byte * /*unused*/, size_t /*unused*/) { diff --git a/include/llfio/v2.0/detail/impl/posix/directory_handle.ipp b/include/llfio/v2.0/detail/impl/posix/directory_handle.ipp index a59921c7..05a2f53a 100644 --- a/include/llfio/v2.0/detail/impl/posix/directory_handle.ipp +++ b/include/llfio/v2.0/detail/impl/posix/directory_handle.ipp @@ -181,7 +181,7 @@ result<directory_handle> directory_handle::reopen(mode mode_, caching caching_, // Fast path if(mode_ == mode::unchanged && caching_ == caching::unchanged) { - result<directory_handle> ret(directory_handle(native_handle_type(), _devid, _inode, _caching, _flags)); + result<directory_handle> ret(directory_handle(native_handle_type(), _devid, _inode, kernel_caching(), _flags)); ret.value()._v.behaviour = _v.behaviour; ret.value()._v.fd = ::fcntl(_v.fd, F_DUPFD_CLOEXEC, 0); if(-1 == ret.value()._v.fd) @@ -248,7 +248,7 @@ result<directory_handle> directory_handle::reopen(mode mode_, caching caching_, LLFIO_HEADERS_ONLY_MEMFUNC_SPEC result<path_handle> directory_handle::clone_to_path_handle() const noexcept { LLFIO_LOG_FUNCTION_CALL(this); - result<path_handle> ret(path_handle(native_handle_type(), _caching, _flags)); + result<path_handle> ret(path_handle(native_handle_type(), kernel_caching(), _flags)); ret.value()._v.behaviour = _v.behaviour; ret.value()._v.fd = ::fcntl(_v.fd, F_DUPFD_CLOEXEC, 0); if(-1 == ret.value()._v.fd) diff --git a/include/llfio/v2.0/detail/impl/posix/file_handle.ipp b/include/llfio/v2.0/detail/impl/posix/file_handle.ipp index 94edbb6e..15299d4a 100644 --- a/include/llfio/v2.0/detail/impl/posix/file_handle.ipp +++ b/include/llfio/v2.0/detail/impl/posix/file_handle.ipp @@ -30,7 +30,7 @@ LLFIO_V2_NAMESPACE_BEGIN result<file_handle> file_handle::file(const path_handle &base, file_handle::path_view_type path, file_handle::mode _mode, file_handle::creation _creation, file_handle::caching _caching, file_handle::flag flags) noexcept { - result<file_handle> ret(file_handle(native_handle_type(), 0, 0, _caching, flags)); + result<file_handle> ret(file_handle(native_handle_type(), 0, 0, _caching, flags, nullptr)); native_handle_type &nativeh = ret.value()._v; LLFIO_LOG_FUNCTION_CALL(&ret); nativeh.behaviour |= native_handle_type::disposition::file; @@ -104,7 +104,7 @@ result<file_handle> file_handle::temp_inode(const path_handle &dirh, mode _mode, caching _caching = caching::temporary; // No need to check inode before unlink flags |= flag::unlink_on_first_close | flag::disable_safety_unlinks; - result<file_handle> ret(file_handle(native_handle_type(), 0, 0, _caching, flags)); + result<file_handle> ret(file_handle(native_handle_type(), 0, 0, _caching, flags, nullptr)); native_handle_type &nativeh = ret.value()._v; LLFIO_LOG_FUNCTION_CALL(&ret); nativeh.behaviour |= native_handle_type::disposition::file; @@ -164,8 +164,7 @@ result<file_handle> file_handle::reopen(mode mode_, caching caching_, deadline d // Fast path if(mode_ == mode::unchanged) { - result<file_handle> ret(file_handle(native_handle_type(), _devid, _inode, caching_, _flags)); - ret.value()._service = _service; + result<file_handle> ret(file_handle(native_handle_type(), _devid, _inode, caching_, _flags, _ctx)); ret.value()._v.behaviour = _v.behaviour; ret.value()._v.fd = ::fcntl(_v.fd, F_DUPFD_CLOEXEC, 0); if(-1 == ret.value()._v.fd) diff --git a/include/llfio/v2.0/detail/impl/posix/handle.ipp b/include/llfio/v2.0/detail/impl/posix/handle.ipp index b42c1508..9b5cfd76 100644 --- a/include/llfio/v2.0/detail/impl/posix/handle.ipp +++ b/include/llfio/v2.0/detail/impl/posix/handle.ipp @@ -161,7 +161,7 @@ result<void> handle::close() noexcept result<handle> handle::clone() const noexcept { LLFIO_LOG_FUNCTION_CALL(this); - result<handle> ret(handle(native_handle_type(), _caching, _flags)); + result<handle> ret(handle(native_handle_type(), kernel_caching(), _flags)); ret.value()._v.behaviour = _v.behaviour; ret.value()._v.fd = ::fcntl(_v.fd, F_DUPFD_CLOEXEC, 0); if(-1 == ret.value()._v.fd) diff --git a/include/llfio/v2.0/detail/impl/posix/map_handle.ipp b/include/llfio/v2.0/detail/impl/posix/map_handle.ipp index 2f383f49..b0c94118 100644 --- a/include/llfio/v2.0/detail/impl/posix/map_handle.ipp +++ b/include/llfio/v2.0/detail/impl/posix/map_handle.ipp @@ -170,7 +170,7 @@ result<void> map_handle::close() noexcept { if(is_writable() && (_flag & section_handle::flag::barrier_on_close)) { - OUTCOME_TRYV(map_handle::barrier({}, barrier_kind::wait_all)); + OUTCOME_TRYV(map_handle::barrier(barrier_kind::wait_all)); } // printf("%d munmap %p-%p\n", getpid(), _addr, _addr+_reservation); if(-1 == ::munmap(_addr, _reservation)) diff --git a/include/llfio/v2.0/detail/impl/posix/path_handle.ipp b/include/llfio/v2.0/detail/impl/posix/path_handle.ipp index d2c71911..99867ecf 100644 --- a/include/llfio/v2.0/detail/impl/posix/path_handle.ipp +++ b/include/llfio/v2.0/detail/impl/posix/path_handle.ipp @@ -30,7 +30,7 @@ LLFIO_V2_NAMESPACE_BEGIN result<path_handle> path_handle::path(const path_handle &base, path_handle::path_view_type path) noexcept { - result<path_handle> ret{path_handle(native_handle_type())}; + result<path_handle> ret(in_place_type<path_handle>); native_handle_type &nativeh = ret.value()._v; LLFIO_LOG_FUNCTION_CALL(&ret); nativeh.behaviour |= native_handle_type::disposition::directory; diff --git a/include/llfio/v2.0/detail/impl/posix/pipe_handle.ipp b/include/llfio/v2.0/detail/impl/posix/pipe_handle.ipp index ef200448..321c801e 100644 --- a/include/llfio/v2.0/detail/impl/posix/pipe_handle.ipp +++ b/include/llfio/v2.0/detail/impl/posix/pipe_handle.ipp @@ -29,7 +29,7 @@ LLFIO_V2_NAMESPACE_BEGIN result<pipe_handle> pipe_handle::pipe(pipe_handle::path_view_type path, pipe_handle::mode _mode, pipe_handle::creation _creation, pipe_handle::caching _caching, pipe_handle::flag flags, const path_handle &base) noexcept { - result<pipe_handle> ret(pipe_handle(native_handle_type(), 0, 0, _caching, flags)); + result<pipe_handle> ret(pipe_handle(native_handle_type(), 0, 0, _caching, flags, nullptr)); native_handle_type &nativeh = ret.value()._v; LLFIO_LOG_FUNCTION_CALL(&ret); nativeh.behaviour |= native_handle_type::disposition::pipe; @@ -129,7 +129,7 @@ result<pipe_handle> pipe_handle::pipe(pipe_handle::path_view_type path, pipe_han result<std::pair<pipe_handle, pipe_handle>> pipe_handle::anonymous_pipe(caching _caching, flag flags) noexcept { - result<std::pair<pipe_handle, pipe_handle>> ret(pipe_handle(native_handle_type(), 0, 0, _caching, flags), pipe_handle(native_handle_type(), 0, 0, _caching, flags)); + result<std::pair<pipe_handle, pipe_handle>> ret(pipe_handle(native_handle_type(), 0, 0, _caching, flags, nullptr), pipe_handle(native_handle_type(), 0, 0, _caching, flags, nullptr)); native_handle_type &readnativeh = ret.value().first._v, &writenativeh = ret.value().second._v; LLFIO_LOG_FUNCTION_CALL(&ret); OUTCOME_TRY(readattribs, attribs_from_handle_mode_caching_and_flags(readnativeh, mode::read, creation::open_existing, _caching, flags)); diff --git a/include/llfio/v2.0/detail/impl/remove_all.ipp b/include/llfio/v2.0/detail/impl/remove_all.ipp index 9e99cbfe..373c8a49 100644 --- a/include/llfio/v2.0/detail/impl/remove_all.ipp +++ b/include/llfio/v2.0/detail/impl/remove_all.ipp @@ -44,7 +44,7 @@ namespace algorithm { namespace detail { - LLFIO_HEADERS_ONLY_FUNC_SPEC result<size_t> remove_all(directory_handle &&topdirh, LLFIO_V2_NAMESPACE::detail::function_ptr<result<void>(remove_all_callback_reason reason, remove_all_callback_arg arg1, remove_all_callback_arg arg2)> _callback, size_t threads) noexcept + LLFIO_HEADERS_ONLY_FUNC_SPEC result<size_t> remove_all(directory_handle &&topdirh, LLFIO_V2_NAMESPACE::function_ptr<result<void>(remove_all_callback_reason reason, remove_all_callback_arg arg1, remove_all_callback_arg arg2)> _callback, size_t threads) noexcept { #ifdef _WIN32 windows_nt_kernel::init(); diff --git a/include/llfio/v2.0/detail/impl/windows/directory_handle.ipp b/include/llfio/v2.0/detail/impl/windows/directory_handle.ipp index 9b3d2dcf..7a3b2831 100644 --- a/include/llfio/v2.0/detail/impl/windows/directory_handle.ipp +++ b/include/llfio/v2.0/detail/impl/windows/directory_handle.ipp @@ -206,7 +206,7 @@ result<directory_handle> directory_handle::directory(const path_handle &base, pa result<directory_handle> directory_handle::reopen(mode mode_, caching caching_, deadline /* unused */) const noexcept { LLFIO_LOG_FUNCTION_CALL(this); - result<directory_handle> ret(directory_handle(native_handle_type(), _devid, _inode, _caching, _flags)); + result<directory_handle> ret(directory_handle(native_handle_type(), _devid, _inode, kernel_caching(), _flags)); OUTCOME_TRY(do_clone_handle(ret.value()._v, _v, mode_, caching_, _flags, true)); return ret; } @@ -214,7 +214,7 @@ result<directory_handle> directory_handle::reopen(mode mode_, caching caching_, LLFIO_HEADERS_ONLY_MEMFUNC_SPEC result<path_handle> directory_handle::clone_to_path_handle() const noexcept { LLFIO_LOG_FUNCTION_CALL(this); - result<path_handle> ret(path_handle(native_handle_type(), _caching, _flags)); + result<path_handle> ret(path_handle(native_handle_type(), kernel_caching(), _flags)); ret.value()._v.behaviour = _v.behaviour; if(DuplicateHandle(GetCurrentProcess(), _v.h, GetCurrentProcess(), &ret.value()._v.h, 0, 0, DUPLICATE_SAME_ACCESS) == 0) { @@ -250,7 +250,7 @@ namespace detail return ntkernel_error(ntstat); } // Return as a file handle so the direct relink and unlink are used - return file_handle(nativeh, 0, 0, file_handle::caching::all); + return file_handle(nativeh, 0, 0, file_handle::caching::all, file_handle::flag::none, nullptr); } } // namespace detail diff --git a/include/llfio/v2.0/detail/impl/windows/file_handle.ipp b/include/llfio/v2.0/detail/impl/windows/file_handle.ipp index 9eda9921..70324d7e 100644 --- a/include/llfio/v2.0/detail/impl/windows/file_handle.ipp +++ b/include/llfio/v2.0/detail/impl/windows/file_handle.ipp @@ -31,7 +31,7 @@ result<file_handle> file_handle::file(const path_handle &base, file_handle::path { windows_nt_kernel::init(); using namespace windows_nt_kernel; - result<file_handle> ret(file_handle(native_handle_type(), 0, 0, _caching, flags)); + result<file_handle> ret(in_place_type<file_handle>); native_handle_type &nativeh = ret.value()._v; LLFIO_LOG_FUNCTION_CALL(&ret); nativeh.behaviour |= native_handle_type::disposition::file; @@ -185,7 +185,7 @@ result<file_handle> file_handle::temp_inode(const path_handle &dirh, mode _mode, caching _caching = caching::temporary; // No need to rename to random on unlink or check inode before unlink flags |= flag::disable_safety_unlinks | flag::win_disable_unlink_emulation; - result<file_handle> ret(file_handle(native_handle_type(), 0, 0, _caching, flags)); + result<file_handle> ret(in_place_type<file_handle>); native_handle_type &nativeh = ret.value()._v; LLFIO_LOG_FUNCTION_CALL(&ret); nativeh.behaviour |= native_handle_type::disposition::file; @@ -297,8 +297,8 @@ result<file_handle> file_handle::temp_inode(const path_handle &dirh, mode _mode, result<file_handle> file_handle::reopen(mode mode_, caching caching_, deadline /*unused*/) const noexcept { LLFIO_LOG_FUNCTION_CALL(this); - result<file_handle> ret(file_handle(native_handle_type(), _devid, _inode, caching_, _flags)); - ret.value()._service = _service; + result<file_handle> ret(in_place_type<file_handle>); + ret.value()._ctx = _ctx; OUTCOME_TRY(do_clone_handle(ret.value()._v, _v, mode_, caching_, _flags)); return ret; } diff --git a/include/llfio/v2.0/detail/impl/windows/io_handle.ipp b/include/llfio/v2.0/detail/impl/windows/io_handle.ipp index ab01e866..e537f833 100644 --- a/include/llfio/v2.0/detail/impl/windows/io_handle.ipp +++ b/include/llfio/v2.0/detail/impl/windows/io_handle.ipp @@ -32,10 +32,10 @@ size_t io_handle::_do_max_buffers() const noexcept return 1; // TODO FIXME support ReadFileScatter/WriteFileGather } -template <class BuffersType> inline bool do_cancel(const native_handle_type &nativeh, span<typename detail::io_operation_connection::_EXTENDED_IO_STATUS_BLOCK> ols, io_handle::io_request<BuffersType> reqs) noexcept +template <class BuffersType> inline bool do_cancel(const native_handle_type &nativeh, span<windows_nt_kernel::IO_STATUS_BLOCK> ols, io_handle::io_request<BuffersType> reqs) noexcept { using namespace windows_nt_kernel; - using EIOSB = typename detail::io_operation_connection::_EXTENDED_IO_STATUS_BLOCK; + using EIOSB = windows_nt_kernel::IO_STATUS_BLOCK; bool did_cancel = false; ols = span<EIOSB>(ols.data(), reqs.buffers.size()); for(auto &ol : ols) @@ -45,7 +45,7 @@ template <class BuffersType> inline bool do_cancel(const native_handle_type &nat // No need to cancel an i/o never begun continue; } - NTSTATUS ntstat = ntcancel_pending_io(nativeh.h, (IO_STATUS_BLOCK &) ol); + NTSTATUS ntstat = ntcancel_pending_io(nativeh.h, ol); if(ntstat < 0 && ntstat != (NTSTATUS) 0xC0000120 /*STATUS_CANCELLED*/) { LLFIO_LOG_FATAL(nullptr, "Failed to cancel earlier i/o"); @@ -60,19 +60,18 @@ template <class BuffersType> inline bool do_cancel(const native_handle_type &nat } template <bool blocking, class Syscall, class BuffersType> -inline bool do_read_write(io_handle::io_result<BuffersType> &ret, size_t &scheduled, Syscall &&syscall, const native_handle_type &nativeh, windows_nt_kernel::PIO_APC_ROUTINE routine, detail::io_operation_connection *op, span<typename detail::io_operation_connection::_EXTENDED_IO_STATUS_BLOCK> ols, - io_handle::io_request<BuffersType> reqs, deadline d) noexcept +inline bool do_read_write(io_handle::io_result<BuffersType> &ret, size_t &scheduled, Syscall &&syscall, const native_handle_type &nativeh, windows_nt_kernel::PIO_APC_ROUTINE routine, span<windows_nt_kernel::IO_STATUS_BLOCK> ols, io_handle::io_request<BuffersType> reqs, deadline d) noexcept { using namespace windows_nt_kernel; - using EIOSB = typename detail::io_operation_connection::_EXTENDED_IO_STATUS_BLOCK; + using EIOSB = windows_nt_kernel::IO_STATUS_BLOCK; if(d && !nativeh.is_nonblocking()) { - ret=errc::not_supported; + ret = errc::not_supported; return true; } if(reqs.buffers.size() > 64) { - ret=errc::argument_list_too_long; + ret = errc::argument_list_too_long; return true; } LLFIO_WIN_DEADLINE_TO_SLEEP_INIT(d); @@ -81,6 +80,7 @@ inline bool do_read_write(io_handle::io_result<BuffersType> &ret, size_t &schedu auto ol_it = ols.begin(); for(auto &req : reqs.buffers) { + (void) req; EIOSB &ol = *ol_it++; ol.Status = -1; } @@ -121,11 +121,11 @@ inline bool do_read_write(io_handle::io_result<BuffersType> &ret, size_t &schedu #endif reqs.offset += req.size(); ol.Status = 0x103 /*STATUS_PENDING*/; - NTSTATUS ntstat = syscall(nativeh.h, nullptr, routine, op, (PIO_STATUS_BLOCK) &ol, (PVOID) req.data(), static_cast<DWORD>(req.size()), &offset, nullptr); + NTSTATUS ntstat = syscall(nativeh.h, nullptr, routine, nullptr, &ol, (PVOID) req.data(), static_cast<DWORD>(req.size()), &offset, nullptr); if(ntstat < 0 && ntstat != 0x103 /*STATUS_PENDING*/) { InterlockedCompareExchange(&ol.Status, ntstat, 0x103 /*STATUS_PENDING*/); - ret=ntkernel_error(ntstat); + ret = ntkernel_error(ntstat); return true; } ++scheduled; @@ -137,7 +137,7 @@ inline bool do_read_write(io_handle::io_result<BuffersType> &ret, size_t &schedu { deadline nd; LLFIO_DEADLINE_TO_PARTIAL_DEADLINE(nd, d); - if(STATUS_TIMEOUT == ntwait(nativeh.h, (IO_STATUS_BLOCK &) ol, nd)) + if(STATUS_TIMEOUT == ntwait(nativeh.h, ol, nd)) { // ntwait cancels the i/o, undoer will cancel all the other i/o auto r = [&]() -> result<void> { @@ -170,7 +170,7 @@ inline bool do_read_write(io_handle::io_result<BuffersType> &ret, size_t &schedu assert(ols[n].Status != -1); if(ols[n].Status < 0) { - ret= ntkernel_error(static_cast<NTSTATUS>(ols[n].Status)); + ret = ntkernel_error(static_cast<NTSTATUS>(ols[n].Status)); return true; } reqs.buffers[n] = {reqs.buffers[n].data(), ols[n].Information}; @@ -187,11 +187,11 @@ io_handle::io_result<io_handle::buffers_type> io_handle::_do_read(io_handle::io_ windows_nt_kernel::init(); using namespace windows_nt_kernel; LLFIO_LOG_FUNCTION_CALL(this); - using EIOSB = typename detail::io_operation_connection::_EXTENDED_IO_STATUS_BLOCK; + using EIOSB = windows_nt_kernel::IO_STATUS_BLOCK; std::array<EIOSB, 64> _ols{}; io_handle::io_result<io_handle::buffers_type> ret(reqs.buffers); size_t scheduled = 0; - do_read_write<true>(ret, scheduled, NtReadFile, _v, nullptr, nullptr, {_ols.data(), _ols.size()}, reqs, d); + do_read_write<true>(ret, scheduled, NtReadFile, _v, nullptr, {_ols.data(), _ols.size()}, reqs, d); return ret; } @@ -200,11 +200,11 @@ io_handle::io_result<io_handle::const_buffers_type> io_handle::_do_write(io_hand windows_nt_kernel::init(); using namespace windows_nt_kernel; LLFIO_LOG_FUNCTION_CALL(this); - using EIOSB = typename detail::io_operation_connection::_EXTENDED_IO_STATUS_BLOCK; + using EIOSB = windows_nt_kernel::IO_STATUS_BLOCK; std::array<EIOSB, 64> _ols{}; io_handle::io_result<io_handle::const_buffers_type> ret(reqs.buffers); size_t scheduled = 0; - do_read_write<true>(ret, scheduled, NtWriteFile, _v, nullptr, nullptr, {_ols.data(), _ols.size()}, reqs, d); + do_read_write<true>(ret, scheduled, NtWriteFile, _v, nullptr, {_ols.data(), _ols.size()}, reqs, d); return ret; } @@ -218,10 +218,10 @@ io_handle::io_result<io_handle::const_buffers_type> io_handle::_do_barrier(io_ha return errc::not_supported; } LLFIO_WIN_DEADLINE_TO_SLEEP_INIT(d); - using EIOSB = typename detail::io_operation_connection::_EXTENDED_IO_STATUS_BLOCK; + using EIOSB = windows_nt_kernel::IO_STATUS_BLOCK; EIOSB ol{}; memset(&ol, 0, sizeof(ol)); - auto *isb = reinterpret_cast<IO_STATUS_BLOCK *>(&ol); + auto *isb = &ol; *isb = make_iostatus(); ULONG flags = 0; if(kind == barrier_kind::nowait_data_only) @@ -235,7 +235,7 @@ io_handle::io_result<io_handle::const_buffers_type> io_handle::_do_barrier(io_ha NTSTATUS ntstat = NtFlushBuffersFileEx(_v.h, flags, nullptr, 0, isb); if(STATUS_PENDING == ntstat) { - ntstat = ntwait(_v.h, (IO_STATUS_BLOCK &) ol, d); + ntstat = ntwait(_v.h, ol, d); if(STATUS_TIMEOUT == ntstat) { return errc::timed_out; diff --git a/include/llfio/v2.0/detail/impl/windows/map_handle.ipp b/include/llfio/v2.0/detail/impl/windows/map_handle.ipp index 8e441aab..089150e9 100644 --- a/include/llfio/v2.0/detail/impl/windows/map_handle.ipp +++ b/include/llfio/v2.0/detail/impl/windows/map_handle.ipp @@ -473,7 +473,7 @@ result<void> map_handle::close() noexcept { if(is_writable() && (_flag & section_handle::flag::barrier_on_close)) { - OUTCOME_TRYV(barrier({}, barrier_kind::wait_all)); + OUTCOME_TRYV(barrier(barrier_kind::wait_all)); } OUTCOME_TRYV(win32_maps_apply(_addr, _reservation, win32_map_sought::committed, [](byte *addr, size_t /* unused */) -> result<void> { NTSTATUS ntstat = NtUnmapViewOfSection(GetCurrentProcess(), addr); diff --git a/include/llfio/v2.0/detail/impl/windows/path_handle.ipp b/include/llfio/v2.0/detail/impl/windows/path_handle.ipp index b7bfd967..ee752eb0 100644 --- a/include/llfio/v2.0/detail/impl/windows/path_handle.ipp +++ b/include/llfio/v2.0/detail/impl/windows/path_handle.ipp @@ -31,7 +31,7 @@ result<path_handle> path_handle::path(const path_handle &base, path_handle::path { windows_nt_kernel::init(); using namespace windows_nt_kernel; - result<path_handle> ret{path_handle(native_handle_type())}; + result<path_handle> ret{path_handle(native_handle_type(), caching::none, flag::none)}; native_handle_type &nativeh = ret.value()._v; LLFIO_LOG_FUNCTION_CALL(&ret); nativeh.behaviour |= native_handle_type::disposition::directory; diff --git a/include/llfio/v2.0/detail/impl/windows/pipe_handle.ipp b/include/llfio/v2.0/detail/impl/windows/pipe_handle.ipp index 6ee3ee44..b50f6e4a 100644 --- a/include/llfio/v2.0/detail/impl/windows/pipe_handle.ipp +++ b/include/llfio/v2.0/detail/impl/windows/pipe_handle.ipp @@ -32,7 +32,7 @@ result<pipe_handle> pipe_handle::pipe(pipe_handle::path_view_type path, pipe_han windows_nt_kernel::init(); using namespace windows_nt_kernel; flags &= ~flag::unlink_on_first_close; - result<pipe_handle> ret(pipe_handle(native_handle_type(), 0, 0, _caching, flags)); + result<pipe_handle> ret(pipe_handle(native_handle_type(), 0, 0, _caching, flags, nullptr)); native_handle_type &nativeh = ret.value()._v; LLFIO_LOG_FUNCTION_CALL(&ret); nativeh.behaviour |= native_handle_type::disposition::pipe; @@ -126,7 +126,7 @@ result<pipe_handle> pipe_handle::pipe(pipe_handle::path_view_type path, pipe_han } // loop } - ret.value()._is_connected=true; + ret.value()._v.behaviour|=native_handle_type::disposition::_is_connected; } else { @@ -155,7 +155,7 @@ result<pipe_handle> pipe_handle::pipe(pipe_handle::path_view_type path, pipe_han { return win32_error(); } - ret.value()._is_connected=true; + ret.value()._v.behaviour |= native_handle_type::disposition::_is_connected; } } return ret; @@ -169,7 +169,7 @@ result<std::pair<pipe_handle, pipe_handle>> pipe_handle::anonymous_pipe(caching // Create an unnamed new pipe flags &= ~flag::unlink_on_first_close; OUTCOME_TRY(anonpipe, pipe({}, mode::read, creation::only_if_not_exist, _caching, flags)); - std::pair<pipe_handle, pipe_handle> ret(std::move(anonpipe), pipe_handle(native_handle_type(), 0, 0, _caching, flags)); + std::pair<pipe_handle, pipe_handle> ret(std::move(anonpipe), pipe_handle(native_handle_type(), 0, 0, _caching, flags, nullptr)); native_handle_type &readnativeh = ret.first._v, &writenativeh = ret.second._v; DWORD fileshare = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE; OUTCOME_TRY(access, access_mask_from_handle_mode(writenativeh, mode::append, flags)); @@ -208,7 +208,7 @@ pipe_handle::io_result<pipe_handle::buffers_type> pipe_handle::_do_read(pipe_han { LLFIO_LOG_FUNCTION_CALL(this); // If not connected, it'll be non-blocking, so connect now. - if(!_is_connected) + if(!(_v.behaviour & native_handle_type::disposition::_is_connected)) { LLFIO_WIN_DEADLINE_TO_SLEEP_INIT(d); OVERLAPPED ol{}; @@ -241,7 +241,7 @@ pipe_handle::io_result<pipe_handle::buffers_type> pipe_handle::_do_read(pipe_han d = deadline(remaining); } } - _is_connected=true; + _v.behaviour |= native_handle_type::disposition::_is_connected; } return io_handle::read(reqs, d); } diff --git a/include/llfio/v2.0/directory_handle.hpp b/include/llfio/v2.0/directory_handle.hpp index 6609e3eb..ebd4ad46 100644 --- a/include/llfio/v2.0/directory_handle.hpp +++ b/include/llfio/v2.0/directory_handle.hpp @@ -167,11 +167,16 @@ public: //! Default constructor constexpr directory_handle() {} // NOLINT //! Construct a directory_handle from a supplied native path_handle - explicit constexpr directory_handle(native_handle_type h, dev_t devid, ino_t inode, caching caching = caching::all, flag flags = flag::none) + explicit constexpr directory_handle(native_handle_type h, dev_t devid, ino_t inode, caching caching, flag flags) : path_handle(std::move(h), caching, flags) , fs_handle(devid, inode) { } + //! Construct a directory_handle from a supplied native path_handle + explicit constexpr directory_handle(native_handle_type h, caching caching, flag flags) + : path_handle(std::move(h), caching, flags) + { + } //! Implicit move construction of directory_handle permitted constexpr directory_handle(directory_handle &&o) noexcept : path_handle(std::move(o)), fs_handle(std::move(o)) {} //! No copy construction (use `clone()`) diff --git a/include/llfio/v2.0/file_handle.hpp b/include/llfio/v2.0/file_handle.hpp index 3afb0bbc..dfe4bb14 100644 --- a/include/llfio/v2.0/file_handle.hpp +++ b/include/llfio/v2.0/file_handle.hpp @@ -76,11 +76,16 @@ public: //! Default constructor constexpr file_handle() {} // NOLINT //! Construct a handle from a supplied native handle - constexpr file_handle(native_handle_type h, dev_t devid, ino_t inode, caching caching = caching::none, flag flags = flag::none) - : lockable_io_handle(std::move(h), caching, flags) + constexpr file_handle(native_handle_type h, dev_t devid, ino_t inode, caching caching, flag flags, io_multiplexer *ctx) + : lockable_io_handle(std::move(h), caching, flags, ctx) , fs_handle(devid, inode) { } + //! Construct a handle from a supplied native handle + constexpr file_handle(native_handle_type h, caching caching, flag flags, io_multiplexer *ctx) + : lockable_io_handle(std::move(h), caching, flags, ctx) + { + } //! No copy construction (use clone()) file_handle(const file_handle &) = delete; //! No copy assignment @@ -91,12 +96,28 @@ public: , fs_handle(std::move(o)) { } - //! Explicit conversion from handle and io_handle permitted - explicit constexpr file_handle(handle &&o, dev_t devid, ino_t inode) noexcept + //! Explicit conversion from handle permitted + explicit constexpr file_handle(handle &&o, dev_t devid, ino_t inode, io_multiplexer *ctx) noexcept + : lockable_io_handle(std::move(o), ctx) + , fs_handle(devid, inode) + { + } + //! Explicit conversion from handle permitted + explicit constexpr file_handle(handle &&o, io_multiplexer *ctx) noexcept + : lockable_io_handle(std::move(o), ctx) + { + } + //! Explicit conversion from io_handle permitted + explicit constexpr file_handle(io_handle &&o, dev_t devid, ino_t inode) noexcept : lockable_io_handle(std::move(o)) , fs_handle(devid, inode) { } + //! Explicit conversion from io_handle permitted + explicit constexpr file_handle(io_handle &&o) noexcept + : lockable_io_handle(std::move(o)) + { + } //! Move assignment of file_handle permitted file_handle &operator=(file_handle &&o) noexcept { diff --git a/include/llfio/v2.0/io_handle.hpp b/include/llfio/v2.0/io_handle.hpp index 9c5434ba..0487687a 100644 --- a/include/llfio/v2.0/io_handle.hpp +++ b/include/llfio/v2.0/io_handle.hpp @@ -69,13 +69,13 @@ public: constexpr io_handle() {} // NOLINT ~io_handle() = default; //! Construct a handle from a supplied native handle - constexpr explicit io_handle(native_handle_type h, caching caching = caching::none, flag flags = flag::none, io_multiplexer *ctx = nullptr) + constexpr explicit io_handle(native_handle_type h, caching caching, flag flags, io_multiplexer *ctx) : handle(h, caching, flags) , _ctx(ctx) { } //! Explicit conversion from handle permitted - explicit constexpr io_handle(handle &&o, io_multiplexer *ctx = nullptr) noexcept + explicit constexpr io_handle(handle &&o, io_multiplexer *ctx) noexcept : handle(std::move(o)) , _ctx(ctx) { @@ -141,10 +141,43 @@ protected: LLFIO_HEADERS_ONLY_VIRTUAL_SPEC result<registered_buffer_type> _do_allocate_registered_buffer(size_t &bytes) noexcept; // default implementation is in map_handle.hpp //! The virtualised implementation of `read()` used if no multiplexer has been set. LLFIO_HEADERS_ONLY_VIRTUAL_SPEC io_result<buffers_type> _do_read(io_request<buffers_type> reqs, deadline d) noexcept; + //! The virtualised implementation of `read()` used if no multiplexer has been set. + LLFIO_HEADERS_ONLY_VIRTUAL_SPEC io_result<buffers_type> _do_read(io_request<registered_buffers_type> reqs, deadline d) noexcept + { + auto _reqs_ = reinterpret_cast<buffer_type *>(alloca(sizeof(buffer_type) * reqs.buffers.size())); + for(size_t n = 0; n < reqs.buffers.size(); n++) + { + _reqs_[n] = *reqs.buffers[n]; + } + io_request<buffers_type> _reqs(buffers_type(_reqs_, reqs.buffers.size()), reqs.offset); + return _do_read(_reqs, d); + } //! The virtualised implementation of `write()` used if no multiplexer has been set. LLFIO_HEADERS_ONLY_VIRTUAL_SPEC io_result<const_buffers_type> _do_write(io_request<const_buffers_type> reqs, deadline d) noexcept; + //! The virtualised implementation of `write()` used if no multiplexer has been set. + LLFIO_HEADERS_ONLY_VIRTUAL_SPEC io_result<const_buffers_type> _do_write(io_request<registered_const_buffers_type> reqs, deadline d) noexcept + { + auto _reqs_ = reinterpret_cast<const_buffer_type *>(alloca(sizeof(const_buffer_type) * reqs.buffers.size())); + for(size_t n = 0; n < reqs.buffers.size(); n++) + { + _reqs_[n] = *reqs.buffers[n]; + } + io_request<const_buffers_type> _reqs(const_buffers_type(_reqs_, reqs.buffers.size()), reqs.offset); + return _do_write(reqs, d); + } //! The virtualised implementation of `barrier()` used if no multiplexer has been set. LLFIO_HEADERS_ONLY_VIRTUAL_SPEC io_result<const_buffers_type> _do_barrier(io_request<const_buffers_type> reqs, barrier_kind kind, deadline d) noexcept; + //! The virtualised implementation of `barrier()` used if no multiplexer has been set. + LLFIO_HEADERS_ONLY_VIRTUAL_SPEC io_result<const_buffers_type> _do_barrier(io_request<registered_const_buffers_type> reqs, barrier_kind kind, deadline d) noexcept + { + auto _reqs_ = reinterpret_cast<const_buffer_type *>(alloca(sizeof(const_buffer_type) * reqs.buffers.size())); + for(size_t n = 0; n < reqs.buffers.size(); n++) + { + _reqs_[n] = *reqs.buffers[n]; + } + io_request<const_buffers_type> _reqs(const_buffers_type(_reqs_, reqs.buffers.size()), reqs.offset); + return _do_barrier(_reqs, kind, d); + } public: /*! \brief The *maximum* number of buffers which a single read or write syscall can (atomically) @@ -237,7 +270,14 @@ public: } //! \overload Registered buffers overload LLFIO_MAKE_FREE_FUNCTION - io_result<registered_buffers_type> read(io_request<registered_buffers_type> reqs, deadline d = deadline()) noexcept { return _ctx->do_io_handle_read(this, reqs, d); } + io_result<buffers_type> read(io_request<registered_buffers_type> reqs, deadline d = deadline()) noexcept + { + if(_ctx == nullptr) + { + return _do_read(reqs, d); + } + return _ctx->do_io_handle_read(this, reqs, d); + } //! \overload Convenience initialiser list based overload for `read()` LLFIO_MAKE_FREE_FUNCTION io_result<size_type> read(extent_type offset, std::initializer_list<buffer_type> lst, deadline d = deadline()) noexcept @@ -287,7 +327,14 @@ public: } //! \overload Registered buffers overload LLFIO_MAKE_FREE_FUNCTION - io_result<registered_const_buffers_type> read(io_request<registered_const_buffers_type> reqs, deadline d = deadline()) noexcept { return _ctx->do_io_handle_write(this, reqs, d); } + io_result<const_buffers_type> write(io_request<registered_const_buffers_type> reqs, deadline d = deadline()) noexcept + { + if(_ctx == nullptr) + { + return _do_write(reqs, d); + } + return _ctx->do_io_handle_write(this, reqs, d); + } //! \overload Convenience initialiser list based overload for `write()` LLFIO_MAKE_FREE_FUNCTION io_result<size_type> write(extent_type offset, std::initializer_list<const_buffer_type> lst, deadline d = deadline()) noexcept @@ -343,9 +390,19 @@ public: } return _ctx->do_io_handle_barrier(this, reqs, kind, d); } + //! \overload Convenience overload + LLFIO_MAKE_FREE_FUNCTION + io_result<const_buffers_type> barrier(barrier_kind kind, deadline d = deadline()) noexcept { return barrier(io_request<const_buffers_type>(), kind, d); } //! \overload Registered buffers overload LLFIO_MAKE_FREE_FUNCTION - io_result<registered_const_buffers_type> barrier(io_request<registered_const_buffers_type> reqs = io_request<registered_const_buffers_type>(), barrier_kind kind = barrier_kind::nowait_data_only, deadline d = deadline()) noexcept { return _ctx->do_io_handle_barrier(this, reqs, kind, d); } + io_result<const_buffers_type> barrier(io_request<registered_const_buffers_type> reqs = io_request<registered_const_buffers_type>(), barrier_kind kind = barrier_kind::nowait_data_only, deadline d = deadline()) noexcept + { + if(_ctx == nullptr) + { + return _do_barrier(reqs, kind, d); + } + return _ctx->do_io_handle_barrier(this, reqs, kind, d); + } LLFIO_DEADLINE_TRY_FOR_UNTIL(barrier) }; diff --git a/include/llfio/v2.0/io_multiplexer.hpp b/include/llfio/v2.0/io_multiplexer.hpp index 8b9a874c..5752151f 100644 --- a/include/llfio/v2.0/io_multiplexer.hpp +++ b/include/llfio/v2.0/io_multiplexer.hpp @@ -158,8 +158,28 @@ public: pointer _data; size_type _len; }; + struct _registered_buffer_type : std::enable_shared_from_this<_registered_buffer_type>, buffer_type + { + _registered_buffer_type() = default; + using buffer_type::buffer_type; + }; + struct registered_const_buffer_type; //! The registered scatter buffer type used by this handle. - using registered_buffer_type = std::shared_ptr<buffer_type>; + struct registered_buffer_type : std::shared_ptr<_registered_buffer_type> + { + protected: + friend struct registered_const_buffer_type; + using _base = std::shared_ptr<_registered_buffer_type>; + + public: + registered_buffer_type() = delete; + LLFIO_TEMPLATE(class Arg, class... Args) + LLFIO_TREQUIRES(LLFIO_TPRED(std::is_constructible<_base, Arg, Args...>::value)) + explicit constexpr registered_buffer_type(Arg &&arg, Args &&... args) + : _base(std::forward<Arg>(arg), std::forward<Args>(args)...) + { + } + }; //! The gather buffer type used by this handle. Guaranteed to be `TrivialType` and `StandardLayoutType`. //! Try to make address and length 64 byte, or ideally, `page_size()` aligned where possible. @@ -240,8 +260,32 @@ public: static_assert(std::is_standard_layout<buffer_type>::value, "buffer_type is not a standard layout type!"); static_assert(std::is_standard_layout<const_buffer_type>::value, "const_buffer_type is not a standard layout type!"); #endif + struct _registered_const_buffer_type : _registered_buffer_type + { + _registered_const_buffer_type() = default; + using _registered_buffer_type::_registered_buffer_type; + }; //! The registered gather buffer type used by this handle. - using registered_const_buffer_type = std::shared_ptr<const_buffer_type>; + struct registered_const_buffer_type : std::shared_ptr<_registered_const_buffer_type> + { + protected: + using _base = std::shared_ptr<_registered_const_buffer_type>; + + public: + registered_const_buffer_type() = delete; + + LLFIO_TEMPLATE(class Arg, class... Args) + LLFIO_TREQUIRES(LLFIO_TPRED(std::is_constructible<_base, Arg, Args...>::value)) + explicit constexpr registered_const_buffer_type(Arg &&arg, Args &&... args) + : _base(std::forward<Arg>(arg), std::forward<Args>(args)...) + { + } + + registered_const_buffer_type(registered_buffer_type &&o) + : _base(std::shared_ptr<_registered_const_buffer_type>(std::move(o), static_cast<_registered_const_buffer_type *>(o.get()))) + { + } + }; //! The scatter buffers type used by this handle. Guaranteed to be `TrivialType` apart from construction, and `StandardLayoutType`. using buffers_type = span<buffer_type>; @@ -259,9 +303,9 @@ public: static_assert(std::is_standard_layout<buffers_type>::value, "buffers_type is not a standard layout type!"); #endif //! The registered scatter buffers type used by this handle. Guaranteed to be `TrivialType` apart from construction, and `StandardLayoutType`. - using registered_buffers_type = span<registered_buffer_type *>; + using registered_buffers_type = span<registered_buffer_type>; //! The registered gather buffers type used by this handle. Guaranteed to be `TrivialType` apart from construction, and `StandardLayoutType`. - using registered_const_buffers_type = span<registered_const_buffer_type *>; + using registered_const_buffers_type = span<registered_const_buffer_type>; //! The i/o request type used by this handle. Guaranteed to be `TrivialType` apart from construction, and `StandardLayoutType`. template <class T> struct io_request @@ -359,15 +403,15 @@ public: //! Implements `io_handle::read()` LLFIO_HEADERS_ONLY_VIRTUAL_SPEC io_result<buffers_type> do_io_handle_read(io_handle *h, io_request<buffers_type> reqs, deadline d) noexcept = 0; //! Implements `io_handle::read()` - LLFIO_HEADERS_ONLY_VIRTUAL_SPEC io_result<registered_buffers_type> do_io_handle_read(io_handle *h, io_request<registered_buffers_type> reqs, deadline d) noexcept = 0; + LLFIO_HEADERS_ONLY_VIRTUAL_SPEC io_result<buffers_type> do_io_handle_read(io_handle *h, io_request<registered_buffers_type> reqs, deadline d) noexcept = 0; //! Implements `io_handle::write()` LLFIO_HEADERS_ONLY_VIRTUAL_SPEC io_result<const_buffers_type> do_io_handle_write(io_handle *h, io_request<const_buffers_type> reqs, deadline d) noexcept = 0; //! Implements `io_handle::write()` - LLFIO_HEADERS_ONLY_VIRTUAL_SPEC io_result<registered_const_buffers_type> do_io_handle_write(io_handle *h, io_request<registered_const_buffers_type> reqs, deadline d) noexcept = 0; + LLFIO_HEADERS_ONLY_VIRTUAL_SPEC io_result<const_buffers_type> do_io_handle_write(io_handle *h, io_request<registered_const_buffers_type> reqs, deadline d) noexcept = 0; //! Implements `io_handle::barrier()` LLFIO_HEADERS_ONLY_VIRTUAL_SPEC io_result<const_buffers_type> do_io_handle_barrier(io_handle *h, io_request<const_buffers_type> reqs, barrier_kind kind, deadline d) noexcept = 0; //! Implements `io_handle::barrier()` - LLFIO_HEADERS_ONLY_VIRTUAL_SPEC io_result<registered_const_buffers_type> do_io_handle_barrier(io_handle *h, io_request<registered_const_buffers_type> reqs, barrier_kind kind, deadline d) noexcept = 0; + LLFIO_HEADERS_ONLY_VIRTUAL_SPEC io_result<const_buffers_type> do_io_handle_barrier(io_handle *h, io_request<registered_const_buffers_type> reqs, barrier_kind kind, deadline d) noexcept = 0; }; //! A unique ptr to an i/o multiplexer implementation. using io_multiplexer_ptr = std::unique_ptr<io_multiplexer>; diff --git a/include/llfio/v2.0/lockable_io_handle.hpp b/include/llfio/v2.0/lockable_io_handle.hpp index 6116c038..c07dd40e 100644 --- a/include/llfio/v2.0/lockable_io_handle.hpp +++ b/include/llfio/v2.0/lockable_io_handle.hpp @@ -76,12 +76,17 @@ public: constexpr lockable_io_handle() {} // NOLINT ~lockable_io_handle() = default; //! Construct a handle from a supplied native handle - constexpr explicit lockable_io_handle(native_handle_type h, caching caching = caching::none, flag flags = flag::none) - : io_handle(h, caching, flags) + constexpr explicit lockable_io_handle(native_handle_type h, caching caching, flag flags, io_multiplexer *ctx) + : io_handle(h, caching, flags, ctx) { } //! Explicit conversion from `handle` permitted - explicit constexpr lockable_io_handle(handle &&o) noexcept + explicit constexpr lockable_io_handle(handle &&o, io_multiplexer *ctx) noexcept + : io_handle(std::move(o), ctx) + { + } + //! Explicit conversion from `io_handle` permitted + explicit constexpr lockable_io_handle(io_handle &&o) noexcept : io_handle(std::move(o)) { } diff --git a/include/llfio/v2.0/map_handle.hpp b/include/llfio/v2.0/map_handle.hpp index 0db64042..beb8725d 100644 --- a/include/llfio/v2.0/map_handle.hpp +++ b/include/llfio/v2.0/map_handle.hpp @@ -787,7 +787,7 @@ namespace detail struct registered_buffer_type_indirect { map_handle h; - io_handle::buffer_type buffer; + io_multiplexer::_registered_buffer_type buffer; registered_buffer_type_indirect(map_handle _h) : h(std::move(_h)) , buffer(h.as_span()) @@ -795,7 +795,7 @@ namespace detail } }; auto ptr = std::make_shared<registered_buffer_type_indirect>(std::move(h)); - return io_handle::registered_buffer_type(ptr, &ptr->buffer); + return io_handle::registered_buffer_type(std::move(ptr), &ptr->buffer); }; const auto &page_sizes = utils::page_sizes(true); size_t idx = 0; diff --git a/include/llfio/v2.0/path_handle.hpp b/include/llfio/v2.0/path_handle.hpp index 5a740315..23c6221c 100644 --- a/include/llfio/v2.0/path_handle.hpp +++ b/include/llfio/v2.0/path_handle.hpp @@ -65,7 +65,7 @@ public: //! Default constructor constexpr path_handle() {} // NOLINT //! Construct a handle from a supplied native handle - explicit constexpr path_handle(native_handle_type h, caching caching = caching::all, flag flags = flag::none) + explicit constexpr path_handle(native_handle_type h, caching caching, flag flags) : handle(h, caching, flags) { } diff --git a/include/llfio/v2.0/pipe_handle.hpp b/include/llfio/v2.0/pipe_handle.hpp index 30fa8edb..5d929051 100644 --- a/include/llfio/v2.0/pipe_handle.hpp +++ b/include/llfio/v2.0/pipe_handle.hpp @@ -109,11 +109,16 @@ public: //! Default constructor constexpr pipe_handle() {} // NOLINT //! Construct a handle from a supplied native handle - constexpr pipe_handle(native_handle_type h, dev_t devid, ino_t inode, caching caching = caching::none, flag flags = flag::none, io_multiplexer *ctx = nullptr) + constexpr pipe_handle(native_handle_type h, dev_t devid, ino_t inode, caching caching, flag flags, io_multiplexer *ctx) : io_handle(std::move(h), caching, flags, ctx) , fs_handle(devid, inode) { } + //! Construct a handle from a supplied native handle + constexpr pipe_handle(native_handle_type h, caching caching, flag flags, io_multiplexer *ctx) + : io_handle(std::move(h), caching, flags, ctx) + { + } //! No copy construction (use clone()) pipe_handle(const pipe_handle &) = delete; //! No copy assignment @@ -124,12 +129,28 @@ public: , fs_handle(std::move(o)) { } - //! Explicit conversion from handle and io_handle permitted - explicit constexpr pipe_handle(handle &&o, dev_t devid, ino_t inode) noexcept + //! Explicit conversion from handle permitted + explicit constexpr pipe_handle(handle &&o, dev_t devid, ino_t inode, io_multiplexer *ctx) noexcept + : io_handle(std::move(o), ctx) + , fs_handle(devid, inode) + { + } + //! Explicit conversion from handle permitted + explicit constexpr pipe_handle(handle &&o, io_multiplexer *ctx) noexcept + : io_handle(std::move(o), ctx) + { + } + //! Explicit conversion from io_handle permitted + explicit constexpr pipe_handle(io_handle &&o, dev_t devid, ino_t inode) noexcept : io_handle(std::move(o)) , fs_handle(devid, inode) { } + //! Explicit conversion from io_handle permitted + explicit constexpr pipe_handle(io_handle &&o) noexcept + : io_handle(std::move(o)) + { + } //! Move assignment of `pipe_handle` permitted pipe_handle &operator=(pipe_handle &&o) noexcept { |