summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/util/ioprocsfill.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/util/ioprocsfill.h')
-rw-r--r--src/lib/util/ioprocsfill.h65
1 files changed, 46 insertions, 19 deletions
diff --git a/src/lib/util/ioprocsfill.h b/src/lib/util/ioprocsfill.h
index e49b10687f0..7179d61852c 100644
--- a/src/lib/util/ioprocsfill.h
+++ b/src/lib/util/ioprocsfill.h
@@ -45,9 +45,21 @@ class read_stream_fill_wrapper : public Base, public virtual fill_wrapper_base<D
public:
using Base::Base;
- virtual std::error_condition read(void *buffer, std::size_t length, std::size_t &actual) noexcept override
+ virtual std::error_condition read_some(void *buffer, std::size_t length, std::size_t &actual) noexcept override
{
- std::error_condition err = Base::read(buffer, length, actual);
+ // not atomic with respect to other read/write calls
+ actual = 0U;
+ std::error_condition err;
+ std::size_t chunk;
+ do
+ {
+ err = Base::read_some(
+ reinterpret_cast<std::uint8_t *>(buffer) + actual,
+ length - actual,
+ chunk);
+ actual += chunk;
+ }
+ while ((length > actual) && ((!err && chunk) || (std::errc::interrupted == err)));
assert(length >= actual);
std::fill(
reinterpret_cast<std::uint8_t *>(buffer) + actual,
@@ -64,9 +76,23 @@ class random_read_fill_wrapper : public read_stream_fill_wrapper<Base, DefaultFi
public:
using read_stream_fill_wrapper<Base, DefaultFiller>::read_stream_fill_wrapper;
- virtual std::error_condition read_at(std::uint64_t offset, void *buffer, std::size_t length, std::size_t &actual) noexcept override
+ virtual std::error_condition read_some_at(std::uint64_t offset, void *buffer, std::size_t length, std::size_t &actual) noexcept override
{
- std::error_condition err = Base::read_at(offset, buffer, length, actual);
+ // not atomic with respect to other read/write calls
+ actual = 0U;
+ std::error_condition err;
+ std::size_t chunk;
+ do
+ {
+ err = Base::read_some_at(
+ offset,
+ reinterpret_cast<std::uint8_t *>(buffer) + actual,
+ length - actual,
+ chunk);
+ offset += chunk;
+ actual += chunk;
+ }
+ while ((length > actual) && ((!err && chunk) || (std::errc::interrupted == err)));
assert(length >= actual);
std::fill(
reinterpret_cast<std::uint8_t *>(buffer) + actual,
@@ -83,8 +109,9 @@ class random_write_fill_wrapper : public Base, public virtual fill_wrapper_base<
public:
using Base::Base;
- virtual std::error_condition write(void const *buffer, std::size_t length, std::size_t &actual) noexcept override
+ virtual std::error_condition write_some(void const *buffer, std::size_t length, std::size_t &actual) noexcept override
{
+ // not atomic with respect to other read/write calls
std::error_condition err;
actual = 0U;
@@ -108,23 +135,22 @@ public:
do
{
std::size_t const chunk = std::min<std::common_type_t<std::size_t, std::uint64_t> >(FillBlock, unfilled);
- err = Base::write_at(current, fill_buffer, chunk, actual);
- if (err)
- {
- actual = 0U;
+ std::size_t filled;
+ err = Base::write_some_at(current, fill_buffer, chunk, filled);
+ current += filled;
+ unfilled -= filled;
+ if (err && (std::errc::interrupted != err))
return err;
- }
- current += chunk;
- unfilled -= chunk;
}
while (unfilled);
}
- return Base::write(buffer, length, actual);
+ return Base::write_some(buffer, length, actual);
}
- virtual std::error_condition write_at(std::uint64_t offset, void const *buffer, std::size_t length, std::size_t &actual) noexcept override
+ virtual std::error_condition write_some_at(std::uint64_t offset, void const *buffer, std::size_t length, std::size_t &actual) noexcept override
{
+ // not atomic with respect to other read/write calls
std::error_condition err;
std::uint64_t current;
err = Base::length(current);
@@ -139,18 +165,19 @@ public:
do
{
std::size_t const chunk = std::min<std::common_type_t<std::size_t, std::uint64_t> >(FillBlock, unfilled);
- err = Base::write_at(current, fill_buffer, chunk, actual);
- current += chunk;
- unfilled -= chunk;
+ std::size_t filled;
+ err = Base::write_some_at(current, fill_buffer, chunk, filled);
+ current += filled;
+ unfilled -= filled;
}
- while (unfilled && !err);
+ while (unfilled && (!err || (std::errc::interrupted == err)));
}
if (err)
{
actual = 0U;
return err;
}
- return Base::write_at(offset, buffer, length, actual);
+ return Base::write_some_at(offset, buffer, length, actual);
}
};