Skip to navigation

hololink::module::ReactorV1

View as Markdown

Reactor provides an event loop that runs deferred, timed and file-descriptor-driven callbacks in a single thread.

Reactor is a singleton object, owned by the host and shared to every module. All callbacks it dispatches run one sequentially in a dedicated thread, so callbacks never run concurrently with each other and need no locking against one another. Callbacks must return promptly, since each one delays all the others, and must not let an exception escape.

Every method may be called from any thread, including from within a callback. Pending callbacks and alarms are discarded when the host shuts down.

#include <hololink/module/reactor.hpp>

Inherits from: hololink::module::Service< ReactorV1 > (public)


Methods

now

virtual struct timespec hololink::module::ReactorV1::now() const

The current time on the reactor’s clock.

This is a monotonic clock (not wall-clock time); it is the clock add_alarm() interprets its when argument against.

Returns: The current time.

add_callback

virtual void hololink::module::ReactorV1::add_callback(
std::shared_ptr<Callback> callback
)

Queues a callback on the reactor thread for execution as soon as possible.

Callbacks queued this way run in the order they were added.

Parameters

callback
std::shared_ptr<Callback>

The function to run. The reactor keeps it alive until it has run.

add_fd_callback

virtual void hololink::module::ReactorV1::add_fd_callback(
int fd,
std::shared_ptr<FdCallback> callback,
short events
)

Call a function whenever a file descriptor has events of interest.

Readiness is level-triggered, as for poll(2): the callback keeps being called for as long as the condition persists, so it should consume or clear it. There can be only one callback per file descriptor; adding another for the same fd replaces the earlier one. Events the reactor saw for an earlier registration of fd are never passed to a later one, even of the same callback. The reactor does not own or close fd.

Parameters

fd
int

The file descriptor to watch.

callback
std::shared_ptr<FdCallback>

The function to call. The reactor keeps it alive until it is removed or replaced and the reactor is done with it: a callback removed while the reactor waits for events, or runs another callback, is released on the reactor thread once that round of callbacks has run.

events
short

The poll(2) events to wait for, e.g. POLLIN.

remove_fd_callback

virtual void hololink::module::ReactorV1::remove_fd_callback(
int fd
)

Stop watching a file descriptor.

After this returns no new calls to the file descriptor’s callback will be scheduled. If called from a thread other than the reactor thread, a call that is already running may still be finishing. Does nothing if fd is not being watched. Remove the callback before closing fd: a callback whose fd is closed while it is registered is dropped, with a warning, when the reactor next polls it.

Parameters

fd
int

The file descriptor passed to add_fd_callback().

add_alarm_s

virtual AlarmHandle hololink::module::ReactorV1::add_alarm_s(
float seconds,
std::shared_ptr<Callback> callback
)

Run a callback once, after a delay.

Returns: A handle for cancel_alarm().

Parameters

seconds
float

Delay from now, in seconds.

callback
std::shared_ptr<Callback>

The function to run. The reactor keeps it alive until it has run or the alarm is cancelled.

add_alarm

virtual AlarmHandle hololink::module::ReactorV1::add_alarm(
const struct timespec &when,
std::shared_ptr<Callback> callback
)

Run a callback once, at a given time.

Alarms that are due run in order of their when. A when that has already passed runs as soon as possible.

Returns: A handle for cancel_alarm().

Parameters

when
const struct timespec &

Time to run at, on the clock reported by now().

callback
std::shared_ptr<Callback>

The function to run. The reactor keeps it alive until it has run or the alarm is cancelled.

cancel_alarm

virtual void hololink::module::ReactorV1::cancel_alarm(
AlarmHandle handle
)

Cancel a scheduled alarm.

Does nothing if handle is null, or if the alarm has already run or been cancelled.

Parameters

handle
AlarmHandle

The handle returned when the alarm was added.

is_current_thread

virtual bool hololink::module::ReactorV1::is_current_thread() const

Determine if the caller is running in the reactor thread.

Returns: true when called in the reactor thread.

module

std::shared_ptr<Module> hololink::module::ServiceBase::module() const

The Module that this service was published from.

The service holds no strong reference to its Module, so this does not extend the Module’s lifetime.

Returns: The owning Module, or an empty pointer if the service has not been published or its Module no longer exists.


Static methods

get_service

static std::shared_ptr<ReactorV1> hololink::module::ReactorV1::get_service(
std::shared_ptr<Module> module,
bool allow_null = false
)

Fetch the process-wide reactor from a module.

There is only one reactor, so no instance identifier is needed.

Returns: A shared pointer to the reactor.

Parameters

module
std::shared_ptr<Module>

The module to query.

allow_null
boolDefaults to false

If false (the default), throws std::runtime_error when the module doesn’t provide a reactor (or module is null). If true, returns nullptr instead.

for_each_type_id

static bool hololink::module::Service<ReactorV1>::for_each_type_id(
Callback &&cb
)

Iterate over every type_id supported by this instance.

The callback signature is bool(const char*) — returning false halts the walk; true continues. Iteration is depth-first, so you’ll see the most specific implementation types first.


Types

Typedefs

NameDefinitionDescription
Callbackstd::function< void()>A function run once on the reactor thread.
FdCallbackstd::function< void(int fd, short events)>A function run on the reactor thread when a watched file descriptor becomes ready.
AlarmHandlestd::shared_ptr< AlarmEntry >Handle to a pending alarm.

Inner classes

AlarmEntry

class hololink::module::ReactorV1::AlarmEntry

Opaque identifier of a pending alarm.

Obtained from add_alarm() or add_alarm_s(), and passed to cancel_alarm(). Applications neither create nor derive from it.