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.

using io_event = storage_event<int>
using cancelation_token = io_event*
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