Implementing a Rudimentary Task Type (Part 2)
Learn how to resume an awaiting coroutine and support void tasks.
We'll cover the following...
Resuming an awaiting coroutine
When the asynchronous task has been completed, it should transfer the control back to the coroutine, waiting for the task to finish. To resume this continuation, the Task object needs the coroutine_handle
to the continuation coroutine. This handle was passed to the Task
object’s await_suspend()
function, and conveniently we made sure to save that handle into the promise object:
Press + to interact
class Task {// ...auto await_suspend(std::coroutine_handle<> c) {h_.promise().continuation_ = c; // Save handlereturn h_;}// ...
The final_suspend()
function is responsible for suspending at the final suspend point of this coroutine and transferring execution to the awaiting coroutine. This is the relevant part of the Promise
reproduced for your convenience:
Press + to interact
auto Promise::final_suspend() noexcept {struct Awaitable {bool await_ready() noexcept { return false; } // Suspendauto await_suspend(std::coroutine_handle<Promise> h) noexcept{return h.promise().continuation_; // Transfer control to} // the waiting coroutinevoid await_resume() noexcept {}};return Awaitable{};}
To begin with, returning false
...