mirror of
https://github.com/matrix-construct/construct
synced 2024-12-28 16:34:13 +01:00
ircd::fs: Simplify API/AIO by eliminating callback: ctx yield only for now.
This commit is contained in:
parent
a8efc59adf
commit
6b7399bf4a
3 changed files with 10 additions and 141 deletions
|
@ -23,11 +23,6 @@
|
||||||
namespace ircd::fs
|
namespace ircd::fs
|
||||||
{
|
{
|
||||||
struct read_opts extern const read_opts_default;
|
struct read_opts extern const read_opts_default;
|
||||||
using read_callback = std::function<void (std::exception_ptr, const string_view &)>;
|
|
||||||
|
|
||||||
// Asynchronous callback-based read into buffer; callback views read portion.
|
|
||||||
void read(const string_view &path, const mutable_raw_buffer &, const read_opts &, read_callback);
|
|
||||||
void read(const string_view &path, const mutable_raw_buffer &, read_callback);
|
|
||||||
|
|
||||||
// Yields ircd::ctx for read into buffer; returns view of read portion.
|
// Yields ircd::ctx for read into buffer; returns view of read portion.
|
||||||
string_view read(const string_view &path, const mutable_raw_buffer &, const read_opts & = read_opts_default);
|
string_view read(const string_view &path, const mutable_raw_buffer &, const read_opts & = read_opts_default);
|
||||||
|
@ -53,11 +48,3 @@ inline
|
||||||
ircd::fs::read_opts::read_opts(const off_t &offset)
|
ircd::fs::read_opts::read_opts(const off_t &offset)
|
||||||
:offset{offset}
|
:offset{offset}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
inline void
|
|
||||||
ircd::fs::read(const string_view &path,
|
|
||||||
const mutable_raw_buffer &buf,
|
|
||||||
read_callback callback)
|
|
||||||
{
|
|
||||||
return read(path, buf, read_opts_default, std::move(callback));
|
|
||||||
}
|
|
||||||
|
|
93
ircd/aio.h
93
ircd/aio.h
|
@ -52,16 +52,12 @@ struct ircd::fs::aio
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Handler to the io context we submit requests to the kernel with
|
/// Handler to the io context we submit requests to the kernel with
|
||||||
aio_context_t idp
|
aio_context_t idp{0};
|
||||||
{
|
|
||||||
0
|
|
||||||
};
|
|
||||||
|
|
||||||
// Callback stack invoked when the sigfd is notified of completed events.
|
// Callback stack invoked when the sigfd is notified of completed events.
|
||||||
void handle_event(const io_event &) noexcept;
|
void handle_event(const io_event &) noexcept;
|
||||||
void handle_events() noexcept;
|
void handle_events() noexcept;
|
||||||
void handle(const error_code &, const size_t) noexcept;
|
void handle(const error_code &, const size_t) noexcept;
|
||||||
|
|
||||||
void set_handle();
|
void set_handle();
|
||||||
|
|
||||||
aio()
|
aio()
|
||||||
|
@ -87,8 +83,6 @@ struct ircd::fs::aio::request
|
||||||
ssize_t retval {0};
|
ssize_t retval {0};
|
||||||
ssize_t errcode {0};
|
ssize_t errcode {0};
|
||||||
ctx::ctx *waiter {nullptr};
|
ctx::ctx *waiter {nullptr};
|
||||||
bool close_fd {false};
|
|
||||||
bool free_req {false};
|
|
||||||
|
|
||||||
/// called if close_fd is true
|
/// called if close_fd is true
|
||||||
void close_fildes() noexcept;
|
void close_fildes() noexcept;
|
||||||
|
@ -288,18 +282,6 @@ noexcept try
|
||||||
request->retval,
|
request->retval,
|
||||||
request->errcode);
|
request->errcode);
|
||||||
*/
|
*/
|
||||||
const unwind cleanup{[&request]
|
|
||||||
{
|
|
||||||
// The user might want us to cleanup their fd after this event
|
|
||||||
if(request->close_fd)
|
|
||||||
request->close_fildes();
|
|
||||||
|
|
||||||
// The user might want us to free a dynamically allocated request struct
|
|
||||||
// to simplify their callback sequence. The noexcept guarantees h
|
|
||||||
if(request->free_req)
|
|
||||||
delete request;
|
|
||||||
}};
|
|
||||||
|
|
||||||
// virtual dispatch based on the request type. Alternatively, we could
|
// virtual dispatch based on the request type. Alternatively, we could
|
||||||
// switch() on the iocb lio_opcode and downcast... but that's what vtable
|
// switch() on the iocb lio_opcode and downcast... but that's what vtable
|
||||||
// does for us right here.
|
// does for us right here.
|
||||||
|
@ -335,7 +317,6 @@ catch(const std::exception &e)
|
||||||
|
|
||||||
namespace ircd::fs
|
namespace ircd::fs
|
||||||
{
|
{
|
||||||
void read__aio(const string_view &path, const mutable_raw_buffer &, const read_opts &, read_callback);
|
|
||||||
string_view read__aio(const string_view &path, const mutable_raw_buffer &, const read_opts &);
|
string_view read__aio(const string_view &path, const mutable_raw_buffer &, const read_opts &);
|
||||||
std::string read__aio(const string_view &path, const read_opts &);
|
std::string read__aio(const string_view &path, const read_opts &);
|
||||||
}
|
}
|
||||||
|
@ -344,19 +325,15 @@ namespace ircd::fs
|
||||||
struct ircd::fs::aio::request::read
|
struct ircd::fs::aio::request::read
|
||||||
:request
|
:request
|
||||||
{
|
{
|
||||||
read_callback callback;
|
|
||||||
|
|
||||||
virtual void handle() final override;
|
virtual void handle() final override;
|
||||||
|
|
||||||
read(const int &fd, const mutable_raw_buffer &buf, const read_opts &opts, read_callback callback);
|
read(const int &fd, const mutable_raw_buffer &buf, const read_opts &opts);
|
||||||
};
|
};
|
||||||
|
|
||||||
ircd::fs::aio::request::read::read(const int &fd,
|
ircd::fs::aio::request::read::read(const int &fd,
|
||||||
const mutable_raw_buffer &buf,
|
const mutable_raw_buffer &buf,
|
||||||
const read_opts &opts,
|
const read_opts &opts)
|
||||||
read_callback callback)
|
|
||||||
:request{fd}
|
:request{fd}
|
||||||
,callback{std::move(callback)}
|
|
||||||
{
|
{
|
||||||
aio_data = uintptr_t(this);
|
aio_data = uintptr_t(this);
|
||||||
aio_reqprio = opts.priority;
|
aio_reqprio = opts.priority;
|
||||||
|
@ -370,31 +347,11 @@ ircd::fs::aio::request::read::read(const int &fd,
|
||||||
void
|
void
|
||||||
ircd::fs::aio::request::read::handle()
|
ircd::fs::aio::request::read::handle()
|
||||||
{
|
{
|
||||||
if(waiter)
|
if(!waiter)
|
||||||
{
|
return;
|
||||||
ircd::ctx::notify(*waiter);
|
|
||||||
waiter = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(callback)
|
ircd::ctx::notify(*waiter);
|
||||||
{
|
waiter = nullptr;
|
||||||
const size_t bytes
|
|
||||||
{
|
|
||||||
retval >= 0? size_t(retval) : 0
|
|
||||||
};
|
|
||||||
|
|
||||||
const string_view view
|
|
||||||
{
|
|
||||||
reinterpret_cast<const char *>(aio_buf), bytes
|
|
||||||
};
|
|
||||||
|
|
||||||
std::exception_ptr eptr
|
|
||||||
{
|
|
||||||
errcode != 0? make_system_error(errcode) : std::exception_ptr{}
|
|
||||||
};
|
|
||||||
|
|
||||||
callback(std::move(eptr), view);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -419,8 +376,6 @@ ircd::fs::read__aio(const string_view &path,
|
||||||
syscall(::close, fd);
|
syscall(::close, fd);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
// This fstat may be defeating; to be sure, don't use this overload
|
|
||||||
// and progressively buffer chunks into your application.
|
|
||||||
struct stat stat;
|
struct stat stat;
|
||||||
syscall(::fstat, fd, &stat);
|
syscall(::fstat, fd, &stat);
|
||||||
const auto &size
|
const auto &size
|
||||||
|
@ -436,7 +391,7 @@ ircd::fs::read__aio(const string_view &path,
|
||||||
|
|
||||||
aio::request::read request
|
aio::request::read request
|
||||||
{
|
{
|
||||||
int(fd), buf, opts, nullptr
|
int(fd), buf, opts
|
||||||
};
|
};
|
||||||
|
|
||||||
const size_t bytes
|
const size_t bytes
|
||||||
|
@ -469,7 +424,7 @@ ircd::fs::read__aio(const string_view &path,
|
||||||
|
|
||||||
aio::request::read request
|
aio::request::read request
|
||||||
{
|
{
|
||||||
int(fd), buf, opts, nullptr
|
int(fd), buf, opts
|
||||||
};
|
};
|
||||||
|
|
||||||
const size_t bytes
|
const size_t bytes
|
||||||
|
@ -484,33 +439,3 @@ ircd::fs::read__aio(const string_view &path,
|
||||||
|
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
ircd::fs::read__aio(const string_view &path,
|
|
||||||
const mutable_raw_buffer &buf,
|
|
||||||
const read_opts &opts,
|
|
||||||
read_callback callback)
|
|
||||||
{
|
|
||||||
static thread_local char pathstr[2048];
|
|
||||||
strlcpy(pathstr, path, sizeof(pathstr));
|
|
||||||
|
|
||||||
const auto fd
|
|
||||||
{
|
|
||||||
syscall(::open, pathstr, O_CLOEXEC, O_RDONLY)
|
|
||||||
};
|
|
||||||
|
|
||||||
const unwind::exceptional cfd{[&fd]
|
|
||||||
{
|
|
||||||
syscall(::close, fd);
|
|
||||||
}};
|
|
||||||
|
|
||||||
auto request
|
|
||||||
{
|
|
||||||
std::make_unique<aio::request::read>(int(fd), buf, opts, std::move(callback))
|
|
||||||
};
|
|
||||||
|
|
||||||
request->close_fd = true;
|
|
||||||
request->free_req = true;
|
|
||||||
(*request)();
|
|
||||||
request.release();
|
|
||||||
}
|
|
||||||
|
|
45
ircd/fs.cc
45
ircd/fs.cc
|
@ -78,7 +78,6 @@ noexcept
|
||||||
|
|
||||||
namespace ircd::fs
|
namespace ircd::fs
|
||||||
{
|
{
|
||||||
void read__std(const string_view &path, const mutable_raw_buffer &, const read_opts &, read_callback);
|
|
||||||
string_view read__std(const string_view &path, const mutable_raw_buffer &, const read_opts &);
|
string_view read__std(const string_view &path, const mutable_raw_buffer &, const read_opts &);
|
||||||
std::string read__std(const string_view &path, const read_opts &);
|
std::string read__std(const string_view &path, const read_opts &);
|
||||||
}
|
}
|
||||||
|
@ -116,20 +115,6 @@ ircd::fs::read(const string_view &path,
|
||||||
return read__std(path, buf, opts);
|
return read__std(path, buf, opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
ircd::fs::read(const string_view &path,
|
|
||||||
const mutable_raw_buffer &buf,
|
|
||||||
const read_opts &opts,
|
|
||||||
read_callback callback)
|
|
||||||
{
|
|
||||||
#ifdef IRCD_USE_AIO
|
|
||||||
if(likely(aioctx))
|
|
||||||
return read__aio(path, buf, opts, std::move(callback));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return read__std(path, buf, opts, std::move(callback));
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// std read
|
// std read
|
||||||
//
|
//
|
||||||
|
@ -149,43 +134,15 @@ ircd::string_view
|
||||||
ircd::fs::read__std(const string_view &path,
|
ircd::fs::read__std(const string_view &path,
|
||||||
const mutable_raw_buffer &buf,
|
const mutable_raw_buffer &buf,
|
||||||
const read_opts &opts)
|
const read_opts &opts)
|
||||||
{
|
|
||||||
string_view ret;
|
|
||||||
std::exception_ptr reptr;
|
|
||||||
read(path, buf, opts, [&reptr, &ret]
|
|
||||||
(std::exception_ptr eptr, const string_view &view)
|
|
||||||
{
|
|
||||||
reptr = std::move(eptr);
|
|
||||||
ret = view;
|
|
||||||
});
|
|
||||||
|
|
||||||
if(reptr)
|
|
||||||
std::rethrow_exception(reptr);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ircd::fs::read__std(const string_view &path,
|
|
||||||
const mutable_raw_buffer &buf,
|
|
||||||
const read_opts &opts,
|
|
||||||
read_callback callback)
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
std::ifstream file{std::string{path}};
|
std::ifstream file{std::string{path}};
|
||||||
file.exceptions(file.failbit | file.badbit);
|
file.exceptions(file.failbit | file.badbit);
|
||||||
file.seekg(opts.offset, file.beg);
|
file.seekg(opts.offset, file.beg);
|
||||||
file.read(reinterpret_cast<char *>(data(buf)), size(buf));
|
file.read(reinterpret_cast<char *>(data(buf)), size(buf));
|
||||||
const string_view view
|
return
|
||||||
{
|
{
|
||||||
reinterpret_cast<const char *>(data(buf)), size_t(file.gcount())
|
reinterpret_cast<const char *>(data(buf)), size_t(file.gcount())
|
||||||
};
|
};
|
||||||
|
|
||||||
callback(std::exception_ptr{}, view);
|
|
||||||
}
|
|
||||||
catch(...)
|
|
||||||
{
|
|
||||||
callback(std::make_exception_ptr(std::current_exception()), string_view{});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue