event_loop
AB is powered by liburing which is a userspace wrapper for io_uring An event_loop
loop exists for every engine
thread in ZAB. This thread loops on the completion queue waiting for completed io requests then fowarding the results to and resuming the respective coroutines. User space events (those submitted by engine::resume
and family) are submitted to the event_loop
via an event_fd. User code should only do short computations or yield
long running computation in the event_loop
to ensure IO completions are reported back in a timely manner.
In this release the following io_uring calls are supported in ZAB:
As in liburing
options can be attempted to be canclled. Each io_uring call has two overloads:
1. A simple future that has a io_handle
out value which will be set to the cancellation handle on suspension.
2. A void function that expects a io_handle
prefilled with the suspended coroutines handle. In either case, the value can be passed to cancel_event
to attempt a cancle.
A io_handle
is an alias to a pause_pack*
which can be obtained through the zab::pause(...)
function.
-
class zab::event_loop
This class implements a coroutine wrapper for the liburing service.
Investigate IORING_SETUP_ATTACH_WQ
Public Types
-
enum class CancelResult
Describes the result of a cancel operation.
Values:
-
enumerator kDone
The cancel was complete.
-
enumerator kNotFound
Could not find an operation with that io_event*.
-
enumerator kTried
We tried, but the operation could not be canceled.
-
enumerator kFailed
We could not create the cancel request dues to an error.
-
enumerator kUnknown
Something exception and unknown happened.
-
enumerator kDone
-
using io_event = storage_event<int>
-
using user_event = tagged_event
Public Functions
-
event_loop()
Constructs a new event_loop. Is unusable until initialise is called.
-
void initialise() noexcept
Initialises the event_loop.
-
void initialise(int _io_fd) noexcept
Initialises the event_loop that shares a worker pool with _io_fd.
- Parameters
_io_fd – The io_ring to share a worker pool with.
-
~event_loop()
Destroys the object and cleans up the resources.
-
inline auto open_at(int _dfd, const std::string_view _path, int _flags, mode_t _mode, cancelation_token *_cancel_token = nullptr) noexcept
Open a file relative to a directory file descriptor.
See https://linux.die.net/man/2/openat.
@co_return The result of
::openat()
- Parameters
_dfd – The directory descriptor or AT_FDCWD
_path – The path to the file relative to _dfd.
_flags – Flags used to open the file.
_mode – Permissions to use for the file
_cancel_token – [out] A ptr to a io_event* which will bet set to the cancelation handle.
-
void open_at(io_event *_cancel_token, int _dfd, const std::string_view _path, int _flags, mode_t _mode) noexcept
Open a file relative to a directory file descriptor.
cancel_token->data will hold the return code of the op.
See https://linux.die.net/man/2/openat.
- Parameters
_cancel_token – A io_event* which will be resumed on completion.
_dfd – The directory descriptor or AT_FDCWD
_path – The path to the file relative to _dfd.
_flags – Flags used to open the file.
_mode – Permissions to use for the file
-
inline auto close(int _fd, cancelation_token *_cancel_token = nullptr) noexcept
Close a file descriptor.
See https://man7.org/linux/man-pages/man2/close.2.html.
@co_return The result of
::close()
- Parameters
_fd – The file descriptor to close.
_cancel_token – [out] A ptr to a io_event* which will bet set to the cancelation handle.
-
void close(io_event *_cancel_token, int _fd) noexcept
Close a file descriptor.
cancel_token->data will hold the return code of the op.
See https://man7.org/linux/man-pages/man2/close.2.html.
- Parameters
_cancel_token – A io_event* which will be resumed on completion.
_fd – The file descriptor to close.
-
inline auto read(int _fd, std::span<std::byte> _buffer, off_t _offset, cancelation_token *_cancel_token = nullptr) noexcept
Read from a file descriptor.
See https://man7.org/linux/man-pages/man2/read.2.html.
@co_return The result of
::read()
- Parameters
_fd – The file to read from.
_buffer – The buffer to read into.
_offset – The offset of the buffer to start from.
_cancel_token – [out] A ptr to a io_event* which will bet set to the cancelation handle.
-
void read(io_event *_cancel_token, int _fd, std::span<std::byte> _buffer, off_t _offset) noexcept
Read from a file descriptor.
cancel_token->data will hold the return code of the op.
See https://man7.org/linux/man-pages/man2/read.2.html.
- Parameters
_cancel_token – A io_event* which will be resumed on completion.
_fd – The file to read from.
_buffer – The buffer to read into.
_offset – The offset of the buffer to start from.
-
inline auto fixed_read(int _fd, std::span<std::byte> _buffer, off_t _offset, int _buf_index, cancelation_token *_cancel_token = nullptr) noexcept
Read from a file descriptor using a fixed buffer.
See https://man7.org/linux/man-pages/man2/read.2.html.
@co_return The result of the
fixed_read()
operation.- Parameters
_fd – The file to read from.
_buffer – The buffer to read into.
_offset – The offset of the buffer to start from.
_buf_index – The index of the fixed buffer.
_cancel_token – [out] A ptr to a io_event* which will bet set to the cancelation handle.
-
void fixed_read(io_event *_cancel_token, int _fd, std::span<std::byte> _buffer, off_t _offset, int _buf_index) noexcept
Read from a file descriptor using a fixed buffer.
cancel_token->data will hold the return code of the op.
See https://man7.org/linux/man-pages/man2/read.2.html.
- Parameters
_cancel_token – A io_event* which will be resumed on completion.
_fd – The file to read from.
_buffer – The buffer to read into.
_offset – The offset of the buffer to start from.
_buf_index – The index of the fixed buffer.
-
inline auto read_v(int _fd, const struct iovec *_iovecs, unsigned _nr_vecs, off_t _offset, cancelation_token *_cancel_token = nullptr) noexcept
Read from a file descriptor into multiple buffers.
See https://man7.org/linux/man-pages/man2/readv.2.html
@co_return The result of the
::readv()
operation.- Parameters
_fd – The file to read from.
_iovecs – The _iovecs array.
_nr_vecs – The size of the _iovecs.
_offset – The offset of the buffer to start from.
_cancel_token – [out] A ptr to a io_event* which will bet set to the cancelation handle.
-
void read_v(io_event *_cancel_token, int _fd, const struct iovec *_iovecs, unsigned _nr_vecs, off_t _offset) noexcept
Read from a file descriptor into multiple buffers.
cancel_token->data will hold the return code of the op.
See https://man7.org/linux/man-pages/man2/readv.2.html
- Parameters
_cancel_token – A io_event* which will be resumed on completion.
_fd – The file to read from.
_iovecs – The _iovecs array.
_nr_vecs – The size of the _iovecs.
_offset – The offset of the buffer to start from.
-
inline auto write(int _fd, std::span<const std::byte> _buffer, off_t _offset, cancelation_token *_cancel_token = nullptr) noexcept
Write to a file descriptor.
See https://man7.org/linux/man-pages/man2/write.2.html.
@co_return The result of the
::write()
operation.- Parameters
_fd – The file descriptor to write to.
_buffer – The buffer to write from.
_offset – The offest from where to start writing.
_cancel_token – [out] A ptr to a io_event* which will bet set to the cancelation handle.
-
void write(io_event *_cancel_token, int _fd, std::span<const std::byte> _buffer, off_t _offset) noexcept
Write to a file descriptor.
cancel_token->data will hold the return code of the op.
See https://man7.org/linux/man-pages/man2/write.2.html
- Parameters
_cancel_token – A io_event* which will be resumed on completion.
_fd – The file descriptor to write to.
_buffer – The buffer to write from.
_offset – The offest from where to start writing.
-
inline auto fixed_write(int _fd, std::span<const std::byte> _buffer, off_t _offset, int _buf_index, cancelation_token *_cancel_token = nullptr) noexcept
Write from a fixed buffer into a file descriptor.
See https://man7.org/linux/man-pages/man2/write.2.html;
@co_return The result of the
fixed_write()
operation.- Parameters
_fd – The file descriptor.
_buffer – The buffer to write from.
_offset – The offset of the buffer.
_buf_index – The pinned buffer index.
_cancel_token – [out] A ptr to a io_event* which will bet set to the cancelation handle.
-
void fixed_write(io_event *_cancel_token, int _fd, std::span<const std::byte> _buffer, off_t _offset, int _buf_index) noexcept
Write from a fixed buffer into a file descriptor.
cancel_token->data will hold the return code of the op.
See https://man7.org/linux/man-pages/man2/write.2.html
- Parameters
_cancel_token – A io_event* which will be resumed on completion.
_fd – The file descriptor.
_buffer – The buffer to write from.
_offset – The offset of the buffer.
_buf_index – The pinned buffer index.
-
inline auto write_v(int _fd, const struct iovec *_iovecs, unsigned _nr_vecs, off_t _offset, cancelation_token *_cancel_token = nullptr) noexcept
Write data from multiple buffers.
See: https://man7.org/linux/man-pages/man2/writev.2.html.
@co_return The result of the
::writev()
operation.- Parameters
_fd – The file descriptor.
_iovecs – The iovec structure array.
_nr_vecs – The size of the iovec array.
_offset – The offest from where to start writing.
_cancel_token – [out] A ptr to a io_event* which will bet set to the cancelation handle.
-
void write_v(io_event *_cancel_token, int _fd, const struct iovec *_iovecs, unsigned _nr_vecs, off_t _offset) noexcept
Write data from multiple buffers.
cancel_token->data will hold the return code of the op.
See https://man7.org/linux/man-pages/man2/writev.2.html
- Parameters
_cancel_token – A io_event* which will be resumed on completion.
_fd – The file descriptor.
_iovecs – The iovec structure array.
_nr_vecs – The size of the iovec array.
_offset – The offest from where to start writing.
-
inline auto recv(int _sockfd, std::span<std::byte> _buffer, int _flags, cancelation_token *_cancel_token = nullptr) noexcept
Receive a message from a socket.
See https://man7.org/linux/man-pages/man2/recv.2.html.
@co_return The result of the
::recv()
operation.- Parameters
_sockfd – The socket descriptor.
_buffer – The buffer to receive into.
_flags – The flags to apply to the read operation.
_cancel_token – [out] A ptr to a io_event* which will bet set to the cancelation handle.
-
void recv(io_event *_cancel_token, int _sockfd, std::span<std::byte> _buffer, int _flags) noexcept
Receive a message from a socket.
cancel_token->data will hold the return code of the op.
See https://man7.org/linux/man-pages/man2/recv.2.html.
- Parameters
_cancel_token – A io_event* which will be resumed on completion.
_sockfd – The socket descriptor.
_buffer – The buffer to receive into.
_flags – The flags to apply to the read operation.
-
inline auto send(int _sockfd, std::span<const std::byte> _buffer, int _flags, cancelation_token *_cancel_token = nullptr) noexcept
Send a message on a socket.
: See https://man7.org/linux/man-pages/man2/send.2.html.
@co_return The result of the
::send()
operation.- Parameters
_sockfd – The socket descriptor.
_buffer – The buffer to receive into.
_flags – The flags to apply to the write operation.
_cancel_token – [out] A ptr to a io_event* which will bet set to the cancelation handle.
-
void send(io_event *_cancel_token, int _sockfd, std::span<const std::byte> _buffer, int _flags) noexcept
Send a message on a socket.
cancel_token->data will hold the return code of the op.
See https://man7.org/linux/man-pages/man2/send.2.html.
- Parameters
_cancel_token – A io_event* which will be resumed on completion.
_sockfd – The socket descriptor.
_buffer – The buffer to receive into.
_flags – The flags to apply to the write operation.
-
inline auto accept(int _sockfd, struct sockaddr *_addr, socklen_t *_addrlen, int _flags, cancelation_token *_cancel_token = nullptr) noexcept
Accept a connection on a socket.
See https://man7.org/linux/man-pages/man2/accept.2.html.
@co_return The result of the
::accept()
operation.- Parameters
_sockfd – The socket descriptor.
_addr – The sockaddr to use.
_addrlen – The length of the sockaddre region.
_flags – The flags to apply to the accept operation.
_cancel_token – [out] A ptr to a io_event* which will bet set to the cancelation handle.
-
void accept(io_event *_cancel_token, int _sockfd, struct sockaddr *_addr, socklen_t *_addrlen, int _flag_) noexcept
Accept a connection on a socket.
cancel_token->data will hold the return code of the op.
See https://man7.org/linux/man-pages/man2/accept.2.html.
- Parameters
_cancel_token – A io_event* which will be resumed on completion.
_sockfd – The socket descriptor.
_addr – The sockaddr to use.
_addrlen – The length of the sockaddre region.
_flags – The flags to apply to the accept operation.
-
inline auto connect(int _sockfd, const struct sockaddr *_addr, socklen_t _addrlen, cancelation_token *_cancel_token = nullptr) noexcept
Initiate a connection on a socket.
See https://man7.org/linux/man-pages/man2/connect.2.html.
@co_return The result of the
::connect()
operation.- Parameters
_sockfd – The socket descriptor.
_addr – The sockaddr to use.
_addrlen – The length of the sockaddre region.
_cancel_token – [out] A ptr to a io_event* which will bet set to the cancelation handle.
-
void connect(io_event *_cancel_token, int _sockfd, const struct sockaddr *_addr, socklen_t _addrlen) noexcept
Initiate a connection on a socket.
cancel_token->data will hold the return code of the op.
See https://man7.org/linux/man-pages/man2/connect.2.html.
- Parameters
_cancel_token – A io_event* which will be resumed on completion.
_sockfd – The socket descriptor.
_addr – The sockaddr to use.
_addrlen – The length of the sockaddre region.
-
inline auto cancel_event(cancelation_token _key) noexcept
Attempt to cancel an operation.
See
CancelResult
for possible results.@co_return CancelResult The result of the cancel_event operation.
- Parameters
_key – The io handle to cancel.
_resume – Whether to resume or destroy the io_event*.
_cancel_code – On resumption, the code to resume the io_event* with.
-
void cancel_event(io_event *_cancel_token, cancelation_token _key) noexcept
Intiate a cancel operation.
This cancel does not attempt to clean up the waiting request.
- Parameters
_cancel_token – The handle to resume once cancel has been attempted.
_key – The handle to cancel.
-
void submit_pending_events() noexcept
Updater the counter on the submission queue to include any new submission.
This is done on every pass of the completion qeue.
-
void dispatch_user_event(user_event _handle) noexcept
Submits a user event to the event_loop.
- Parameters
_handle – The event to submit.
-
inline std::size_t event_size() const noexcept
The number of user events currently waiting to be handled.
- Returns
std::size_t
-
inline auto get_stop_function() noexcept
Get the stop function for the run time.
This is a lambda that just calls wake.
- Returns
A lambda wrapper for wake.
-
void run(std::stop_token _st) noexcept
Run the event loop until until signaled be the stop token.
- Parameters
_st – The stop token.
-
void wake(event_loop &_from) noexcept
Wakes the event loop by inserting a user space event.
- Parameters
_from – The event_loop to wake up from.
-
void wake() noexcept
Wakes the event loop by inserting a user space event.
-
int io_fd() noexcept
Public Static Functions
-
static CancelResult cancel_code(std::intptr_t _result) noexcept
Converts errno error codes into CancelResult.
- Parameters
_result – The errno result.
- Returns
CancelResult The corresponding CancelResult.
-
static inline constexpr std::string_view cancel_message(CancelResult _result) noexcept
Converts CancelResult into a message.
- Parameters
_result – The errno result.
- Returns
CancelResult The corresponding CancelResult message.
Public Static Attributes
-
static constexpr auto kQueueSize = 4096
-
enum class CancelResult