mirror of
https://github.com/matrix-construct/construct
synced 2025-01-16 09:36:54 +01:00
ircd::fs: Further simplify AIO interface.
This commit is contained in:
parent
09e32dce56
commit
9f6eda4c3d
1 changed files with 32 additions and 76 deletions
108
ircd/aio.h
108
ircd/aio.h
|
@ -82,32 +82,28 @@ 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 {ctx::current};
|
||||||
|
|
||||||
/// called if close_fd is true
|
void handle();
|
||||||
void close_fildes() noexcept;
|
|
||||||
|
|
||||||
/// Overriden by types of requests
|
|
||||||
virtual void handle() = 0;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Submit a request. ctx overload will properly yield
|
size_t operator()();
|
||||||
size_t operator()(ctx::ctx &waiter);
|
|
||||||
void operator()();
|
|
||||||
|
|
||||||
void cancel();
|
void cancel();
|
||||||
|
|
||||||
request(const int &fd);
|
request(const int &fd);
|
||||||
virtual ~request() noexcept;
|
~request() noexcept;
|
||||||
};
|
};
|
||||||
|
|
||||||
ircd::fs::aio::request::request(const int &fd)
|
ircd::fs::aio::request::request(const int &fd)
|
||||||
:iocb{0}
|
:iocb{0}
|
||||||
{
|
{
|
||||||
assert(aioctx);
|
assert(aioctx);
|
||||||
|
assert(ctx::current);
|
||||||
|
|
||||||
aio_flags = IOCB_FLAG_RESFD;
|
aio_flags = IOCB_FLAG_RESFD;
|
||||||
aio_resfd = aioctx->resfd.native_handle();
|
aio_resfd = aioctx->resfd.native_handle();
|
||||||
aio_fildes = fd;
|
aio_fildes = fd;
|
||||||
|
aio_data = uintptr_t(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// vtable base
|
/// vtable base
|
||||||
|
@ -130,23 +126,26 @@ ircd::fs::aio::request::cancel()
|
||||||
aioctx->handle_event(result);
|
aioctx->handle_event(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Submit a request and properly yield the ircd::ctx. The ctx argument
|
/// Submit a request and properly yield the ircd::ctx. When this returns the
|
||||||
/// must be the currently running ctx (or ctx::current) for now; there is
|
/// result will be available or an exception will be thrown.
|
||||||
/// no other usage. When this returns the result will be available or
|
|
||||||
/// exception will be thrown.
|
|
||||||
size_t
|
size_t
|
||||||
ircd::fs::aio::request::operator()(ctx::ctx &waiter)
|
ircd::fs::aio::request::operator()()
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Cooperation strategy is to set this->waiter to the ctx and wait for
|
assert(aioctx);
|
||||||
// notification with this->waiter set to null to ignore spurious notes.
|
assert(ctx::current);
|
||||||
assert(&waiter == ctx::current);
|
assert(waiter == ctx::current);
|
||||||
this->waiter = &waiter;
|
|
||||||
operator()(); do
|
struct iocb *const cbs[]
|
||||||
|
{
|
||||||
|
static_cast<iocb *>(this)
|
||||||
|
};
|
||||||
|
|
||||||
|
syscall<SYS_io_submit>(aioctx->idp, 1, &cbs); do
|
||||||
{
|
{
|
||||||
ctx::wait();
|
ctx::wait();
|
||||||
}
|
}
|
||||||
while(this->waiter);
|
while(!retval && !errcode);
|
||||||
|
|
||||||
if(retval == -1)
|
if(retval == -1)
|
||||||
throw_system_error(errcode);
|
throw_system_error(errcode);
|
||||||
|
@ -158,34 +157,22 @@ catch(const ctx::interrupted &e)
|
||||||
// When the ctx is interrupted we're obligated to cancel the request.
|
// When the ctx is interrupted we're obligated to cancel the request.
|
||||||
// The handler callstack is invoked directly from here by cancel() for
|
// The handler callstack is invoked directly from here by cancel() for
|
||||||
// what it's worth but we rethrow the interrupt anyway.
|
// what it's worth but we rethrow the interrupt anyway.
|
||||||
this->waiter = nullptr;
|
|
||||||
cancel();
|
cancel();
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Submit a request.
|
|
||||||
void
|
void
|
||||||
ircd::fs::aio::request::operator()()
|
ircd::fs::aio::request::handle()
|
||||||
{
|
{
|
||||||
struct iocb *const cbs[]
|
assert(this->retval || errcode);
|
||||||
{
|
if(likely(waiter && waiter != ctx::current))
|
||||||
static_cast<iocb *>(this)
|
ircd::ctx::notify(*waiter);
|
||||||
};
|
|
||||||
|
|
||||||
assert(aioctx);
|
|
||||||
syscall<SYS_io_submit>(aioctx->idp, 1, &cbs);
|
|
||||||
/*
|
|
||||||
log::debug("AIO request(%p) fd:%u op:%d bytes:%lu off:%ld prio:%d ctx:%p submit",
|
|
||||||
this,
|
|
||||||
this->aio_fildes,
|
|
||||||
this->aio_lio_opcode,
|
|
||||||
this->aio_nbytes,
|
|
||||||
this->aio_offset,
|
|
||||||
this->aio_reqprio,
|
|
||||||
this->waiter);
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// aio
|
||||||
|
//
|
||||||
|
|
||||||
void
|
void
|
||||||
ircd::fs::aio::set_handle()
|
ircd::fs::aio::set_handle()
|
||||||
{
|
{
|
||||||
|
@ -253,7 +240,7 @@ ircd::fs::aio::handle_event(const io_event &event)
|
||||||
noexcept try
|
noexcept try
|
||||||
{
|
{
|
||||||
// Our extended control block is passed in event.data
|
// Our extended control block is passed in event.data
|
||||||
auto *const request
|
auto *const &request
|
||||||
{
|
{
|
||||||
reinterpret_cast<aio::request *>(event.data)
|
reinterpret_cast<aio::request *>(event.data)
|
||||||
};
|
};
|
||||||
|
@ -282,9 +269,6 @@ noexcept try
|
||||||
request->retval,
|
request->retval,
|
||||||
request->errcode);
|
request->errcode);
|
||||||
*/
|
*/
|
||||||
// virtual dispatch based on the request type. Alternatively, we could
|
|
||||||
// switch() on the iocb lio_opcode and downcast... but that's what vtable
|
|
||||||
// does for us right here.
|
|
||||||
request->handle();
|
request->handle();
|
||||||
}
|
}
|
||||||
catch(const std::exception &e)
|
catch(const std::exception &e)
|
||||||
|
@ -295,21 +279,6 @@ catch(const std::exception &e)
|
||||||
e.what());
|
e.what());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If requested, close the file descriptor. Errors here can be logged but
|
|
||||||
/// must be otherwise ignored.
|
|
||||||
void
|
|
||||||
ircd::fs::aio::request::close_fildes()
|
|
||||||
noexcept try
|
|
||||||
{
|
|
||||||
syscall(::close, aio_fildes);
|
|
||||||
}
|
|
||||||
catch(const std::exception &e)
|
|
||||||
{
|
|
||||||
log::error("Failed to close request(%p) fd:%d: %s",
|
|
||||||
this,
|
|
||||||
aio_fildes);
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// fs/read.h
|
// fs/read.h
|
||||||
|
@ -325,8 +294,6 @@ namespace ircd::fs
|
||||||
struct ircd::fs::aio::request::read
|
struct ircd::fs::aio::request::read
|
||||||
:request
|
:request
|
||||||
{
|
{
|
||||||
virtual void handle() final override;
|
|
||||||
|
|
||||||
read(const int &fd, const mutable_raw_buffer &buf, const read_opts &opts);
|
read(const int &fd, const mutable_raw_buffer &buf, const read_opts &opts);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -335,7 +302,6 @@ ircd::fs::aio::request::read::read(const int &fd,
|
||||||
const read_opts &opts)
|
const read_opts &opts)
|
||||||
:request{fd}
|
:request{fd}
|
||||||
{
|
{
|
||||||
aio_data = uintptr_t(this);
|
|
||||||
aio_reqprio = opts.priority;
|
aio_reqprio = opts.priority;
|
||||||
aio_lio_opcode = IOCB_CMD_PREAD;
|
aio_lio_opcode = IOCB_CMD_PREAD;
|
||||||
|
|
||||||
|
@ -344,16 +310,6 @@ ircd::fs::aio::request::read::read(const int &fd,
|
||||||
aio_offset = opts.offset;
|
aio_offset = opts.offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
ircd::fs::aio::request::read::handle()
|
|
||||||
{
|
|
||||||
if(!waiter)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ircd::ctx::notify(*waiter);
|
|
||||||
waiter = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Interface
|
// Interface
|
||||||
//
|
//
|
||||||
|
@ -396,7 +352,7 @@ ircd::fs::read__aio(const string_view &path,
|
||||||
|
|
||||||
const size_t bytes
|
const size_t bytes
|
||||||
{
|
{
|
||||||
request(ctx::cur())
|
request()
|
||||||
};
|
};
|
||||||
|
|
||||||
ret.resize(bytes);
|
ret.resize(bytes);
|
||||||
|
@ -429,7 +385,7 @@ ircd::fs::read__aio(const string_view &path,
|
||||||
|
|
||||||
const size_t bytes
|
const size_t bytes
|
||||||
{
|
{
|
||||||
request(ctx::cur())
|
request()
|
||||||
};
|
};
|
||||||
|
|
||||||
const string_view view
|
const string_view view
|
||||||
|
|
Loading…
Reference in a new issue