diff --git a/ircd/aio.h b/ircd/aio.h index f7806d6f0..6b5c15dea 100644 --- a/ircd/aio.h +++ b/ircd/aio.h @@ -82,32 +82,28 @@ struct ircd::fs::aio::request ssize_t retval {0}; ssize_t errcode {0}; - ctx::ctx *waiter {nullptr}; + ctx::ctx *waiter {ctx::current}; - /// called if close_fd is true - void close_fildes() noexcept; - - /// Overriden by types of requests - virtual void handle() = 0; + void handle(); public: - // Submit a request. ctx overload will properly yield - size_t operator()(ctx::ctx &waiter); - void operator()(); - + size_t operator()(); void cancel(); request(const int &fd); - virtual ~request() noexcept; + ~request() noexcept; }; ircd::fs::aio::request::request(const int &fd) :iocb{0} { assert(aioctx); + assert(ctx::current); + aio_flags = IOCB_FLAG_RESFD; aio_resfd = aioctx->resfd.native_handle(); aio_fildes = fd; + aio_data = uintptr_t(this); } /// vtable base @@ -130,23 +126,26 @@ ircd::fs::aio::request::cancel() aioctx->handle_event(result); } -/// Submit a request and properly yield the ircd::ctx. The ctx argument -/// must be the currently running ctx (or ctx::current) for now; there is -/// no other usage. When this returns the result will be available or -/// exception will be thrown. +/// Submit a request and properly yield the ircd::ctx. When this returns the +/// result will be available or an exception will be thrown. size_t -ircd::fs::aio::request::operator()(ctx::ctx &waiter) +ircd::fs::aio::request::operator()() try { - // Cooperation strategy is to set this->waiter to the ctx and wait for - // notification with this->waiter set to null to ignore spurious notes. - assert(&waiter == ctx::current); - this->waiter = &waiter; - operator()(); do + assert(aioctx); + assert(ctx::current); + assert(waiter == ctx::current); + + struct iocb *const cbs[] + { + static_cast(this) + }; + + syscall(aioctx->idp, 1, &cbs); do { ctx::wait(); } - while(this->waiter); + while(!retval && !errcode); if(retval == -1) 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. // The handler callstack is invoked directly from here by cancel() for // what it's worth but we rethrow the interrupt anyway. - this->waiter = nullptr; cancel(); throw; } -/// Submit a request. void -ircd::fs::aio::request::operator()() +ircd::fs::aio::request::handle() { - struct iocb *const cbs[] - { - static_cast(this) - }; - - assert(aioctx); - syscall(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); -*/ + assert(this->retval || errcode); + if(likely(waiter && waiter != ctx::current)) + ircd::ctx::notify(*waiter); } +// +// aio +// + void ircd::fs::aio::set_handle() { @@ -253,7 +240,7 @@ ircd::fs::aio::handle_event(const io_event &event) noexcept try { // Our extended control block is passed in event.data - auto *const request + auto *const &request { reinterpret_cast(event.data) }; @@ -282,9 +269,6 @@ noexcept try request->retval, 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(); } catch(const std::exception &e) @@ -295,21 +279,6 @@ catch(const std::exception &e) 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 @@ -325,8 +294,6 @@ namespace ircd::fs struct ircd::fs::aio::request::read :request { - virtual void handle() final override; - 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) :request{fd} { - aio_data = uintptr_t(this); aio_reqprio = opts.priority; aio_lio_opcode = IOCB_CMD_PREAD; @@ -344,16 +310,6 @@ ircd::fs::aio::request::read::read(const int &fd, aio_offset = opts.offset; } -void -ircd::fs::aio::request::read::handle() -{ - if(!waiter) - return; - - ircd::ctx::notify(*waiter); - waiter = nullptr; -} - // // Interface // @@ -396,7 +352,7 @@ ircd::fs::read__aio(const string_view &path, const size_t bytes { - request(ctx::cur()) + request() }; ret.resize(bytes); @@ -429,7 +385,7 @@ ircd::fs::read__aio(const string_view &path, const size_t bytes { - request(ctx::cur()) + request() }; const string_view view