Coroutines

A Task is a C++20 coroutine that produces a single result and can be cancelled while it is suspended. A Generator yields a sequence of values and may also suspend. Both types integrate with the event loop: awaitable operations resume the coroutine when I/O, timers or other loop-driven work complete.

These types are available when the program is compiled as C++20 or later.

Use a function that returns Task as an asynchronous unit of work. The coroutine starts suspended. Use Task::run() to begin execution on the current thread. After the task has finished, Task::done() is true and Task::result() returns the value.

Inside a task, co_await suspends until an awaitable operation completes. Framework types already provide awaitables, for example Pt::System::Timer::waitAsync() for a one-shot delay. Custom operations derive from Awaiter or BasicAwaiter.

I/O awaitables typically resume from the event loop. The usual pairing is to start the task with Task::run() and then run the loop so completions can resume the coroutine.

Destroying a task or calling Task::cancel() aborts the pending awaitable and destroys the coroutine frame. Nested tasks cancel the inner pending operation the same way. A generator cancels in the same manner.

Exceptions that leave a coroutine body are stored. They are rethrown by Task::result() and by co_await of that task.

The following example starts a task that waits for a timer and then exits the loop:

Pt::Task<> delayThenExit(Pt::System::EventLoop& loop,
{
co_await timer.waitAsync(1000);
loop.exit();
}
int main()
{
timer.setActive(loop);
Pt::Task<> task = delayThenExit(loop, timer);
task.run();
return loop.run();
}
void run()
Starts the loop.
Notifies clients in constant intervals.
Definition: Timer.h:79
void setActive(EventLoop &loop)
Sets the used event loop.
void exit()
Stops the loop.
Thread-safe event loop supporting I/O multiplexing and Timers.
Definition: EventLoop.h:83
Thread-safe event loop supporting I/O multiplexing and Timers.
Definition: MainLoop.h:67