Implement fs::file::write_gather (Vectored I/O)

This commit is contained in:
Nekotekina 2019-06-03 22:57:59 +03:00
parent 31994dd3b2
commit 447029a700
3 changed files with 64 additions and 6 deletions

View file

@ -125,6 +125,7 @@ static fs::error to_error(DWORD e)
#include <sys/types.h>
#include <sys/statvfs.h>
#include <sys/file.h>
#include <sys/uio.h>
#include <dirent.h>
#include <fcntl.h>
#include <libgen.h>
@ -203,6 +204,34 @@ namespace fs
#endif
}
u64 file_base::write_gather(const iovec_clone* buffers, u64 buf_count)
{
u64 total = 0;
for (u64 i = 0; i < buf_count; i++)
{
if (!buffers[i].iov_base || buffers[i].iov_len + total < total)
{
g_tls_error = error::inval;
return -1;
}
total += buffers[i].iov_len;
}
const auto buf = std::make_unique<uchar>(total);
u64 copied = 0;
for (u64 i = 0; i < buf_count; i++)
{
std::memcpy(buf.get() + copied, buffers[i].iov_base, buffers[i].iov_len);
copied += buffers[i].iov_len;
}
return this->write(buf.get(), total);
}
dir_base::~dir_base()
{
}
@ -1157,6 +1186,17 @@ fs::file::file(const std::string& path, bs_t<open_mode> mode)
{
return m_fd;
}
u64 write_gather(const iovec_clone* buffers, u64 buf_count) override
{
static_assert(sizeof(iovec) == sizeof(iovec_clone), "Weird iovec size");
static_assert(offsetof(iovec, iov_len) == offsetof(iovec_clone, iov_len), "Weird iovec::iov_len offset");
const auto result = ::writev(m_fd, (const iovec*)buffers, buf_count);
verify("file::write_gather" HERE), result != -1;
return result;
}
};
m_file = std::make_unique<unix_file>(fd);