COROIO: NNet::TPollerBase Class Reference
COROIO
 
Loading...
Searching...
No Matches
NNet::TPollerBase Class Reference

Base class for pollers managing asynchronous I/O events and timers. More...

#include <poller.hpp>

Inheritance diagram for NNet::TPollerBase:
NNet::TEPoll NNet::TIOCp NNet::TKqueue NNet::TPoll NNet::TSelect NNet::TUring

Public Member Functions

 TPollerBase ()=default
 Default constructor.
 
 TPollerBase (const TPollerBase &)=delete
 Copying is disabled.
 
TPollerBaseoperator= (const TPollerBase &)=delete
 
unsigned AddTimer (TTime deadline, THandle h)
 Schedules a timer.
 
bool RemoveTimer (unsigned timerId, TTime deadline)
 Removes or cancels a timer.
 
void AddRead (int fd, THandle h)
 Registers a read event on a file descriptor.
 
void AddWrite (int fd, THandle h)
 Registers a write event on a file descriptor.
 
void AddRemoteHup (int fd, THandle h)
 Registers a remote hang-up (RHUP) event.
 
void RemoveEvent (int fd)
 Removes registered events for a specific file descriptor.
 
void RemoveEvent (THandle)
 Removes events associated with a given coroutine handle.
 
auto Sleep (TTime until)
 Suspends execution until the specified time.
 
template<typename Rep, typename Period>
auto Sleep (std::chrono::duration< Rep, Period > duration)
 Overload of Sleep() accepting a duration.
 
auto Yield ()
 Yields execution to the next event loop iteration.
 
void Wakeup (TEvent &&change)
 Wakes up a coroutine waiting on an event.
 
void WakeupReadyHandles ()
 Wakes up all coroutines waiting on ready events.
 
void SetMaxDuration (std::chrono::milliseconds maxDuration)
 Sets the maximum polling duration.
 
auto TimersSize () const
 Returns the number of scheduled timers.
 

Protected Member Functions

timespec GetTimeout () const
 Computes the poll timeout based on scheduled timers.
 
void Reset ()
 Clears the lists of ready events and pending changes.
 
void ProcessTimers ()
 Processes scheduled timers.
 

Static Protected Member Functions

static constexpr timespec GetMaxDuration (std::chrono::milliseconds duration)
 Computes a timespec from a duration.
 

Protected Attributes

int MaxFd_ = -1
 Highest file descriptor in use.
 
std::vector< TEventChanges_
 Pending changes (registered events).
 
std::vector< TEventReadyEvents_
 Events ready to wake up their coroutines.
 
unsigned TimerId_ = 0
 Counter for generating unique timer IDs.
 
std::priority_queue< TTimerTimers_
 Priority queue for scheduled timers.
 
TTime LastTimersProcessTime_
 Last time timers were processed.
 
unsigned LastFiredTimer_ = (unsigned)(-1)
 ID of the last fired timer.
 
std::chrono::milliseconds MaxDuration_ = std::chrono::milliseconds(100)
 Maximum poll duration.
 
timespec MaxDurationTs_ = GetMaxDuration(MaxDuration_)
 Max duration represented as timespec.
 

Detailed Description

Base class for pollers managing asynchronous I/O events and timers.

TPollerBase provides the common interface and functionality for pollers that drive asynchronous operations. It allows scheduling timers, registering I/O events (read, write, remote hang-up) on file descriptors, and waking up waiting coroutines. It also offers convenience methods such as Sleep() (and its overload accepting a std::chrono::duration) and Yield().

The class maintains internal collections for pending changes (events), ready events, and timers. It also keeps track of the maximum file descriptor, which is used in system-level polling calls.

Key methods include:

The class also provides helper methods for computing timeout values (via GetTimeout()).

The detailed comment inside Wakeup() describes how a waiting coroutine is resumed and how new event registrations are matched.

Member Function Documentation

◆ AddRead()

void NNet::TPollerBase::AddRead ( int fd,
THandle h )
inline

Registers a read event on a file descriptor.

Parameters
fdThe file descriptor.
hThe coroutine handle to resume when data is available.

◆ AddRemoteHup()

void NNet::TPollerBase::AddRemoteHup ( int fd,
THandle h )
inline

Registers a remote hang-up (RHUP) event.

Parameters
fdThe file descriptor.
hThe coroutine handle to resume when the remote end closes the connection.

◆ AddTimer()

unsigned NNet::TPollerBase::AddTimer ( TTime deadline,
THandle h )
inline

Schedules a timer.

Inserts a timer event with the given deadline and coroutine handle into the internal timer queue.

