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>2017-04-10 20:08:25 +0300
committerNiall Douglas (s [underscore] sourceforge {at} nedprod [dot] com) <spamtrap@nedprod.com>2017-04-10 20:08:25 +0300
commitf76e3d07c7e7ae6bf6504837af1bb3ba7a90a367 (patch)
tree513836a4a6f213c470a8553e02c93c285264fe3a
parentb0638aa44b6aecc35351a12bd73838d521fb7f92 (diff)
Much build fixing on the POSIX backend.
m---------doc/html8
-rw-r--r--include/boost/afio/revision.hpp6
-rw-r--r--include/boost/afio/v2.0/async_file_handle.hpp3
-rw-r--r--include/boost/afio/v2.0/config.hpp4
-rw-r--r--include/boost/afio/v2.0/detail/impl/posix/async_file_handle.ipp9
-rw-r--r--include/boost/afio/v2.0/detail/impl/posix/file_handle.ipp87
-rw-r--r--include/boost/afio/v2.0/detail/impl/posix/handle.ipp68
-rw-r--r--include/boost/afio/v2.0/detail/impl/posix/io_service.ipp17
-rw-r--r--include/boost/afio/v2.0/detail/impl/posix/map_handle.ipp155
-rw-r--r--include/boost/afio/v2.0/detail/impl/posix/stat.ipp64
-rw-r--r--include/boost/afio/v2.0/detail/impl/posix/statfs.ipp66
-rw-r--r--include/boost/afio/v2.0/detail/impl/posix/storage_profile.ipp16
-rw-r--r--include/boost/afio/v2.0/detail/impl/posix/utils.ipp10
-rw-r--r--include/boost/afio/v2.0/detail/impl/windows/map_handle.ipp23
-rw-r--r--include/boost/afio/v2.0/detail/impl/windows/stat.ipp2
-rw-r--r--include/boost/afio/v2.0/detail/impl/windows/statfs.ipp2
-rw-r--r--include/boost/afio/v2.0/file_handle.hpp2
-rw-r--r--include/boost/afio/v2.0/handle.hpp1
-rw-r--r--include/boost/afio/v2.0/io_service.hpp2
-rw-r--r--include/boost/afio/v2.0/map_handle.hpp17
-rw-r--r--include/boost/afio/v2.0/stat.hpp4
-rw-r--r--include/boost/afio/v2.0/statfs.hpp4
22 files changed, 334 insertions, 236 deletions
diff --git a/doc/html b/doc/html
-Subproject 641cadb4e991fa835d5d7e26f58f2dd7f02634d
+Subproject 1b7c5e0124f0c57418b5b26b451a7afc28b6025
diff --git a/include/boost/afio/revision.hpp b/include/boost/afio/revision.hpp
index 63674219..e36d2fa3 100644
--- a/include/boost/afio/revision.hpp
+++ b/include/boost/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 BOOST_AFIO_PREVIOUS_COMMIT_REF 8374482f8398578f93d9649b54749c6017ef7c78
-#define BOOST_AFIO_PREVIOUS_COMMIT_DATE "2017-04-09 21:07:41 +00:00"
-#define BOOST_AFIO_PREVIOUS_COMMIT_UNIQUE 8374482f
+#define BOOST_AFIO_PREVIOUS_COMMIT_REF b0638aa44b6aecc35351a12bd73838d521fb7f92
+#define BOOST_AFIO_PREVIOUS_COMMIT_DATE "2017-04-10 09:18:59 +00:00"
+#define BOOST_AFIO_PREVIOUS_COMMIT_UNIQUE b0638aa4
diff --git a/include/boost/afio/v2.0/async_file_handle.hpp b/include/boost/afio/v2.0/async_file_handle.hpp
index c990069b..1298aaa7 100644
--- a/include/boost/afio/v2.0/async_file_handle.hpp
+++ b/include/boost/afio/v2.0/async_file_handle.hpp
@@ -43,6 +43,7 @@ BOOST_AFIO_V2_NAMESPACE_EXPORT_BEGIN
*/
class BOOST_AFIO_DECL async_file_handle : public file_handle
{
+ friend class io_service;
public:
using dev_t = file_handle::dev_t;
using ino_t = file_handle::ino_t;
@@ -65,7 +66,7 @@ protected:
public:
//! Default constructor
- constexpr async_file_handle() = default;
+ async_file_handle() = default;
//! Construct a handle from a supplied native handle
async_file_handle(io_service *service, native_handle_type h, dev_t devid, ino_t inode, path_type path, caching caching = caching::none, flag flags = flag::none)
diff --git a/include/boost/afio/v2.0/config.hpp b/include/boost/afio/v2.0/config.hpp
index 9c92c5d6..86fcfc44 100644
--- a/include/boost/afio/v2.0/config.hpp
+++ b/include/boost/afio/v2.0/config.hpp
@@ -517,7 +517,7 @@ inline span<char> afio_namespace_string()
return span<char>(buffer, length);
const char *src = BOOST_AFIO_LOG_STRINGIFY(BOOST_AFIO_V2_NAMESPACE);
char *bufferp = buffer;
- for(; *src && bufferp - buffer < sizeof(buffer); src++)
+ for(; *src && (bufferp - buffer) < (ptrdiff_t) sizeof(buffer); src++)
{
if(*src != ' ')
*bufferp++ = *src;
@@ -535,7 +535,7 @@ inline span<char> outcome_namespace_string()
return span<char>(buffer, length);
const char *src = BOOST_AFIO_LOG_STRINGIFY(BOOST_OUTCOME_V1_NAMESPACE);
char *bufferp = buffer;
- for(; *src && bufferp - buffer < sizeof(buffer); src++)
+ for(; *src && (bufferp - buffer) < (ptrdiff_t) sizeof(buffer); src++)
{
if(*src != ' ')
*bufferp++ = *src;
diff --git a/include/boost/afio/v2.0/detail/impl/posix/async_file_handle.ipp b/include/boost/afio/v2.0/detail/impl/posix/async_file_handle.ipp
index 112524d7..b91c7f80 100644
--- a/include/boost/afio/v2.0/detail/impl/posix/async_file_handle.ipp
+++ b/include/boost/afio/v2.0/detail/impl/posix/async_file_handle.ipp
@@ -48,7 +48,7 @@ result<async_file_handle> async_file_handle::clone(io_service &service) const no
}
template <class CompletionRoutine, class BuffersType, class IORoutine>
-result<async_file_handle::io_state_ptr<CompletionRoutine, BuffersType>> async_file_handle::_begin_io(async_file_handle::operation_t operation, async_file_handle::io_request<BuffersType> reqs, CompletionRoutine &&completion, IORoutine &&ioroutine) noexcept
+result<async_file_handle::io_state_ptr<CompletionRoutine, BuffersType>> async_file_handle::_begin_io(async_file_handle::operation_t operation, async_file_handle::io_request<BuffersType> reqs, CompletionRoutine &&completion, IORoutine &&/*ioroutine*/) noexcept
{
// Need to keep a set of aiocbs matching the scatter-gather buffers
struct state_type : public _io_state_type<CompletionRoutine, BuffersType>
@@ -58,7 +58,7 @@ result<async_file_handle::io_state_ptr<CompletionRoutine, BuffersType>> async_fi
#else
#error todo
#endif
- state_type(handle *_parent, operation_t _operation, CompletionRoutine &&f, size_t _items)
+ state_type(async_file_handle *_parent, operation_t _operation, CompletionRoutine &&f, size_t _items)
: _io_state_type<CompletionRoutine, BuffersType>(_parent, _operation, std::forward<CompletionRoutine>(f), _items)
{
}
@@ -106,6 +106,7 @@ result<async_file_handle::io_state_ptr<CompletionRoutine, BuffersType>> async_fi
{
#if BOOST_AFIO_USE_POSIX_AIO
int ret = aio_cancel(this->parent->native_handle().fd, aiocbs + n);
+ (void) ret;
#if 0
if(ret<0 || ret==AIO_NOTCANCELED)
{
@@ -227,7 +228,7 @@ async_file_handle::io_result<async_file_handle::buffers_type> async_file_handle:
{
io_result<buffers_type> ret;
auto _io_state(_begin_io(operation_t::read, std::move(reqs), [&ret](auto *state) { ret = std::move(state->result); }, nullptr));
- BOOST_OUTCOME_FILTER_ERROR(io_state, _io_state);
+ BOOST_OUTCOME_TRY(io_state, _io_state);
// While i/o is not done pump i/o completion
while(!ret.is_ready())
@@ -251,7 +252,7 @@ async_file_handle::io_result<async_file_handle::const_buffers_type> async_file_h
{
io_result<const_buffers_type> ret;
auto _io_state(_begin_io(operation_t::write, std::move(reqs), [&ret](auto *state) { ret = std::move(state->result); }, nullptr));
- BOOST_OUTCOME_FILTER_ERROR(io_state, _io_state);
+ BOOST_OUTCOME_TRY(io_state, _io_state);
// While i/o is not done pump i/o completion
while(!ret.is_ready())
diff --git a/include/boost/afio/v2.0/detail/impl/posix/file_handle.ipp b/include/boost/afio/v2.0/detail/impl/posix/file_handle.ipp
index 6009cd04..14d20bca 100644
--- a/include/boost/afio/v2.0/detail/impl/posix/file_handle.ipp
+++ b/include/boost/afio/v2.0/detail/impl/posix/file_handle.ipp
@@ -31,6 +31,8 @@ DEALINGS IN THE SOFTWARE.
#include "../../../handle.hpp"
+#include "../../../stat.hpp"
+
#include <fcntl.h>
#include <unistd.h>
@@ -104,71 +106,72 @@ const fixme_path &fixme_temporary_files_directory() noexcept
return temporary_files_directory_;
}
-inline result<int> attribs_from_handle_mode_caching_and_flags(native_handle_type &nativeh, file_handle::mode _mode, file_handle::creation _creation, file_handle::caching _caching, file_handle::flag flags) noexcept
+inline result<int> attribs_from_handle_mode_caching_and_flags(native_handle_type &nativeh, file_handle::mode _mode, file_handle::creation _creation, file_handle::caching _caching, file_handle::flag) noexcept
{
int attribs = 0;
switch(_mode)
{
- case mode::unchanged:
- return make_errored_result<file_handle>(stl11::errc::invalid_argument);
- case mode::none:
+ case file_handle::mode::unchanged:
+ return make_errored_result<int>(stl11::errc::invalid_argument);
+ case file_handle::mode::none:
break;
- case mode::attr_read:
- case mode::read:
+ case file_handle::mode::attr_read:
+ case file_handle::mode::read:
attribs = O_RDONLY;
nativeh.behaviour |= native_handle_type::disposition::seekable | native_handle_type::disposition::readable;
break;
- case mode::attr_write:
- case mode::write:
+ case file_handle::mode::attr_write:
+ case file_handle::mode::write:
attribs = O_RDWR;
nativeh.behaviour |= native_handle_type::disposition::seekable | native_handle_type::disposition::readable | native_handle_type::disposition::writable;
break;
- case mode::append:
+ case file_handle::mode::append:
attribs = O_APPEND;
nativeh.behaviour |= native_handle_type::disposition::writable | native_handle_type::disposition::append_only;
break;
}
switch(_creation)
{
- case creation::open_existing:
+ case file_handle::creation::open_existing:
break;
- case creation::only_if_not_exist:
+ case file_handle::creation::only_if_not_exist:
attribs |= O_CREAT | O_EXCL;
break;
- case creation::if_needed:
+ case file_handle::creation::if_needed:
attribs |= O_CREAT;
break;
- case creation::truncate:
+ case file_handle::creation::truncate:
attribs |= O_TRUNC;
break;
}
switch(_caching)
{
- case caching::unchanged:
- return make_errored_result<file_handle>(stl11::errc::invalid_argument);
- case caching::none:
+ case file_handle::caching::unchanged:
+ return make_errored_result<int>(stl11::errc::invalid_argument);
+ case file_handle::caching::none:
attribs |= O_SYNC | O_DIRECT;
nativeh.behaviour |= native_handle_type::disposition::aligned_io;
break;
- case caching::only_metadata:
+ case file_handle::caching::only_metadata:
attribs |= O_DIRECT;
nativeh.behaviour |= native_handle_type::disposition::aligned_io;
break;
- case caching::reads:
+ case file_handle::caching::reads:
attribs |= O_SYNC;
break;
- case caching::reads_and_metadata:
+ case file_handle::caching::reads_and_metadata:
#ifdef O_DSYNC
attribs |= O_DSYNC;
#else
attribs |= O_SYNC;
#endif
break;
- case caching::all:
- case caching::safety_fsyncs:
- case caching::temporary:
+ case file_handle::caching::all:
+ case file_handle::caching::safety_fsyncs:
+ case file_handle::caching::temporary:
break;
}
+ return attribs;
}
result<void> file_handle::_fetch_inode() noexcept
@@ -191,18 +194,18 @@ inline result<void> check_inode(const file_handle &h) noexcept
result<file_handle> file_handle::file(file_handle::path_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(std::move(_path), native_handle_type(), _caching, flags));
+ result<file_handle> ret(file_handle(native_handle_type(), 0, 0, std::move(_path), _caching, flags));
native_handle_type &nativeh = ret.get()._v;
BOOST_OUTCOME_TRY(attribs, attribs_from_handle_mode_caching_and_flags(nativeh, _mode, _creation, _caching, flags));
nativeh.behaviour |= native_handle_type::disposition::file;
const char *path_ = ret.value()._path.c_str();
nativeh.fd = ::open(path_, attribs, 0x1b0 /*660*/);
if(-1 == nativeh.fd)
- return make_errored_result<file_handle>(errno, last190(ret.value()._path));
+ return make_errored_result<file_handle>(errno, last190(ret.value()._path.native()));
BOOST_AFIO_LOG_FUNCTION_CALL(nativeh.fd);
- if(!(flags & disable_safety_unlinks))
+ if(!(flags & flag::disable_safety_unlinks))
{
- BOOST_OUTCOME_TRYV(_fetch_inode());
+ BOOST_OUTCOME_TRYV(ret.value()._fetch_inode());
}
if(_creation == creation::truncate && ret.value().are_safety_fsyncs_issued())
fsync(nativeh.fd);
@@ -214,7 +217,7 @@ result<file_handle> file_handle::temp_inode(path_type dirpath, mode _mode, flag
caching _caching = caching::temporary;
// No need to rename to random on unlink or check inode before unlink
flags |= flag::unlink_on_close | flag::disable_safety_unlinks;
- result<file_handle> ret(file_handle(path_type(), native_handle_type(), _caching, flags));
+ result<file_handle> ret(file_handle(native_handle_type(), 0, 0, path_type(), _caching, flags));
native_handle_type &nativeh = ret.get()._v;
// Open file exclusively to prevent collision
BOOST_OUTCOME_TRY(attribs, attribs_from_handle_mode_caching_and_flags(nativeh, _mode, creation::only_if_not_exist, _caching, flags));
@@ -227,7 +230,7 @@ result<file_handle> file_handle::temp_inode(path_type dirpath, mode _mode, flag
nativeh.fd = ::open(path_, attribs, 0600);
if(-1 != nativeh.fd)
{
- BOOST_OUTCOME_TRYV(_fetch_inode()); // It can be useful to know the inode of temporary inodes
+ BOOST_OUTCOME_TRYV(ret.value()._fetch_inode()); // It can be useful to know the inode of temporary inodes
return ret;
}
// If it failed, assume this kernel or FS doesn't support O_TMPFILE
@@ -255,7 +258,7 @@ result<file_handle> file_handle::temp_inode(path_type dirpath, mode _mode, flag
// Immediately unlink after creation
if(-1 == ::unlink(path_))
return make_errored_result<file_handle>(errno);
- BOOST_OUTCOME_TRYV(_fetch_inode()); // It can be useful to know the inode of temporary inodes
+ BOOST_OUTCOME_TRYV(ret.value()._fetch_inode()); // It can be useful to know the inode of temporary inodes
return ret;
}
}
@@ -263,12 +266,12 @@ result<file_handle> file_handle::temp_inode(path_type dirpath, mode _mode, flag
result<file_handle> file_handle::clone() const noexcept
{
BOOST_AFIO_LOG_FUNCTION_CALL(_v.fd);
- result<file_handle> ret(file_handle(native_handle_type(), _path, _devid, _inode, _caching, _flags));
+ result<file_handle> ret(file_handle(native_handle_type(), _devid, _inode, _path, _caching, _flags));
ret.value()._service = _service;
ret.value()._v.behaviour = _v.behaviour;
ret.value()._v.fd = ::dup(_v.fd);
if(-1 == ret.value()._v.fd)
- return make_errored_result<file_handle>(errno, last190(_path));
+ return make_errored_result<file_handle>(errno, last190(_path.native()));
return ret;
}
@@ -279,7 +282,7 @@ result<file_handle::path_type> file_handle::relink(path_type newpath) noexcept
newpath = _path.parent_path() / newpath;
#ifdef O_TMPFILE
// If the handle was created with O_TMPFILE, we need a different approach
- if(_path.empty() && (_caching & caching::temporary))
+ if(_path.empty() && (_caching == file_handle::caching::temporary))
{
char path[PATH_MAX];
snprintf(path, PATH_MAX, "/proc/self/fd/%d", _v.fd);
@@ -290,12 +293,12 @@ result<file_handle::path_type> file_handle::relink(path_type newpath) noexcept
#endif
{
// FIXME: As soon as we implement fat paths, make this race free
- if(!(flags & disable_safety_unlinks))
+ if(!(_flags & flag::disable_safety_unlinks))
{
- BOOST_OUTCOME_TRYV(verify_inode(*this));
+ BOOST_OUTCOME_TRYV(check_inode(*this));
}
if(-1 == ::rename(_path.c_str(), newpath.c_str()))
- return make_errored_result<path_type>(errno, last190(_path));
+ return make_errored_result<path_type>(errno, last190(_path.native()));
}
_path = std::move(newpath);
return _path;
@@ -305,12 +308,12 @@ result<void> file_handle::unlink() noexcept
{
BOOST_AFIO_LOG_FUNCTION_CALL(_v.fd);
// FIXME: As soon as we implement fat paths, make this race free
- if(!(flags & disable_safety_unlinks))
+ if(!(_flags & flag::disable_safety_unlinks))
{
- BOOST_OUTCOME_TRYV(verify_inode(*this));
+ BOOST_OUTCOME_TRYV(check_inode(*this));
}
- if(-1 == ::rename(_path.c_str(), newpath.c_str()))
- return make_errored_result<path_type>(errno, last190(_path));
+ if(-1 == ::unlink(_path.c_str()))
+ return make_errored_result<void>(errno, last190(_path.native()));
_path.clear();
return make_valued_result<void>();
}
@@ -318,10 +321,10 @@ result<void> file_handle::unlink() noexcept
result<file_handle::extent_type> file_handle::length() const noexcept
{
BOOST_AFIO_LOG_FUNCTION_CALL(_v.fd);
- struct stat_t s;
+ struct stat s;
memset(&s, 0, sizeof(s));
if(-1 == ::fstat(_v.fd, &s))
- return make_errored_result<file_handle::extent_type>(errno, last190(_path));
+ return make_errored_result<file_handle::extent_type>(errno, last190(_path.native()));
return s.st_size;
}
@@ -329,7 +332,7 @@ result<file_handle::extent_type> file_handle::truncate(file_handle::extent_type
{
BOOST_AFIO_LOG_FUNCTION_CALL(_v.fd);
if(ftruncate(_v.fd, newsize) < 0)
- return make_errored_result<extent_type>(errno, last190(_path));
+ return make_errored_result<extent_type>(errno, last190(_path.native()));
if(are_safety_fsyncs_issued())
{
fsync(_v.fd);
diff --git a/include/boost/afio/v2.0/detail/impl/posix/handle.ipp b/include/boost/afio/v2.0/detail/impl/posix/handle.ipp
index 53452aaf..8ae0fbb4 100644
--- a/include/boost/afio/v2.0/detail/impl/posix/handle.ipp
+++ b/include/boost/afio/v2.0/detail/impl/posix/handle.ipp
@@ -32,6 +32,8 @@ DEALINGS IN THE SOFTWARE.
#include "../../../handle.hpp"
#include <fcntl.h>
+#include <limits.h> // for IOV_MAX
+#include <sys/uio.h> // for preadv etc
#include <unistd.h>
#if BOOST_AFIO_USE_POSIX_AIO
#include <aio.h>
@@ -77,7 +79,7 @@ result<handle> handle::clone() const noexcept
ret.value()._v.behaviour = _v.behaviour;
ret.value()._v.fd = ::dup(_v.fd);
if (-1 == ret.value()._v.fd)
- return make_errored_result<handle>(errno, last190(path()));
+ return make_errored_result<handle>(errno, last190(path().native()));
return ret;
}
@@ -86,13 +88,13 @@ result<void> handle::set_append_only(bool enable) noexcept
BOOST_AFIO_LOG_FUNCTION_CALL(_v.fd);
int attribs = fcntl(_v.fd, F_GETFL);
if(-1 == attribs)
- return make_errored_result<void>(errno);
+ return make_errored_result<void>(errno, last190(path().native()));
if(enable)
{
// Set append_only
attribs |= O_APPEND;
if(-1 == fcntl(_v.fd, F_SETFL, attribs))
- return make_errored_result<void>(errno);
+ return make_errored_result<void>(errno, last190(path().native()));
_v.behaviour |= native_handle_type::disposition::append_only;
}
else
@@ -100,7 +102,7 @@ result<void> handle::set_append_only(bool enable) noexcept
// Remove append_only
attribs &= ~O_APPEND;
if(-1 == fcntl(_v.fd, F_SETFL, attribs))
- return make_errored_result<void>(errno);
+ return make_errored_result<void>(errno, last190(path().native()));
_v.behaviour &= ~native_handle_type::disposition::append_only;
}
return make_result<void>();
@@ -119,41 +121,41 @@ result<void> handle::set_kernel_caching(caching caching) noexcept
);
switch(_caching)
{
- case caching::unchanged:
+ case handle::caching::unchanged:
break;
- case caching::none:
+ case handle::caching::none:
attribs |= O_SYNC | O_DIRECT;
if(-1 == fcntl(_v.fd, F_SETFL, attribs))
- return make_errored_result<void>(errno);
+ return make_errored_result<void>(errno, last190(path().native()));
_v.behaviour |= native_handle_type::disposition::aligned_io;
break;
- case caching::only_metadata:
+ case handle::caching::only_metadata:
attribs |= O_DIRECT;
if(-1 == fcntl(_v.fd, F_SETFL, attribs))
- return make_errored_result<void>(errno);
+ return make_errored_result<void>(errno, last190(path().native()));
_v.behaviour |= native_handle_type::disposition::aligned_io;
break;
- case caching::reads:
+ case handle::caching::reads:
attribs |= O_SYNC;
if(-1 == fcntl(_v.fd, F_SETFL, attribs))
- return make_errored_result<void>(errno);
+ return make_errored_result<void>(errno, last190(path().native()));
_v.behaviour &= ~native_handle_type::disposition::aligned_io;
break;
- case caching::reads_and_metadata:
+ case handle::caching::reads_and_metadata:
#ifdef O_DSYNC
attribs |= O_DSYNC;
#else
attribs |= O_SYNC;
#endif
if(-1 == fcntl(_v.fd, F_SETFL, attribs))
- return make_errored_result<void>(errno);
+ return make_errored_result<void>(errno, last190(path().native()));
_v.behaviour &= ~native_handle_type::disposition::aligned_io;
break;
- case caching::all:
- case caching::safety_fsyncs:
- case caching::temporary:
+ case handle::caching::all:
+ case handle::caching::safety_fsyncs:
+ case handle::caching::temporary:
if(-1 == fcntl(_v.fd, F_SETFL, attribs))
- return make_errored_result<void>(errno);
+ return make_errored_result<void>(errno, last190(path().native()));
_v.behaviour &= ~native_handle_type::disposition::aligned_io;
break;
}
@@ -171,16 +173,18 @@ io_handle::io_result<io_handle::buffers_type> io_handle::read(io_handle::io_requ
return make_errored_result<>(stl11::errc::not_supported);
if(reqs.buffers.size() > IOV_MAX)
return make_errored_result<>(stl11::errc::argument_list_too_long);
- struct iovec *iov = (struct iovec *) alloca(reqs.size() * sizeof(struct iovec));
+ struct iovec *iov = (struct iovec *) alloca(reqs.buffers.size() * sizeof(struct iovec));
for(size_t n = 0; n < reqs.buffers.size(); n++)
{
iov[n].iov_base = reqs.buffers[n].first;
iov[n].iov_len = reqs.buffers[n].second;
}
- ssize_t bytesread = ::preadv(_v.fd, iov, reqs.size(), reqs.offset);
+ ssize_t bytesread = ::preadv(_v.fd, iov, reqs.buffers.size(), reqs.offset);
+ if(bytesread < 0)
+ return make_errored_result<io_handle::buffers_type>(errno, last190(path().native()));
for(size_t n = 0; n < reqs.buffers.size(); n++)
{
- if(reqs.buffers[n].second >= bytesread)
+ if(reqs.buffers[n].second >= (size_t) bytesread)
bytesread -= reqs.buffers[n].second;
else if(bytesread > 0)
{
@@ -200,16 +204,18 @@ io_handle::io_result<io_handle::const_buffers_type> io_handle::write(io_handle::
return make_errored_result<>(stl11::errc::not_supported);
if(reqs.buffers.size() > IOV_MAX)
return make_errored_result<>(stl11::errc::argument_list_too_long);
- struct iovec *iov = (struct iovec *) alloca(reqs.size() * sizeof(struct iovec));
+ struct iovec *iov = (struct iovec *) alloca(reqs.buffers.size() * sizeof(struct iovec));
for(size_t n = 0; n < reqs.buffers.size(); n++)
{
- iov[n].iov_base = reqs.buffers[n].first;
+ iov[n].iov_base = const_cast<char *>(reqs.buffers[n].first);
iov[n].iov_len = reqs.buffers[n].second;
}
- ssize_t byteswritten = ::pwritev(_v.fd, iov, reqs.size(), reqs.offset);
+ ssize_t byteswritten = ::pwritev(_v.fd, iov, reqs.buffers.size(), reqs.offset);
+ if(byteswritten < 0)
+ return make_errored_result<io_handle::const_buffers_type>(errno, last190(path().native()));
for(size_t n = 0; n < reqs.buffers.size(); n++)
{
- if(reqs.buffers[n].second >= byteswritten)
+ if(reqs.buffers[n].second >= (size_t) byteswritten)
byteswritten -= reqs.buffers[n].second;
else if(byteswritten > 0)
{
@@ -241,25 +247,25 @@ result<io_handle::extent_guard> io_handle::lock(io_handle::extent_type offset, i
{
struct flock fl;
memset(&fl, 0, sizeof(fl));
- fl.l_type = exclusive ? F_WRLOCK : F_RDLCK;
+ fl.l_type = exclusive ? F_WRLCK : F_RDLCK;
constexpr extent_type extent_topbit = (extent_type) 1<<(8*sizeof(extent_type)-1);
if(offset & extent_topbit)
{
- BOOST_AFIO_LOG_WARNING(_v.fd, "io_handle::lock() called with offset with top bit set, masking out");
+ BOOST_AFIO_LOG_WARN(_v.fd, "io_handle::lock() called with offset with top bit set, masking out");
}
if(bytes & extent_topbit)
{
- BOOST_AFIO_LOG_WARNING(_v.fd, "io_handle::lock() called with bytes with top bit set, masking out");
+ BOOST_AFIO_LOG_WARN(_v.fd, "io_handle::lock() called with bytes with top bit set, masking out");
}
fl.l_whence = SEEK_SET;
fl.l_start = offset & ~extent_topbit;
fl.l_len = bytes & ~extent_topbit;
#ifdef F_OFD_SETLK
- if(-1 == fcntl(_v.fd, (d && !d.nsec) ? F_OFD_SETLK : F_OFD_SETLKW, &fl))
+ if(-1 == fcntl(_v.fd, (d && !d.nsecs) ? F_OFD_SETLK : F_OFD_SETLKW, &fl))
{
if(EINVAL == errno) // OFD locks not supported on this kernel
{
- if(-1 == fcntl(_v.fd, (d && !d.nsec) ? F_SETLK : F_SETLKW, &fl))
+ if(-1 == fcntl(_v.fd, (d && !d.nsecs) ? F_SETLK : F_SETLKW, &fl))
failed = true;
else
_flags |= flag::byte_lock_insanity;
@@ -268,7 +274,7 @@ result<io_handle::extent_guard> io_handle::lock(io_handle::extent_type offset, i
failed = true;
}
#else
- if(-1 == fcntl(_v.fd, (d && !d.nsec) ? F_SETLK : F_SETLKW, &fl))
+ if(-1 == fcntl(_v.fd, (d && !d.nsecs) ? F_SETLK : F_SETLKW, &fl))
failed = true;
else
_flags |= flag::byte_lock_insanity;
@@ -279,7 +285,7 @@ result<io_handle::extent_guard> io_handle::lock(io_handle::extent_type offset, i
if(d && !d.nsecs && (EACCES == errno || EAGAIN == errno || EWOULDBLOCK == errno))
return make_errored_result<void>(stl11::errc::timed_out);
else
- return make_errored_result<void>(errno);
+ return make_errored_result<void>(errno, last190(path().native()));
}
return extent_guard(this, offset, bytes, exclusive);
}
diff --git a/include/boost/afio/v2.0/detail/impl/posix/io_service.ipp b/include/boost/afio/v2.0/detail/impl/posix/io_service.ipp
index 8211da80..3f29caa0 100644
--- a/include/boost/afio/v2.0/detail/impl/posix/io_service.ipp
+++ b/include/boost/afio/v2.0/detail/impl/posix/io_service.ipp
@@ -29,7 +29,7 @@ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
-#include "../../../handle.hpp"
+#include "../../../async_file_handle.hpp"
#include <pthread.h>
#if BOOST_AFIO_USE_POSIX_AIO
@@ -73,7 +73,8 @@ int io_service::set_interruption_signal(int signo)
{
for(signo=SIGRTMIN; signo<SIGRTMAX; signo++)
{
- struct sigaction sigact = { 0 };
+ struct sigaction sigact;
+ memset(&sigact, 0, sizeof(sigact));
if(sigaction(signo, nullptr, &sigact)>=0)
{
if(sigact.sa_handler==SIG_DFL)
@@ -83,7 +84,8 @@ int io_service::set_interruption_signal(int signo)
}
#endif
// Install process wide signal handler for signal
- struct sigaction sigact = { 0 };
+ struct sigaction sigact;
+ memset(&sigact, 0, sizeof(sigact));
sigact.sa_sigaction=&interrupt_signal_handler;
sigact.sa_flags=SA_SIGINFO;
sigemptyset(&sigact.sa_mask);
@@ -144,7 +146,9 @@ io_service::~io_service()
{
if (_work_queued)
{
- std::cerr << "WARNING: ~io_service() sees work still queued, blocking until no work queued" << std::endl;
+#ifndef NDEBUG
+ fprintf(stderr, "WARNING: ~io_service() sees work still queued, blocking until no work queued\n");
+#endif
while (_work_queued)
std::this_thread::yield();
}
@@ -201,7 +205,8 @@ result<bool> io_service::run_until(deadline d) noexcept
else
end_utc = d.to_time_point();
}
- struct timespec *ts=nullptr, _ts={0};
+ struct timespec *ts=nullptr, _ts;
+ memset(&_ts, 0, sizeof(_ts));
bool done=false;
do
{
@@ -283,7 +288,7 @@ result<bool> io_service::run_until(deadline d) noexcept
int errcode=ioret<0 ? errno : 0;
// std::cout << "aiocb " << aiocb << " sees return " << ioret << " errno " << errcode << std::endl;
// The aiocb aio_sigevent.sigev_value.sival_ptr field will point to a file_handle::_io_state_type
- auto io_state=(file_handle::_erased_io_state_type *) aiocb->aio_sigevent.sigev_value.sival_ptr;
+ auto io_state=(async_file_handle::_erased_io_state_type *) aiocb->aio_sigevent.sigev_value.sival_ptr;
assert(io_state);
(*io_state)(errcode, ioret, &aiocb);
}
diff --git a/include/boost/afio/v2.0/detail/impl/posix/map_handle.ipp b/include/boost/afio/v2.0/detail/impl/posix/map_handle.ipp
index 852a428a..78fa9370 100644
--- a/include/boost/afio/v2.0/detail/impl/posix/map_handle.ipp
+++ b/include/boost/afio/v2.0/detail/impl/posix/map_handle.ipp
@@ -52,7 +52,7 @@ result<section_handle> section_handle::section(file_handle &backing, extent_type
maximum_size = utils::round_up_to_page_size(maximum_size);
result<section_handle> ret(section_handle(native_handle_type(), backing.is_valid() ? &backing : nullptr, maximum_size, _flag));
// There are no section handles on POSIX, so do nothing
- BOOST_AFIO_LOG_FUNCTION_CALL(nativeh.h);
+ BOOST_AFIO_LOG_FUNCTION_CALL(ret.value()._v.fd);
return ret;
}
@@ -104,17 +104,10 @@ native_handle_type map_handle::release() noexcept
return native_handle_type();
}
-
-result<map_handle> map_handle::map(section_handle &section, size_type bytes, extent_type offset, section_handle::flag _flag) noexcept
+inline result<void *> do_mmap(native_handle_type &nativeh, void *ataddr, section_handle &section, map_handle::size_type bytes, map_handle::extent_type offset, section_handle::flag _flag) noexcept
{
- if(!section.backing)
- {
- // Do NOT round up bytes to the nearest page size, it causes an attempt to extend the file
- bytes = utils::round_up_to_page_size(bytes);
- }
- result<map_handle> ret(map_handle(io_handle(), &section));
- native_handle_type &nativeh = ret.get()._v;
- int prot = 0, int flags = backing ? MAP_SHARED : MAP_ANONYMOUS;
+ bool have_backing = section.backing();
+ int prot = 0, flags = have_backing ? MAP_SHARED : MAP_ANONYMOUS;
void *addr = nullptr;
if(_flag == section_handle::flag::none)
{
@@ -152,116 +145,118 @@ result<map_handle> map_handle::map(section_handle &section, size_type bytes, ext
flags |= MAP_PREFAULT_READ;
#endif
#ifdef MAP_NOSYNC
- if(section.backing && (section.backing->kernel_caching() == handle::caching::temporary))
+ if(have_backing && (section.backing()->kernel_caching() == handle::caching::temporary))
flags |= MAP_NOSYNC;
#endif
- addr = ::mmap(nullptr, bytes, prot, flags, section.native_handle().fd, offset);
+ addr = ::mmap(ataddr, bytes, prot, flags, have_backing ? section.backing_native_handle().fd : -1, offset);
if(!addr)
- return make_errored_result<map_handle>(errno);
+ return make_errored_result<void *>(errno);
+ return addr;
+}
+
+result<map_handle> map_handle::map(section_handle &section, size_type bytes, extent_type offset, section_handle::flag _flag) noexcept
+{
+ if(!section.backing())
+ {
+ // Do NOT round up bytes to the nearest page size for backed maps, it causes an attempt to extend the file
+ bytes = utils::round_up_to_page_size(bytes);
+ }
+ result<map_handle> ret(map_handle(io_handle(), &section));
+ native_handle_type &nativeh = ret.get()._v;
+ BOOST_OUTCOME_TRY(addr, do_mmap(nativeh, nullptr, section, bytes, offset, _flag));
ret.get()._addr = (char *) addr;
- ret.get()._length = _bytes;
+ ret.get()._offset = offset;
+ ret.get()._length = bytes;
// Make my handle borrow the native handle of my backing storage
- ret.get()._v.h = section.backing_native_handle().h;
- BOOST_AFIO_LOG_FUNCTION_CALL(ret.get()._v.h);
+ ret.get()._v.fd = section.backing_native_handle().fd;
+ BOOST_AFIO_LOG_FUNCTION_CALL(ret.get()._v.fd);
return ret;
}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
result<map_handle::buffer_type> map_handle::commit(buffer_type region, section_handle::flag _flag) noexcept
{
+ BOOST_AFIO_LOG_FUNCTION_CALL(_v.fd);
+ if(!region.first)
+ return make_errored_result<map_handle::buffer_type>(stl11::errc::invalid_argument);
+ // Set permissions on the pages
+ region = utils::round_to_page_size(region);
+ extent_type offset = _offset + (region.first - _addr);
+ size_type bytes = region.second;
+ BOOST_OUTCOME_TRYV(do_mmap(_v, region.first, section, bytes, offset, _flag));
+ // Tell the kernel we will be using these pages soon
+ if(-1 == ::madvise(region.first, region.second, MADV_WILLNEED))
+ return make_errored_result<map_handle::buffer_type>(errno);
+ return region;
+}
+
+result<map_handle::buffer_type> map_handle::decommit(buffer_type region) noexcept
+{
BOOST_AFIO_LOG_FUNCTION_CALL(_v.h);
if(!region.first)
return make_errored_result<map_handle::buffer_type>(stl11::errc::invalid_argument);
- DWORD prot = 0;
- if(_flag == section_handle::flag::none)
- {
- BOOST_OUTCOME_TRY(_region, do_not_store(region));
- DWORD _ = 0;
- if(!VirtualProtect(_region.first, _region.second, PAGE_NOACCESS, &_))
- return make_errored_result<buffer_type>(GetLastError());
- return _region;
- }
- if(_flag & section_handle::flag::cow)
- {
- prot = PAGE_WRITECOPY;
- _v.behaviour |= native_handle_type::disposition::seekable | native_handle_type::disposition::readable | native_handle_type::disposition::writable;
- }
- else if(_flag & section_handle::flag::write)
- {
- prot = PAGE_READWRITE;
- _v.behaviour |= native_handle_type::disposition::seekable | native_handle_type::disposition::readable | native_handle_type::disposition::writable;
- }
- else if(_flag & section_handle::flag::read)
- {
- prot = PAGE_READONLY;
- _v.behaviour |= native_handle_type::disposition::seekable | native_handle_type::disposition::readable;
- }
- if(_flag & section_handle::flag::execute)
- prot = PAGE_EXECUTE;
region = utils::round_to_page_size(region);
- if(!VirtualAlloc(region.first, region.second, MEM_COMMIT, prot))
- return make_errored_result<buffer_type>(GetLastError());
+ // Tell the kernel to kick these pages into storage
+ if(-1 == ::madvise(region.first, region.second, MADV_DONTNEED))
+ return make_errored_result<map_handle::buffer_type>(errno);
+ // Set permissions on the pages to no access
+ extent_type offset = _offset + (region.first - _addr);
+ size_type bytes = region.second;
+ BOOST_OUTCOME_TRYV(do_mmap(_v, region.first, section, bytes, offset, section_handle::flag::none));
return region;
}
result<void> map_handle::zero(buffer_type region) noexcept
{
- BOOST_AFIO_LOG_FUNCTION_CALL(_v.h);
+ BOOST_AFIO_LOG_FUNCTION_CALL(_v.fd);
if(!region.first)
return make_errored_result<void>(stl11::errc::invalid_argument);
+#ifdef MADV_REMOVE
+ buffer_type page_region { (char *) utils::round_up_to_page_size((uintptr_t) region.first), utils::round_down_to_page_size(region.second) };
+ // Zero contents and punch a hole in any backing storage
+ if(page_region.second && -1 != ::madvise(page_region.first, page_region.second, MADV_REMOVE))
+ {
+ memset(region.first, 0, page_region.first - region.first);
+ memset(page_region.first + page_region.second, 0, (region.first + region.second) - (page_region.first + page_region.second));
+ return make_valued_result<void>();
+ }
+#endif
//! \todo Once you implement file_handle::zero(), please implement map_handle::zero()
- // buffer_type page_region { (char *) utils::round_up_to_page_size((uintptr_t) region.first), utils::round_down_to_page_size(region.second); };
memset(region.first, 0, region.second);
return make_valued_result<void>();
}
result<span<map_handle::buffer_type>> map_handle::prefetch(span<buffer_type> regions) noexcept
{
- windows_nt_kernel::init();
- using namespace windows_nt_kernel;
BOOST_AFIO_LOG_FUNCTION_CALL(0);
- if(!PrefetchVirtualMemory_)
- return span<map_handle::buffer_type>();
- PWIN32_MEMORY_RANGE_ENTRY wmre = (PWIN32_MEMORY_RANGE_ENTRY) regions.data();
- if(!PrefetchVirtualMemory_(GetCurrentProcess(), regions.size(), wmre, 0))
- return make_errored_result<span<map_handle::buffer_type>>(GetLastError());
+ for(const auto &region : regions)
+ {
+ if(-1 == ::madvise(region.first, region.second, MADV_WILLNEED))
+ return make_errored_result<span<map_handle::buffer_type>>(errno);
+ }
return regions;
}
result<map_handle::buffer_type> map_handle::do_not_store(buffer_type region) noexcept
{
+ BOOST_AFIO_LOG_FUNCTION_CALL(0);
region = utils::round_to_page_size(region);
if(!region.first)
return make_errored_result<map_handle::buffer_type>(stl11::errc::invalid_argument);
- if(!VirtualAlloc(region.first, region.second, MEM_RESET, 0))
- return make_errored_result<buffer_type>(GetLastError());
+#ifdef MADV_FREE
+ // Tell the kernel to throw away the contents of these pages
+ if(-1 == ::madvise(_region.first, _region.second, MADV_FREE))
+ return make_errored_result<map_handle::buffer_type>(errno);
+ else
+ return region;
+#endif
+ // No support on this platform
+ region.second = 0;
return region;
}
map_handle::io_result<map_handle::buffers_type> map_handle::read(io_request<buffers_type> reqs, deadline) noexcept
{
- BOOST_AFIO_LOG_FUNCTION_CALL(_v.h);
+ BOOST_AFIO_LOG_FUNCTION_CALL(_v.fd);
char *addr = _addr + reqs.offset;
size_type togo = (size_type)(_length - reqs.offset);
for(buffer_type &req : reqs.buffers)
@@ -282,7 +277,7 @@ map_handle::io_result<map_handle::buffers_type> map_handle::read(io_request<buff
map_handle::io_result<map_handle::const_buffers_type> map_handle::write(io_request<const_buffers_type> reqs, deadline) noexcept
{
- BOOST_AFIO_LOG_FUNCTION_CALL(_v.h);
+ BOOST_AFIO_LOG_FUNCTION_CALL(_v.fd);
char *addr = _addr + reqs.offset;
size_type togo = (size_type)(_length - reqs.offset);
for(const_buffer_type &req : reqs.buffers)
diff --git a/include/boost/afio/v2.0/detail/impl/posix/stat.ipp b/include/boost/afio/v2.0/detail/impl/posix/stat.ipp
index 607479ee..ec5c82f0 100644
--- a/include/boost/afio/v2.0/detail/impl/posix/stat.ipp
+++ b/include/boost/afio/v2.0/detail/impl/posix/stat.ipp
@@ -31,17 +31,73 @@ DEALINGS IN THE SOFTWARE.
#include "../../../handle.hpp"
#include "../../../stat.hpp"
-#include "import.hpp"
+
+#include <sys/stat.h>
BOOST_AFIO_V2_NAMESPACE_BEGIN
-BOOST_AFIO_HEADERS_ONLY_MEMFUNC_SPEC result<size_t> stat_t::fill(handle &h, stat_t::want wanted) noexcept
+static inline stl1z::filesystem::file_type to_st_type(uint16_t mode)
+{
+ switch(mode & S_IFMT)
+ {
+#ifdef BOOST_AFIO_USE_LEGACY_FILESYSTEM_SEMANTICS
+ case S_IFBLK:
+ return stl1z::filesystem::file_type::block_file;
+ case S_IFCHR:
+ return stl1z::filesystem::file_type::character_file;
+ case S_IFDIR:
+ return stl1z::filesystem::file_type::directory_file;
+ case S_IFIFO:
+ return stl1z::filesystem::file_type::fifo_file;
+ case S_IFLNK:
+ return stl1z::filesystem::file_type::symlink_file;
+ case S_IFREG:
+ return stl1z::filesystem::file_type::regular_file;
+ case S_IFSOCK:
+ return stl1z::filesystem::file_type::socket_file;
+ default:
+ return stl1z::filesystem::file_type::type_unknown;
+#else
+ case S_IFBLK:
+ return stl1z::filesystem::file_type::block;
+ case S_IFCHR:
+ return stl1z::filesystem::file_type::character;
+ case S_IFDIR:
+ return stl1z::filesystem::file_type::directory;
+ case S_IFIFO:
+ return stl1z::filesystem::file_type::fifo;
+ case S_IFLNK:
+ return stl1z::filesystem::file_type::symlink;
+ case S_IFREG:
+ return stl1z::filesystem::file_type::regular;
+ case S_IFSOCK:
+ return stl1z::filesystem::file_type::socket;
+ default:
+ return stl1z::filesystem::file_type::unknown;
+#endif
+ }
+}
+
+static inline stl11::chrono::system_clock::time_point to_timepoint(struct timespec ts)
+{
+ // Need to have this self-adapt to the STL being used
+ static constexpr unsigned long long STL_TICKS_PER_SEC=(unsigned long long) stl11::chrono::system_clock::period::den/stl11::chrono::system_clock::period::num;
+ static constexpr unsigned long long multiplier=STL_TICKS_PER_SEC>=1000000000ULL ? STL_TICKS_PER_SEC/1000000000ULL : 1;
+ static constexpr unsigned long long divider=STL_TICKS_PER_SEC>=1000000000ULL ? 1 : 1000000000ULL/STL_TICKS_PER_SEC;
+ // For speed we make the big assumption that the STL's system_clock is based on the time_t epoch 1st Jan 1970.
+ stl11::chrono::system_clock::duration duration(ts.tv_sec*STL_TICKS_PER_SEC+ts.tv_nsec*multiplier/divider);
+ return stl11::chrono::system_clock::time_point(duration);
+}
+
+BOOST_AFIO_HEADERS_ONLY_MEMFUNC_SPEC result<size_t> stat_t::fill(const handle &h, stat_t::want wanted) noexcept
{
BOOST_AFIO_LOG_FUNCTION_CALL(h.native_handle().fd);
- struct stat_t s;
+ struct stat s;
memset(&s, 0, sizeof(s));
+ size_t ret = 0;
+
if(-1 == ::fstat(h.native_handle().fd, &s))
- return make_errored_result<size_t>(errno, last190(h.path()));
+ return make_errored_result<size_t>(errno, last190(h.path().native()));
if(wanted&want::dev) { st_dev=s.st_dev; ++ret; }
if(wanted&want::ino) { st_ino=s.st_ino; ++ret; }
if(wanted&want::type) { st_type=to_st_type(s.st_mode); ++ret; }
diff --git a/include/boost/afio/v2.0/detail/impl/posix/statfs.ipp b/include/boost/afio/v2.0/detail/impl/posix/statfs.ipp
index a46525f5..c71ed66e 100644
--- a/include/boost/afio/v2.0/detail/impl/posix/statfs.ipp
+++ b/include/boost/afio/v2.0/detail/impl/posix/statfs.ipp
@@ -40,61 +40,62 @@ DEALINGS IN THE SOFTWARE.
BOOST_AFIO_V2_NAMESPACE_BEGIN
-BOOST_AFIO_HEADERS_ONLY_MEMFUNC_SPEC result<size_t> statfs_t::fill(handle &h, statfs_t::want wanted) noexcept
+BOOST_AFIO_HEADERS_ONLY_MEMFUNC_SPEC result<size_t> statfs_t::fill(const handle &h, statfs_t::want wanted) noexcept
{
size_t ret = 0;
#ifdef __linux__
- struct statfs64 s = {0};
+ struct statfs64 s;
+ memset(&s, 0, sizeof(s));
if(-1 == fstatfs64(h.native_handle().fd, &s))
return make_errored_result<size_t>(errno);
- if(!!(wanted && want::bsize))
+ if(!!(wanted & want::bsize))
{
f_bsize = s.f_bsize;
++ret;
}
- if(!!(wanted && want::iosize))
+ if(!!(wanted & want::iosize))
{
f_iosize = s.f_frsize;
++ret;
}
- if(!!(wanted && want::blocks))
+ if(!!(wanted & want::blocks))
{
f_blocks = s.f_blocks;
++ret;
}
- if(!!(wanted && want::bfree))
+ if(!!(wanted & want::bfree))
{
f_bfree = s.f_bfree;
++ret;
}
- if(!!(wanted && want::bavail))
+ if(!!(wanted & want::bavail))
{
f_bavail = s.f_bavail;
++ret;
}
- if(!!(wanted && want::files))
+ if(!!(wanted & want::files))
{
f_files = s.f_files;
++ret;
}
- if(!!(wanted && want::ffree))
+ if(!!(wanted & want::ffree))
{
f_ffree = s.f_ffree;
++ret;
}
- if(!!(wanted && want::namemax))
+ if(!!(wanted & want::namemax))
{
f_namemax = s.f_namelen;
++ret;
}
// if(!!(wanted&&want::owner)) { f_owner =s.f_owner; ++ret; }
- if(!!(wanted && want::fsid))
+ if(!!(wanted & want::fsid))
{
f_fsid[0] = (unsigned) s.f_fsid.__val[0];
f_fsid[1] = (unsigned) s.f_fsid.__val[1];
++ret;
}
- if(!!(wanted && want::flags) || !!(wanted && want::fstypename) || !!(wanted && want::mntfromname) || !!(wanted && want::mntonname))
+ if(!!(wanted & want::flags) || !!(wanted & want::fstypename) || !!(wanted & want::mntfromname) || !!(wanted & want::mntonname))
{
struct mountentry
{
@@ -118,7 +119,8 @@ BOOST_AFIO_HEADERS_ONLY_MEMFUNC_SPEC result<size_t> statfs_t::fill(handle &h, st
char buffer[32768];
while(getmntent_r(mtab, &m, buffer, sizeof(buffer)))
{
- struct statfs64 temp = {0};
+ struct statfs64 temp;
+ memset(&temp, 0, sizeof(temp));
if(0 == statfs64(m.mnt_dir, &temp) && temp.f_type == s.f_type && !memcmp(&temp.f_fsid, &s.f_fsid, sizeof(s.f_fsid)))
mountentries.push_back(std::make_pair(mountentry(m.mnt_fsname, m.mnt_dir, m.mnt_type, m.mnt_opts), temp));
}
@@ -146,7 +148,7 @@ BOOST_AFIO_HEADERS_ONLY_MEMFUNC_SPEC result<size_t> statfs_t::fill(handle &h, st
mountentries.push_back(std::move(temp));
}
#endif
- if(!!(wanted && want::flags))
+ if(!!(wanted & want::flags))
{
f_flags.rdonly = !!(s.f_flags & MS_RDONLY);
f_flags.noexec = !!(s.f_flags & MS_NOEXEC);
@@ -158,17 +160,17 @@ BOOST_AFIO_HEADERS_ONLY_MEMFUNC_SPEC result<size_t> statfs_t::fill(handle &h, st
f_flags.extents = (mountentries.front().first.mnt_type == "btrfs" || mountentries.front().first.mnt_type == "ext4" || mountentries.front().first.mnt_type == "xfs" || mountentries.front().first.mnt_type == "tmpfs");
++ret;
}
- if(!!(wanted && want::fstypename))
+ if(!!(wanted & want::fstypename))
{
f_fstypename = mountentries.front().first.mnt_type;
++ret;
}
- if(!!(wanted && want::mntfromname))
+ if(!!(wanted & want::mntfromname))
{
f_mntfromname = mountentries.front().first.mnt_fsname;
++ret;
}
- if(!!(wanted && want::mntonname))
+ if(!!(wanted & want::mntonname))
{
f_mntonname = mountentries.front().first.mnt_dir;
++ret;
@@ -178,7 +180,7 @@ BOOST_AFIO_HEADERS_ONLY_MEMFUNC_SPEC result<size_t> statfs_t::fill(handle &h, st
struct statfs s;
if(-1 == fstatfs(h.native_handle().fd, &s))
return make_errored_result<size_t>(errno);
- if(!!(wanted && want::flags))
+ if(!!(wanted & want::flags))
{
f_flags.rdonly = !!(s.f_flags & MNT_RDONLY);
f_flags.noexec = !!(s.f_flags & MNT_NOEXEC);
@@ -192,76 +194,76 @@ BOOST_AFIO_HEADERS_ONLY_MEMFUNC_SPEC result<size_t> statfs_t::fill(handle &h, st
f_flags.extents = !strcmp(s.f_fstypename, "ufs") || !strcmp(s.f_fstypename, "zfs");
++ret;
}
- if(!!(wanted && want::bsize))
+ if(!!(wanted & want::bsize))
{
f_bsize = s.f_bsize;
++ret;
}
- if(!!(wanted && want::iosize))
+ if(!!(wanted & want::iosize))
{
f_iosize = s.f_iosize;
++ret;
}
- if(!!(wanted && want::blocks))
+ if(!!(wanted & want::blocks))
{
f_blocks = s.f_blocks;
++ret;
}
- if(!!(wanted && want::bfree))
+ if(!!(wanted & want::bfree))
{
f_bfree = s.f_bfree;
++ret;
}
- if(!!(wanted && want::bavail))
+ if(!!(wanted & want::bavail))
{
f_bavail = s.f_bavail;
++ret;
}
- if(!!(wanted && want::files))
+ if(!!(wanted & want::files))
{
f_files = s.f_files;
++ret;
}
- if(!!(wanted && want::ffree))
+ if(!!(wanted & want::ffree))
{
f_ffree = s.f_ffree;
++ret;
}
#ifdef __APPLE__
- if(!!(wanted && want::namemax))
+ if(!!(wanted & want::namemax))
{
f_namemax = 255;
++ret;
}
#else
- if(!!(wanted && want::namemax))
+ if(!!(wanted & want::namemax))
{
f_namemax = s.f_namemax;
++ret;
}
#endif
- if(!!(wanted && want::owner))
+ if(!!(wanted & want::owner))
{
f_owner = s.f_owner;
++ret;
}
- if(!!(wanted && want::fsid))
+ if(!!(wanted & want::fsid))
{
f_fsid[0] = (unsigned) s.f_fsid.val[0];
f_fsid[1] = (unsigned) s.f_fsid.val[1];
++ret;
}
- if(!!(wanted && want::fstypename))
+ if(!!(wanted & want::fstypename))
{
f_fstypename = s.f_fstypename;
++ret;
}
- if(!!(wanted && want::mntfromname))
+ if(!!(wanted & want::mntfromname))
{
f_mntfromname = s.f_mntfromname;
++ret;
}
- if(!!(wanted && want::mntonname))
+ if(!!(wanted & want::mntonname))
{
f_mntonname = s.f_mntonname;
++ret;
diff --git a/include/boost/afio/v2.0/detail/impl/posix/storage_profile.ipp b/include/boost/afio/v2.0/detail/impl/posix/storage_profile.ipp
index 3a7c31da..680f6943 100644
--- a/include/boost/afio/v2.0/detail/impl/posix/storage_profile.ipp
+++ b/include/boost/afio/v2.0/detail/impl/posix/storage_profile.ipp
@@ -49,7 +49,7 @@ namespace storage_profile
namespace system
{
// OS name, version
- outcome<void> os(storage_profile &sp, file_handle &h) noexcept
+ outcome<void> os(storage_profile &sp, file_handle &) noexcept
{
static std::string os_name, os_ver;
if (!os_name.empty())
@@ -61,7 +61,8 @@ namespace storage_profile
{
try
{
- struct utsname name = {0};
+ struct utsname name;
+ memset(&name, 0, sizeof(name));
if(uname(&name)<0)
return make_errored_outcome<void>(errno);
sp.os_name.value = os_name = name.sysname;
@@ -76,7 +77,7 @@ namespace storage_profile
}
// CPU name, architecture, physical cores
- outcome<void> cpu(storage_profile &sp, file_handle &h) noexcept
+ outcome<void> cpu(storage_profile &sp, file_handle &) noexcept
{
static std::string cpu_name, cpu_architecture;
static unsigned cpu_physical_cores;
@@ -90,7 +91,8 @@ namespace storage_profile
{
try
{
- struct utsname name = {0};
+ struct utsname name;
+ memset(&name, 0, sizeof(name));
if(uname(&name)<0)
return make_errored_outcome<void>(errno);
sp.cpu_name.value = sp.cpu_architecture.value = name.machine;
@@ -192,7 +194,7 @@ namespace storage_profile
}
namespace posix
{
- outcome<void> _mem(storage_profile &sp, file_handle &h) noexcept
+ outcome<void> _mem(storage_profile &sp, file_handle &) noexcept
{
#if defined(_SC_PHYS_PAGES)
size_t physpages=sysconf (_SC_PHYS_PAGES), pagesize=sysconf (_SC_PAGESIZE);
@@ -222,7 +224,7 @@ namespace storage_profile
namespace posix
{
// Controller type, max transfer, max buffers. Device name, size
- outcome<void> _device(storage_profile &sp, file_handle &h, std::string mntfromname, std::string fstypename) noexcept
+ outcome<void> _device(storage_profile &sp, file_handle &, std::string mntfromname, std::string /*fstypename*/) noexcept
{
try
{
@@ -266,7 +268,7 @@ namespace storage_profile
#endif
return make_errored_outcome<void>(stl11::errc::function_not_supported);
}
- BOOST_OUTCOME_TRY(deviceh, file_handle::file(*h.service(), mntfromname, handle::mode::none, handle::creation::open_existing, handle::caching::only_metadata));
+ BOOST_OUTCOME_TRY(deviceh, file_handle::file(mntfromname, handle::mode::none, handle::creation::open_existing, handle::caching::only_metadata));
// TODO See https://github.com/baruch/diskscan/blob/master/arch/arch-linux.c
// sp.controller_type.value = "SCSI";
diff --git a/include/boost/afio/v2.0/detail/impl/posix/utils.ipp b/include/boost/afio/v2.0/detail/impl/posix/utils.ipp
index 4a49638a..06bb29a1 100644
--- a/include/boost/afio/v2.0/detail/impl/posix/utils.ipp
+++ b/include/boost/afio/v2.0/detail/impl/posix/utils.ipp
@@ -31,6 +31,8 @@ DEALINGS IN THE SOFTWARE.
#include "../../../utils.hpp"
+#include "../boost-lite/include/spinlock.hpp"
+
#include <sys/mman.h>
BOOST_AFIO_V2_NAMESPACE_BEGIN
@@ -46,7 +48,7 @@ namespace utils
}
std::vector<size_t> page_sizes(bool only_actually_available)
{
- static spinlock<bool> lock;
+ static boost_lite::configurable_spinlock::spinlock<bool> lock;
static std::vector<size_t> pagesizes, pagesizes_available;
stl11::lock_guard<decltype(lock)> g(lock);
if(pagesizes.empty())
@@ -119,14 +121,14 @@ namespace utils
void random_fill(char *buffer, size_t bytes)
{
- static spinlock<bool> lock;
+ static boost_lite::configurable_spinlock::spinlock<bool> lock;
static int randomfd = -1;
if(-1 == randomfd)
{
stl11::lock_guard<decltype(lock)> g(lock);
randomfd = ::open("/dev/urandom", O_RDONLY);
}
- if(-1 == randomfd || ::read(randomfd, buffer, bytes) < bytes)
+ if(-1 == randomfd || ::read(randomfd, buffer, bytes) < (ssize_t) bytes)
{
BOOST_AFIO_LOG_FATAL(0, "afio: Kernel crypto function failed");
std::terminate();
@@ -159,7 +161,7 @@ namespace utils
}
#ifndef NDEBUG
else if(ret.page_size_used > 65536)
- std::cout << "afio: Large page allocation successful" << std::endl;
+ printf("afio: Large page allocation successful\n");
#endif
return ret;
}
diff --git a/include/boost/afio/v2.0/detail/impl/windows/map_handle.ipp b/include/boost/afio/v2.0/detail/impl/windows/map_handle.ipp
index c385e05b..d34e4a89 100644
--- a/include/boost/afio/v2.0/detail/impl/windows/map_handle.ipp
+++ b/include/boost/afio/v2.0/detail/impl/windows/map_handle.ipp
@@ -49,7 +49,7 @@ result<section_handle> section_handle::section(file_handle &backing, extent_type
else
return make_errored_result<section_handle>(stl11::errc::invalid_argument);
}
- // Do NOT round up to page size here, it causes STATUS_SECTION_TOO_BIG
+ // Do NOT round up to page size here if backed by a file, it causes STATUS_SECTION_TOO_BIG
if(!backing.is_valid())
maximum_size = utils::round_up_to_page_size(maximum_size);
result<section_handle> ret(section_handle(native_handle_type(), backing.is_valid() ? &backing : nullptr, maximum_size, _flag));
@@ -175,8 +175,11 @@ result<map_handle> map_handle::map(section_handle &section, size_type bytes, ext
{
windows_nt_kernel::init();
using namespace windows_nt_kernel;
- // Do NOT round up bytes to the nearest page size, it causes an attempt to extend the file
- // bytes = utils::round_up_to_page_size(bytes);
+ if(!section.backing())
+ {
+ // Do NOT round up bytes to the nearest page size for backed maps, it causes an attempt to extend the file
+ bytes = utils::round_up_to_page_size(bytes);
+ }
result<map_handle> ret(map_handle(io_handle(), &section));
native_handle_type &nativeh = ret.get()._v;
ULONG allocation = 0, prot = 0;
@@ -219,6 +222,7 @@ result<map_handle> map_handle::map(section_handle &section, size_type bytes, ext
return make_errored_result_nt<map_handle>(ntstat);
}
ret.get()._addr = (char *) addr;
+ ret.get()._offset = offset;
ret.get()._length = _bytes;
// Make my handle borrow the native handle of my backing storage
ret.get()._v.h = section.backing_native_handle().h;
@@ -250,7 +254,6 @@ result<map_handle::buffer_type> map_handle::commit(buffer_type region, section_h
DWORD prot = 0;
if(_flag == section_handle::flag::none)
{
- BOOST_OUTCOME_TRY(_region, do_not_store(region));
DWORD _ = 0;
if(!VirtualProtect(_region.first, _region.second, PAGE_NOACCESS, &_))
return make_errored_result<buffer_type>(GetLastError());
@@ -279,6 +282,17 @@ result<map_handle::buffer_type> map_handle::commit(buffer_type region, section_h
return region;
}
+result<map_handle::buffer_type> map_handle::decommit(buffer_type region) noexcept
+{
+ BOOST_AFIO_LOG_FUNCTION_CALL(_v.h);
+ if(!region.first)
+ return make_errored_result<map_handle::buffer_type>(stl11::errc::invalid_argument);
+ region = utils::round_to_page_size(region);
+ if(!VirtualFree(_region.first, _region.second, MEM_DECOMMIT))
+ return make_errored_result<buffer_type>(GetLastError());
+ return _region;
+}
+
result<void> map_handle::zero(buffer_type region) noexcept
{
BOOST_AFIO_LOG_FUNCTION_CALL(_v.h);
@@ -305,6 +319,7 @@ result<span<map_handle::buffer_type>> map_handle::prefetch(span<buffer_type> reg
result<map_handle::buffer_type> map_handle::do_not_store(buffer_type region) noexcept
{
+ BOOST_AFIO_LOG_FUNCTION_CALL(0);
region = utils::round_to_page_size(region);
if(!region.first)
return make_errored_result<map_handle::buffer_type>(stl11::errc::invalid_argument);
diff --git a/include/boost/afio/v2.0/detail/impl/windows/stat.ipp b/include/boost/afio/v2.0/detail/impl/windows/stat.ipp
index 2e451e6e..141fc15e 100644
--- a/include/boost/afio/v2.0/detail/impl/windows/stat.ipp
+++ b/include/boost/afio/v2.0/detail/impl/windows/stat.ipp
@@ -37,7 +37,7 @@ DEALINGS IN THE SOFTWARE.
BOOST_AFIO_V2_NAMESPACE_BEGIN
-BOOST_AFIO_HEADERS_ONLY_MEMFUNC_SPEC result<size_t> stat_t::fill(handle &h, stat_t::want wanted) noexcept
+BOOST_AFIO_HEADERS_ONLY_MEMFUNC_SPEC result<size_t> stat_t::fill(const handle &h, stat_t::want wanted) noexcept
{
BOOST_AFIO_LOG_FUNCTION_CALL(h.native_handle().h);
windows_nt_kernel::init();
diff --git a/include/boost/afio/v2.0/detail/impl/windows/statfs.ipp b/include/boost/afio/v2.0/detail/impl/windows/statfs.ipp
index 5519a4e1..7de894f0 100644
--- a/include/boost/afio/v2.0/detail/impl/windows/statfs.ipp
+++ b/include/boost/afio/v2.0/detail/impl/windows/statfs.ipp
@@ -35,7 +35,7 @@ DEALINGS IN THE SOFTWARE.
BOOST_AFIO_V2_NAMESPACE_BEGIN
-BOOST_AFIO_HEADERS_ONLY_MEMFUNC_SPEC result<size_t> statfs_t::fill(handle &h, statfs_t::want wanted) noexcept
+BOOST_AFIO_HEADERS_ONLY_MEMFUNC_SPEC result<size_t> statfs_t::fill(const handle &h, statfs_t::want wanted) noexcept
{
BOOST_AFIO_LOG_FUNCTION_CALL(h.native_handle().h);
windows_nt_kernel::init();
diff --git a/include/boost/afio/v2.0/file_handle.hpp b/include/boost/afio/v2.0/file_handle.hpp
index bdc50e07..be1d18a8 100644
--- a/include/boost/afio/v2.0/file_handle.hpp
+++ b/include/boost/afio/v2.0/file_handle.hpp
@@ -98,7 +98,7 @@ protected:
public:
//! Default constructor
- constexpr file_handle()
+ file_handle()
: io_handle()
, _devid(0)
, _inode(0)
diff --git a/include/boost/afio/v2.0/handle.hpp b/include/boost/afio/v2.0/handle.hpp
index 0492f84f..40dbec3b 100644
--- a/include/boost/afio/v2.0/handle.hpp
+++ b/include/boost/afio/v2.0/handle.hpp
@@ -37,6 +37,7 @@ DEALINGS IN THE SOFTWARE.
#include "../boost-lite/include/uint128.hpp"
+#include <algorithm> // for std::count
#include <utility> // for pair<>
//! \file handle.hpp Provides handle
diff --git a/include/boost/afio/v2.0/io_service.hpp b/include/boost/afio/v2.0/io_service.hpp
index e8e11324..cbda69d2 100644
--- a/include/boost/afio/v2.0/io_service.hpp
+++ b/include/boost/afio/v2.0/io_service.hpp
@@ -213,7 +213,7 @@ public:
\note Only present if BOOST_AFIO_IO_POST_SIGNAL is defined.
*/
- static BOOST_AFIO_HEADERS_ONLY_FUNC_SPEC int set_interruption_signal(int sig = BOOST_AFIO_IO_POST_SIGNAL);
+ static BOOST_AFIO_HEADERS_ONLY_MEMFUNC_SPEC int set_interruption_signal(int sig = BOOST_AFIO_IO_POST_SIGNAL);
#endif
#if BOOST_AFIO_USE_POSIX_AIO
diff --git a/include/boost/afio/v2.0/map_handle.hpp b/include/boost/afio/v2.0/map_handle.hpp
index 99f99470..1af93297 100644
--- a/include/boost/afio/v2.0/map_handle.hpp
+++ b/include/boost/afio/v2.0/map_handle.hpp
@@ -129,7 +129,9 @@ public:
//! Returns the memory section's flags
flag section_flags() const noexcept { return _flag; }
- //! Returns the borrowed native handle backing this section, if any
+ //! Returns the borrowed handle backing this section, if any
+ io_handle *backing() const noexcept { return _backing; }
+ //! Returns the borrowed native handle backing this section
native_handle_type backing_native_handle() const noexcept { return _backing ? _backing->native_handle() : native_handle_type(); }
//! Return the current maximum permitted extent of the memory section.
extent_type length() const noexcept { return _length; }
@@ -185,7 +187,7 @@ public:
using path_type = io_handle::path_type;
using extent_type = io_handle::extent_type;
using size_type = io_handle::size_type;
- using flag = io_handle::flag;
+ using mode = io_handle::mode;
using creation = io_handle::creation;
using caching = io_handle::caching;
using flag = io_handle::flag;
@@ -199,6 +201,7 @@ public:
protected:
section_handle *_section;
char *_addr;
+ extent_type _offset;
size_type _length;
public:
@@ -207,6 +210,7 @@ public:
: io_handle()
, _section(nullptr)
, _addr(nullptr)
+ , _offset(0)
, _length(0)
{
}
@@ -215,15 +219,17 @@ public:
: io_handle(std::move(h))
, _section(section)
, _addr(nullptr)
+ , _offset(0)
, _length(0)
{
}
~map_handle();
//! Implicit move construction of map_handle permitted
- map_handle(map_handle &&o) noexcept : io_handle(std::move(o)), _section(o._section), _addr(o._addr), _length(o._length)
+ map_handle(map_handle &&o) noexcept : io_handle(std::move(o)), _section(o._section), _addr(o._addr), _offset(o._offset), _length(o._length)
{
o._section = nullptr;
o._addr = nullptr;
+ o._offset = 0;
o._length = 0;
}
//! Move assignment of map_handle permitted
@@ -264,6 +270,9 @@ public:
//! The address in memory where this mapped view resides
char *address() const noexcept { return _addr; }
+ //! The offset of the memory map.
+ extent_type offset() const noexcept { return _offset; }
+
//! The size of the memory map.
size_type length() const noexcept { return _length; }
@@ -271,7 +280,7 @@ public:
result<buffer_type> commit(buffer_type region, section_handle::flag _flag = section_handle::flag::read | section_handle::flag::write) noexcept;
//! Ask the system to make the memory represented by the buffer unavailable and to decommit the system resources representing them. addr and length should be page aligned (see utils::page_sizes()), if not the returned buffer is the region actually decommitted.
- result<buffer_type> decommit(buffer_type region) noexcept { return commit(region, section_handle::flag::none); }
+ result<buffer_type> decommit(buffer_type region) noexcept;
/*! Zero the memory represented by the buffer. On Linux, Windows and FreeBSD any full 4Kb pages will be deallocated from the system entirely, including the extents for them in any backing storage. On newer Linux kernels the kernel can additionally swap whole 4Kb pages for freshly zeroed ones making this a very
efficient way of zeroing large ranges of memory.
diff --git a/include/boost/afio/v2.0/stat.hpp b/include/boost/afio/v2.0/stat.hpp
index 47ec3bf1..bc36228d 100644
--- a/include/boost/afio/v2.0/stat.hpp
+++ b/include/boost/afio/v2.0/stat.hpp
@@ -149,7 +149,7 @@ struct stat_t
st_size(0), st_allocated(0), st_blocks(0), st_blksize(0), st_flags(0), st_gen(0), st_sparse(0), st_compressed(0), st_reparse_point(0) { }
#ifdef __cpp_exceptions
//! Constructs a filled instance, throwing as an exception any error which might occur
- stat_t(handle &h, want wanted = want::all)
+ stat_t(const handle &h, want wanted = want::all)
: stat_t()
{
auto v(fill(h, wanted));
@@ -158,7 +158,7 @@ struct stat_t
}
#endif
//! Fills in the structure with metadata, returning number of items filled in
- BOOST_AFIO_HEADERS_ONLY_MEMFUNC_SPEC result<size_t> fill(handle &h, want wanted = want::all) noexcept;
+ BOOST_AFIO_HEADERS_ONLY_MEMFUNC_SPEC result<size_t> fill(const handle &h, want wanted = want::all) noexcept;
};
BOOST_AFIO_V2_NAMESPACE_END
diff --git a/include/boost/afio/v2.0/statfs.hpp b/include/boost/afio/v2.0/statfs.hpp
index 9358b032..936e145b 100644
--- a/include/boost/afio/v2.0/statfs.hpp
+++ b/include/boost/afio/v2.0/statfs.hpp
@@ -92,7 +92,7 @@ struct BOOST_AFIO_DECL statfs_t
}
#ifdef __cpp_exceptions
//! Constructs a filled instance, throwing as an exception any error which might occur
- statfs_t(handle &h, want wanted = want::all)
+ statfs_t(const handle &h, want wanted = want::all)
: statfs_t()
{
auto v(fill(h, wanted));
@@ -101,7 +101,7 @@ struct BOOST_AFIO_DECL statfs_t
}
#endif
//! Fills in the structure with metadata, returning number of items filled in
- BOOST_AFIO_HEADERS_ONLY_MEMFUNC_SPEC result<size_t> fill(handle &h, want wanted = want::all) noexcept;
+ BOOST_AFIO_HEADERS_ONLY_MEMFUNC_SPEC result<size_t> fill(const handle &h, want wanted = want::all) noexcept;
};
BOOST_AFIO_V2_NAMESPACE_END