Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/windirstat/llfio.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNiall Douglas (s [underscore] sourceforge {at} nedprod [dot] com) <spamtrap@nedprod.com>2020-04-09 13:07:17 +0300
committerNiall Douglas (s [underscore] sourceforge {at} nedprod [dot] com) <spamtrap@nedprod.com>2020-04-09 13:07:17 +0300
commit62fd7f4f4059cba9aed1962609e75d0a1ea46c7d (patch)
treec732755c1f80c094ea76f98377a163f1896e90de
parent44f0a6d7b7f2c2de8215b20b541ef27a3a367c56 (diff)
More progress on merging resumable_io branch.
-rw-r--r--cmake/headers.cmake8
-rw-r--r--include/llfio/revision.hpp6
-rw-r--r--include/llfio/v2.0/algorithm/handle_adapter/combining.hpp4
-rw-r--r--include/llfio/v2.0/detail/impl/path_view.ipp9
-rw-r--r--include/llfio/v2.0/detail/impl/posix/directory_handle.ipp4
-rw-r--r--include/llfio/v2.0/detail/impl/posix/file_handle.ipp7
-rw-r--r--include/llfio/v2.0/detail/impl/posix/handle.ipp2
-rw-r--r--include/llfio/v2.0/detail/impl/posix/map_handle.ipp2
-rw-r--r--include/llfio/v2.0/detail/impl/posix/path_handle.ipp2
-rw-r--r--include/llfio/v2.0/detail/impl/posix/pipe_handle.ipp4
-rw-r--r--include/llfio/v2.0/detail/impl/remove_all.ipp2
-rw-r--r--include/llfio/v2.0/detail/impl/windows/directory_handle.ipp6
-rw-r--r--include/llfio/v2.0/detail/impl/windows/file_handle.ipp8
-rw-r--r--include/llfio/v2.0/detail/impl/windows/io_handle.ipp38
-rw-r--r--include/llfio/v2.0/detail/impl/windows/map_handle.ipp2
-rw-r--r--include/llfio/v2.0/detail/impl/windows/path_handle.ipp2
-rw-r--r--include/llfio/v2.0/detail/impl/windows/pipe_handle.ipp12
-rw-r--r--include/llfio/v2.0/directory_handle.hpp7
-rw-r--r--include/llfio/v2.0/file_handle.hpp29
-rw-r--r--include/llfio/v2.0/io_handle.hpp67
-rw-r--r--include/llfio/v2.0/io_multiplexer.hpp58
-rw-r--r--include/llfio/v2.0/lockable_io_handle.hpp11
-rw-r--r--include/llfio/v2.0/map_handle.hpp4
-rw-r--r--include/llfio/v2.0/path_handle.hpp2
-rw-r--r--include/llfio/v2.0/pipe_handle.hpp27
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
{