Sane C++ Libraries
C++ Platform Abstraction Libraries
SC::AsyncEventLoop Struct Reference

Asynchronous I/O (files, sockets, timers, processes, fs events, threads wake-up) (see Async) AsyncEventLoop pushes all AsyncRequest derived classes to I/O queues in the OS. More...

#include <Async.h>

Classes

struct  Options
 Options given to AsyncEventLoop::create. More...
 

Public Types

using InternalOpaque = OpaqueObject< InternalDefinition >
 

Public Member Functions

Result create (Options options=Options())
 Creates the event loop kernel object. More...
 
Result close ()
 Closes the event loop kernel object. More...
 
Result run ()
 Blocks until there are no more active queued requests, dispatching all completions. More...
 
Result runOnce ()
 Blocks until at least one request proceeds, ensuring forward progress, dispatching all completions. More...
 
Result runNoWait ()
 Process active requests if any, dispatching their completions, or returns immediately without blocking. More...
 
Result submitRequests (AsyncKernelEvents &kernelEvents)
 Submits all queued async requests. More...
 
Result blockingPoll (AsyncKernelEvents &kernelEvents)
 Blocks until at least one event happens, ensuring forward progress, without executing completions. More...
 
Result dispatchCompletions (AsyncKernelEvents &kernelEvents)
 Invokes completions for the AsyncKernelEvents collected by a call to AsyncEventLoop::blockingPoll. More...
 
Result wakeUpFromExternalThread (AsyncLoopWakeUp &wakeUp)
 Wake up the event loop from a thread different than the one where run() is called (and potentially blocked). More...
 
Result wakeUpFromExternalThread ()
 Wake up the event loop from a thread different than the one where run() is called (and potentially blocked) More...
 
Result createAsyncTCPSocket (SocketFlags::AddressFamily family, SocketDescriptor &outDescriptor)
 Helper to creates a TCP socket with AsyncRequest flags of the given family (IPV4 / IPV6). More...
 
Result associateExternallyCreatedTCPSocket (SocketDescriptor &outDescriptor)
 Associates a TCP Socket created externally (without using createAsyncTCPSocket) with the eventLoop. More...
 
Result associateExternallyCreatedFileDescriptor (FileDescriptor &outDescriptor)
 Associates a File descriptor created externally with the eventLoop. More...
 
Time::HighResolutionCounter getLoopTime () const
 Get Loop time. More...
 

Static Public Member Functions

static bool tryLoadingLiburing ()
 Check if liburing is loadable (only on Linux) More...
 

Friends

struct AsyncRequest
 
struct AsyncFileWrite
 
struct AsyncFileRead
 

Detailed Description

Asynchronous I/O (files, sockets, timers, processes, fs events, threads wake-up) (see Async) AsyncEventLoop pushes all AsyncRequest derived classes to I/O queues in the OS.

See also
AsyncEventLoopMonitor can be used to integrate AsyncEventLoop with a GUI event loop

Basic lifetime for an event loop is:

AsyncEventLoop eventLoop;
SC_TRY(eventLoop.create()); // Create OS specific queue handles
// ...
// Add all needed AsyncRequest
// ...
SC_TRY(eventLoop.run());
// ...
// Here all AsyncRequest have either finished or have been stopped
// ...
SC_TRY(eventLoop.close()); // Free OS specific queue handles
#define SC_TRY(expression)
Checks the value of the given expression and if failed, returns this value to caller.
Definition: Result.h:47

Member Function Documentation

◆ associateExternallyCreatedFileDescriptor()

Result SC::AsyncEventLoop::associateExternallyCreatedFileDescriptor ( FileDescriptor outDescriptor)

Associates a File descriptor created externally with the eventLoop.

◆ associateExternallyCreatedTCPSocket()

Result SC::AsyncEventLoop::associateExternallyCreatedTCPSocket ( SocketDescriptor outDescriptor)

Associates a TCP Socket created externally (without using createAsyncTCPSocket) with the eventLoop.

◆ blockingPoll()

Result SC::AsyncEventLoop::blockingPoll ( AsyncKernelEvents kernelEvents)

Blocks until at least one event happens, ensuring forward progress, without executing completions.

It's one of the three building blocks of AsyncEventLoop::runOnce allowing co-operation of AsyncEventLoop within another event loop (for example a GUI event loop or another IO event loop).