Parameters
deadlineThe time at which the timer should fire.
hThe handle of the coroutine to resume when the timer expires.
Returns
A unique timer ID.

◆ AddWrite()

void NNet::TPollerBase::AddWrite ( int fd,
THandle h )
inline

Registers a write event on a file descriptor.

Parameters
fdThe file descriptor.
hThe coroutine handle to resume when ready for writing.

◆ GetMaxDuration()

static constexpr timespec NNet::TPollerBase::GetMaxDuration ( std::chrono::milliseconds duration)
inlinestaticconstexprprotected

Computes a timespec from a duration.

Parameters
durationThe maximum duration in milliseconds.
Returns
A timespec representing the duration.

◆ GetTimeout()

timespec NNet::TPollerBase::GetTimeout ( ) const
inlineprotected

Computes the poll timeout based on scheduled timers.

Returns
A timespec representing the timeout.

◆ ProcessTimers()

void NNet::TPollerBase::ProcessTimers ( )
inlineprotected

Processes scheduled timers.

Resumes waiting coroutines for timers that have expired. The method tracks whether a timer was fired by comparing its ID to LastFiredTimer_.

◆ RemoveEvent() [1/2]

void NNet::TPollerBase::RemoveEvent ( int fd)
inline

Removes registered events for a specific file descriptor.

This method signals that events for a descriptor should be deregistered.

Parameters
fdThe file descriptor.

◆ RemoveEvent() [2/2]

void NNet::TPollerBase::RemoveEvent ( THandle )
inline

Removes events associated with a given coroutine handle.

This overload will be called by destructors of unfinished futures. Unimplemented.

Parameters
hThe coroutine handle.

◆ RemoveTimer()

bool NNet::TPollerBase::RemoveTimer ( unsigned timerId,
TTime deadline )
inline

Removes or cancels a timer.

Checks if the specified timer (by its ID) has fired based on the deadline; if not, inserts an empty timer to force removal.

Parameters
timerIdThe timer ID to remove.
deadlineThe associated deadline.
Returns
True if the timer had already fired; false otherwise.

◆ SetMaxDuration()

void NNet::TPollerBase::SetMaxDuration ( std::chrono::milliseconds maxDuration)
inline

Sets the maximum polling duration.

Parameters
maxDurationThe maximum duration for a poll cycle.

◆ Sleep() [1/2]

template<typename Rep, typename Period>
auto NNet::TPollerBase::Sleep ( std::chrono::duration< Rep, Period > duration)
inline

Overload of Sleep() accepting a duration.

Template Parameters
RepThe representation type.
PeriodThe period type.
Parameters
durationThe duration to sleep.
Returns
An awaitable sleep object.

◆ Sleep() [2/2]

auto NNet::TPollerBase::Sleep ( TTime until)
inline

Suspends execution until the specified time.

Returns an awaitable object that registers a timer and suspends the current coroutine until the deadline.

Parameters
untilThe time until which to sleep.
Returns
An awaitable sleep object.

◆ Wakeup()

void NNet::TPollerBase::Wakeup ( TEvent && change)
inline

Wakes up a coroutine waiting on an event.

This method resumes the coroutine associated with the given TEvent (change), then checks whether that coroutine has added a new wait for the same file descriptor.

Parameters
changeThe event change containing the file descriptor and coroutine handle.

Wakes up the coroutine associated with the given TEvent change, then checks whether that coroutine has added a new wait on the same file descriptor (Fd). We first store the current size of the Changes_ vector and call change.Handle.resume().

If after resuming, the coroutine does NOT add (or match) a wait entry for change.Fd, we assume that this descriptor is not in use yet and remove it from the poller by resetting change.Handle and appending change to Changes_.

In most cases, Changes_ grows by exactly one entry after resuming a coroutine (it suspends again on a descriptor), but there are scenarios where it can grow by more than one. For example, one coroutine might launch another coroutine without waiting; that second coroutine suspends on ReadSome/WriteSome, returns control to the first coroutine, which then also suspends on ReadSome/WriteSome. In that chain of calls, multiple new waits can be added before returning here, so Changes_ can increase by 2 (or potentially more) in a single wake-up cycle.

◆ WakeupReadyHandles()

void NNet::TPollerBase::WakeupReadyHandles ( )
inline

Wakes up all coroutines waiting on ready events.

Iterates over the list of ready events and calls Wakeup() on each.

◆ Yield()

auto NNet::TPollerBase::Yield ( )
inline

Yields execution to the next event loop iteration.

Equivalent to calling Sleep() with a default zero time.

Returns
An awaitable object for yielding execution.

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