Sponge
CS144's user-space TCP library
Classes | Public Types | Public Member Functions | Private Types | Private Attributes | List of all members
EventLoop Class Reference

Waits for events on file descriptors and executes corresponding callbacks. More...

#include <eventloop.hh>

Classes

class  Rule
 Specifies a condition and callback that an EventLoop should handle. More...
 

Public Types

enum  Direction : short { Direction::In = POLLIN, Direction::Out = POLLOUT }
 Indicates interest in reading (In) or writing (Out) a polled fd. More...
 
enum  Result { Result::Success, Result::Timeout, Result::Exit }
 Returned by each call to EventLoop::wait_next_event. More...
 

Public Member Functions

void add_rule (const FileDescriptor &fd, const Direction direction, const CallbackT &callback, const InterestT &interest=[] { return true;}, const CallbackT &cancel=[] {})
 Add a rule whose callback will be called when fd is ready in the specified Direction. More...
 
Result wait_next_event (const int timeout_ms)
 Calls poll(2) and then executes callback for each ready fd. More...
 

Private Types

using CallbackT = std::function< void(void)>
 Callback for ready Rule::fd. More...
 
using InterestT = std::function< bool(void)>
 true return indicates Rule::fd should be polled. More...
 

Private Attributes

std::list< Rule_rules {}
 All rules that have been added and not canceled. More...
 

Detailed Description

Waits for events on file descriptors and executes corresponding callbacks.

An EventLoop holds a std::list of Rule objects. Each time EventLoop::wait_next_event is executed, the EventLoop uses the Rule objects to construct a call to poll(2).

When a Rule is installed using EventLoop::add_rule, it will be polled for the specified Rule::direction whenver the Rule::interest callback returns true, until Rule::fd is no longer readable (for Rule::direction == Direction::In) or writable (for Rule::direction == Direction::Out). Once this occurs, the Rule is canceled, i.e., the EventLoop deletes it.

A Rule installed using EventLoop::add_cancelable_rule will be polled and canceled under the same conditions, with the additional condition that if Rule::callback returns true, the Rule will be canceled.

Definition at line 12 of file eventloop.hh.

Member Typedef Documentation

◆ CallbackT

using EventLoop::CallbackT = std::function<void(void)>
private

Callback for ready Rule::fd.

Definition at line 21 of file eventloop.hh.

◆ InterestT

using EventLoop::InterestT = std::function<bool(void)>
private

true return indicates Rule::fd should be polled.

Definition at line 22 of file eventloop.hh.

Member Enumeration Documentation

◆ Direction

enum EventLoop::Direction : short
strong

Indicates interest in reading (In) or writing (Out) a polled fd.

Enumerator
In 

Callback will be triggered when Rule::fd is readable.

Out 

Callback will be triggered when Rule::fd is writable.

Definition at line 15 of file eventloop.hh.

◆ Result

enum EventLoop::Result
strong

Returned by each call to EventLoop::wait_next_event.

Enumerator
Success 

At least one Rule was triggered.

Timeout 

No rules were triggered before timeout.

Exit 

All rules have been canceled or were uninterested; make no further calls to EventLoop::wait_next_event.

Definition at line 43 of file eventloop.hh.

Member Function Documentation

◆ add_rule()

void EventLoop::add_rule ( const FileDescriptor fd,
const Direction  direction,
const CallbackT callback,
const InterestT interest = [] { return true; },
const CallbackT cancel = [] {} 
)

Add a rule whose callback will be called when fd is ready in the specified Direction.

Parameters
[in]fdis the FileDescriptor to be polled
[in]directionindicates whether to poll for reading (Direction::In) or writing (Direction::Out)
[in]callbackis called when fd is ready.
[in]interestis called by EventLoop::wait_next_event. If it returns true, fd will be polled, otherwise fd will be ignored only for this execution of `wait_next_event.
[in]cancelis called when the rule is cancelled (e.g. on hangup, EOF, or closure).

Definition at line 23 of file eventloop.cc.

◆ wait_next_event()

EventLoop::Result EventLoop::wait_next_event ( const int  timeout_ms)

Calls poll(2) and then executes callback for each ready fd.

Parameters
[in]timeout_msis the timeout value passed to poll(2); wait_next_event returns Result::Timeout if no fd is ready after the timeout expires.
Returns
Eventloop::Result indicating success, timeout, or no more Rule objects to poll.

For each Rule, this function first calls Rule::interest; if true, Rule::fd is added to the list of file descriptors to be polled for readability (if Rule::direction == Direction::In) or writability (if Rule::direction == Direction::Out) unless Rule::fd has reached EOF, in which case the Rule is canceled (i.e., deleted from EventLoop::_rules).

Next, this function calls poll(2) with timeout value timeout_ms.

Then, for each ready file descriptor, this function calls Rule::callback. If fd reaches EOF or if the Rule was registered using EventLoop::add_cancelable_rule and Rule::callback returns true, this Rule is canceled.

If an error occurs during polling, this function throws a std::runtime_error.

If a signal(7) was caught during polling or if EventLoop::_rules becomes empty, this function returns Result::Exit.

If a timeout occurred while polling (i.e., no fd became ready), this function returns Result::Timeout.

Otherwise, this function returns Result::Success.

IMPORTANT: every call to Rule::callback must read from or write to Rule::fd, or the interest callback must stop returning true after the callback completes. If none of these conditions occur, EventLoop::wait_next_event will throw std::runtime_error. This is because poll(2) is level triggered, so failing to act on a ready file descriptor will result in a busy loop (poll returns on a ready file descriptor; file descriptor is not read or written, so it is still ready; the next call to poll will immediately return).

Definition at line 61 of file eventloop.cc.

Member Data Documentation

◆ _rules

std::list<Rule> EventLoop::_rules {}
private

All rules that have been added and not canceled.

Definition at line 39 of file eventloop.hh.


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