One possible example of such integration with a GUI event loop could:

Waiting on requests blocks the current thread with 0% CPU utilization.

Parameters
kernelEventsMandatory parameter to store kernel IO events WITHOUT running their completions. In that case user is expected to run completions passing it to AsyncEventLoop::dispatchCompletions.
See also
AsyncEventLoop::submitRequests sends async requests to kernel before calling blockingPoll
AsyncEventLoop::dispatchCompletions invokes callbacks associated with kernel events after blockingPoll

◆ close()

Result SC::AsyncEventLoop::close ( )

Closes the event loop kernel object.

◆ create()

Result SC::AsyncEventLoop::create ( Options  options = Options())

Creates the event loop kernel object.

◆ createAsyncTCPSocket()

Result SC::AsyncEventLoop::createAsyncTCPSocket ( SocketFlags::AddressFamily  family,
SocketDescriptor outDescriptor 
)

Helper to creates a TCP socket with AsyncRequest flags of the given family (IPV4 / IPV6).

It also automatically registers the socket with the eventLoop (associateExternallyCreatedTCPSocket)

◆ dispatchCompletions()

Result SC::AsyncEventLoop::dispatchCompletions ( AsyncKernelEvents kernelEvents)

Invokes completions for the AsyncKernelEvents collected by a call to AsyncEventLoop::blockingPoll.

This is typically done when user wants to pool for events on a thread (calling AsyncEventLoop::blockingPoll) and dispatch the callbacks on another thread (calling AsyncEventLoop::dispatchCompletions). The typical example would be integrating AsyncEventLoop with a GUI event loop.

See also
AsyncEventLoop::blockingPoll for a description on how to integrate AsyncEventLoop with another event loop

◆ getLoopTime()

Time::HighResolutionCounter SC::AsyncEventLoop::getLoopTime ( ) const

Get Loop time.

◆ run()

Result SC::AsyncEventLoop::run ( )

Blocks until there are no more active queued requests, dispatching all completions.

It's useful for applications where the eventLoop is the only (or the main) loop. One example could be a console based app doing socket IO or a web server. Waiting on kernel events blocks the current thread with 0% CPU utilization.

See also
AsyncEventLoop::blockingPoll to integrate the loop with a GUI event loop

◆ runNoWait()

Result SC::AsyncEventLoop::runNoWait ( )

Process active requests if any, dispatching their completions, or returns immediately without blocking.

It's useful for game-like applications where the event loop runs every frame and one would like to check and dispatch its I/O callbacks in-between frames. This call allows poll-checking I/O without blocking.

See also
AsyncEventLoop::blockingPoll to integrate the loop with a GUI event loop

◆ runOnce()

Result SC::AsyncEventLoop::runOnce ( )

Blocks until at least one request proceeds, ensuring forward progress, dispatching all completions.

It's useful for application where it's needed to run some idle work after every IO event. Waiting on requests blocks the current thread with 0% CPU utilization.

This function is a shortcut invoking async event loop building blocks:

◆ submitRequests()

Result SC::AsyncEventLoop::submitRequests ( AsyncKernelEvents kernelEvents)

Submits all queued async requests.

An AsyncRequest becomes queued after user calls its specific AsyncRequest::start method.

See also
AsyncEventLoop::blockingPoll for a description on how to integrate AsyncEventLoop with another event loop

◆ tryLoadingLiburing()

static bool SC::AsyncEventLoop::tryLoadingLiburing ( )
static

Check if liburing is loadable (only on Linux)

Returns
true if liburing has been loaded, false otherwise (and on any non-Linux os)

◆ wakeUpFromExternalThread() [1/2]

Result SC::AsyncEventLoop::wakeUpFromExternalThread ( )

Wake up the event loop from a thread different than the one where run() is called (and potentially blocked)

◆ wakeUpFromExternalThread() [2/2]

Result SC::AsyncEventLoop::wakeUpFromExternalThread ( AsyncLoopWakeUp wakeUp)

Wake up the event loop from a thread different than the one where run() is called (and potentially blocked).

The parameter is an AsyncLoopWakeUp that must have been previously started (with AsyncLoopWakeUp::start).


The documentation for this struct was generated from the following file: