diff options
-rw-r--r-- | CMakeLists.txt | 8 | ||||
-rw-r--r-- | Readme.md | 3 | ||||
-rw-r--r-- | include/afio/revision.hpp | 6 | ||||
-rw-r--r-- | include/afio/v2.0/afio.hpp | 5 | ||||
-rw-r--r-- | include/afio/v2.0/config.hpp | 10 | ||||
-rw-r--r-- | include/afio/v2.0/detail/impl/posix/map_handle.ipp | 11 | ||||
-rw-r--r-- | include/afio/v2.0/detail/impl/windows/map_handle.ipp | 11 | ||||
-rw-r--r-- | include/afio/v2.0/mapped_file_handle.hpp | 17 | ||||
m--------- | test/kerneltest | 0 |
9 files changed, 55 insertions, 16 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index f8349bc9..5feb59e5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -158,14 +158,18 @@ if(AFIO_USE_EXPERIMENTAL_SG14_STATUS_CODE) endif() if(WIN32) all_compile_definitions(PRIVATE _WIN32_WINNT=0x600) ## Target WinVista - target_link_libraries(afio_dl PUBLIC ntkernel-error-category::dl) - target_link_libraries(afio_sl PUBLIC ntkernel-error-category::sl) + if(NOT AFIO_USE_EXPERIMENTAL_SG14_STATUS_CODE) + target_link_libraries(afio_dl PUBLIC ntkernel-error-category::dl) + target_link_libraries(afio_sl PUBLIC ntkernel-error-category::sl) + endif() endif() # Anyone using the static or dynamic libraries is not using the header only variant foreach(lib afio_sl afio_dl) target_compile_definitions(${lib} INTERFACE AFIO_HEADERS_ONLY=0) target_compile_definitions(${lib} PRIVATE AFIO_SOURCE=1) endforeach() +# The single header test requires C++ 17 +target_compile_features(afio-example_single-header PRIVATE cxx_std_17) # For all possible configurations of this library, add each test include(QuickCppLibMakeStandardTests) @@ -19,8 +19,7 @@ Tarballs of source and prebuilt binaries for Linux x64, MacOS x64 and Windows x6 - [x] Make lazy the stat fetch during file/dir open. - [x] Implement SG14 `status_code` as a standalone library and test in AFIO. - [x] Single include generation now we're on `status_code` and it's safe. -- [ ] Implement `SIGBUS`/`EXCEPTION_IN_PAGE_ERROR` RAII catcher. - - Is `io_service` reference counting the signal handler install? +- [x] Implement `SIGBUS`/`EXCEPTION_IN_PAGE_ERROR` RAII catcher. - [ ] `atomic_append` isn't actually being tested in shared_fs_mutex - [ ] Implement a non-toy ACID key-value BLOB store and send it to Boost for peer review. - [ ] For this need to implement a file-based B+ tree. And for that, need to diff --git a/include/afio/revision.hpp b/include/afio/revision.hpp index f8266792..edac0620 100644 --- a/include/afio/revision.hpp +++ b/include/afio/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 AFIO_PREVIOUS_COMMIT_REF 128ff433151efbad5585de55c3e365a982ba1acb -#define AFIO_PREVIOUS_COMMIT_DATE "2018-06-18 20:18:55 +00:00" -#define AFIO_PREVIOUS_COMMIT_UNIQUE 128ff433 +#define AFIO_PREVIOUS_COMMIT_REF 5854802f283de2b9c5026ea1a905ffdde1b09034 +#define AFIO_PREVIOUS_COMMIT_DATE "2018-06-19 09:00:24 +00:00" +#define AFIO_PREVIOUS_COMMIT_UNIQUE 5854802f diff --git a/include/afio/v2.0/afio.hpp b/include/afio/v2.0/afio.hpp index ebdee881..be31688c 100644 --- a/include/afio/v2.0/afio.hpp +++ b/include/afio/v2.0/afio.hpp @@ -57,6 +57,11 @@ import AFIO_MODULE_NAME; #include "config.hpp" +// Predeclare to keep the single header edition happy +#include "handle.hpp" +#include "stat.hpp" +#include "utils.hpp" + #ifndef AFIO_LEAN_AND_MEAN #include "async_file_handle.hpp" #else diff --git a/include/afio/v2.0/config.hpp b/include/afio/v2.0/config.hpp index 2e8016fc..afd3c636 100644 --- a/include/afio/v2.0/config.hpp +++ b/include/afio/v2.0/config.hpp @@ -215,6 +215,10 @@ AFIO_V2_NAMESPACE_END // Bring in the Boost-lite macros #include "quickcpplib/include/config.hpp" +#if AFIO_LOGGING_LEVEL +#include "quickcpplib/include/ringbuffer_log.hpp" +#include "quickcpplib/include/utils/thread.hpp" +#endif // Bring in filesystem #if defined(__has_include) // clang-format off @@ -230,9 +234,9 @@ namespace filesystem = std::experimental::filesystem; AFIO_V2_NAMESPACE_END #endif #elif __PCPP_ALWAYS_TRUE__ -#include <filesystem> +#include <experimental/filesystem> AFIO_V2_NAMESPACE_BEGIN -namespace filesystem = std::filesystem; +namespace filesystem = std::experimental::filesystem; AFIO_V2_NAMESPACE_END // clang-format on #elif defined(_MSC_VER) @@ -741,8 +745,6 @@ AFIO_V2_NAMESPACE_END #if AFIO_LOGGING_LEVEL -#include "quickcpplib/include/ringbuffer_log.hpp" -#include "quickcpplib/include/utils/thread.hpp" /*! \todo TODO FIXME Replace in-memory log with memory map file backed log. */ diff --git a/include/afio/v2.0/detail/impl/posix/map_handle.ipp b/include/afio/v2.0/detail/impl/posix/map_handle.ipp index 44860dcf..aace6f35 100644 --- a/include/afio/v2.0/detail/impl/posix/map_handle.ipp +++ b/include/afio/v2.0/detail/impl/posix/map_handle.ipp @@ -25,7 +25,15 @@ Distributed under the Boost Software License, Version 1.0. #include "../../../map_handle.hpp" #include "../../../utils.hpp" +#ifdef __has_include +#if __has_include("../../../quickcpplib/include/signal_guard.hpp") #include "../../../quickcpplib/include/signal_guard.hpp" +#else +#include "quickcpplib/include/signal_guard.hpp" +#endif +#else +#include "quickcpplib/include/signal_guard.hpp" +#endif #include <sys/mman.h> @@ -568,7 +576,8 @@ map_handle::io_result<map_handle::const_buffers_type> map_handle::write(io_reque } return false; }, - [&](QUICKCPPLIB_NAMESPACE::signal_guard::signalc /* unused */, const void *_info, const void *_context) { + [&](QUICKCPPLIB_NAMESPACE::signal_guard::signalc signo, const void *_info, const void *_context) { + (void) signo; assert(signo == QUICKCPPLIB_NAMESPACE::signal_guard::signalc::undefined_memory_access); const auto *info = (const siginfo_t *) _info; assert(info->si_signo == SIGBUS); diff --git a/include/afio/v2.0/detail/impl/windows/map_handle.ipp b/include/afio/v2.0/detail/impl/windows/map_handle.ipp index 1331fb01..744f8d82 100644 --- a/include/afio/v2.0/detail/impl/windows/map_handle.ipp +++ b/include/afio/v2.0/detail/impl/windows/map_handle.ipp @@ -26,8 +26,18 @@ Distributed under the Boost Software License, Version 1.0. #include "../../../utils.hpp" #include "import.hpp" +#ifdef __has_include +#if __has_include("../../../quickcpplib/include/signal_guard.hpp") #include "../../../quickcpplib/include/algorithm/hash.hpp" #include "../../../quickcpplib/include/signal_guard.hpp" +#else +#include "quickcpplib/include/algorithm/hash.hpp" +#include "quickcpplib/include/signal_guard.hpp" +#endif +#else +#include "quickcpplib/include/algorithm/hash.hpp" +#include "quickcpplib/include/signal_guard.hpp" +#endif AFIO_V2_NAMESPACE_BEGIN @@ -836,6 +846,7 @@ map_handle::io_result<map_handle::const_buffers_type> map_handle::write(io_reque return false; }, [&](QUICKCPPLIB_NAMESPACE::signal_guard::signalc signo, const void *_info, const void * /*unused*/) { + (void)signo; assert(signo == QUICKCPPLIB_NAMESPACE::signal_guard::signalc::undefined_memory_access); const auto *info = (const _EXCEPTION_RECORD *) _info; assert(info->ExceptionCode == EXCEPTION_IN_PAGE_ERROR); diff --git a/include/afio/v2.0/mapped_file_handle.hpp b/include/afio/v2.0/mapped_file_handle.hpp index b7735f3f..37c0b49b 100644 --- a/include/afio/v2.0/mapped_file_handle.hpp +++ b/include/afio/v2.0/mapped_file_handle.hpp @@ -378,9 +378,11 @@ public: /*! \brief Read data from the mapped file. - \note Because this implementation never copies memory, you can pass in buffers with a null address. + \note Because this implementation never copies memory, you can pass in buffers with a null address. As this + function never reads any memory, no attempt to trap signal raises can be made, this falls onto the user of + this function. See `QUICKCPPLIB_NAMESPACE::signal_guard` for a helper function. - \return The buffers read, which will never be the buffers input because they will point into the mapped view. + \return The buffers read, which will never be the buffers input, because they will point into the mapped view. The size of each scatter-gather buffer is updated with the number of bytes of that buffer transferred. \param reqs A scatter-gather and offset request. \param d Ignored. @@ -390,12 +392,19 @@ public: AFIO_HEADERS_ONLY_VIRTUAL_SPEC io_result<buffers_type> read(io_request<buffers_type> reqs, deadline d = deadline()) noexcept override { return _mh.read(reqs, d); } /*! \brief Write data to the mapped file. + \note This call traps signals and structured exception throws using `QUICKCPPLIB_NAMESPACE::signal_guard`. + Instantiating a `QUICKCPPLIB_NAMESPACE::signal_guard_install` somewhere much higher up in the call stack + will improve performance enormously. The signal guard may cost less than 100 CPU cycles depending on how + you configure it. If you don't want the guard, you can write memory directly using `address()`. + \return The buffers written, which will never be the buffers input because they will point at where the data was copied into the mapped view. The size of each scatter-gather buffer is updated with the number of bytes of that buffer transferred. \param reqs A scatter-gather and offset request. \param d Ignored. - \errors None, though the various signals and structured exception throws common to using memory maps may occur. - \mallocs None. + \errors If during the attempt to write the buffers to the map a `SIGBUS` or `EXCEPTION_IN_PAGE_ERROR` is raised, + an error code comparing equal to `errc::no_space_on_device` will be returned. This may not always be the cause + of the raised signal, but it is by far the most likely. + \mallocs None if a `QUICKCPPLIB_NAMESPACE::signal_guard_install` is already instanced. */ AFIO_HEADERS_ONLY_VIRTUAL_SPEC io_result<const_buffers_type> write(io_request<const_buffers_type> reqs, deadline d = deadline()) noexcept override { return _mh.write(reqs, d); } }; diff --git a/test/kerneltest b/test/kerneltest -Subproject fe191a261b6fd2cbfa1e7a5b53fcbd89373d08a +Subproject f0902aee1cc1b7dc2ba7ba5bd508c9b636f3f89 |