Case Study IV: Various Job Workflows
Discuss the job workflow, started in the section about the 'co_await' keyword.
We'll cover the following...
Before I modify the workflow from section co_await
, I want to make the awaiter workflow more transparent.
The transparent awaiter workflow
I added a few output messages to the program we saw previously when discussing co_await
.
#include <coroutine>#include <iostream>struct MySuspendAlways {bool await_ready() const noexcept {std::cout << " MySuspendAlways::await_ready" << '\n';return false;}void await_suspend(std::coroutine_handle<>) const noexcept {std::cout << " MySuspendAlways::await_suspend" << '\n';}void await_resume() const noexcept {std::cout << " MySuspendAlways::await_resume" << '\n';}};struct MySuspendNever {bool await_ready() const noexcept {std::cout << " MySuspendNever::await_ready" << '\n';return true;}void await_suspend(std::coroutine_handle<>) const noexcept {std::cout << " MySuspendNever::await_suspend" << '\n';}void await_resume() const noexcept {std::cout << " MySuspendNever::await_resume" << '\n';}};struct Job {struct promise_type;using handle_type = std::coroutine_handle<promise_type>;handle_type coro;Job(handle_type h): coro(h){}~Job() {if ( coro ) coro.destroy();}void start() {coro.resume();}struct promise_type {auto get_return_object() {return Job{handle_type::from_promise(*this)};}MySuspendAlways initial_suspend() {std::cout << " Job prepared" << '\n';return {};}MySuspendAlways final_suspend() noexcept {std::cout << " Job finished" << '\n';return {};}void unhandled_exception() {}};};Job prepareJob() {co_await MySuspendNever();}int main() {std::cout << "Before job" << '\n';auto job = prepareJob();job.start();std::cout << "After job" << '\n';}
First of all, I replaced the predefined awaitables std::suspend_always and std::suspend_never with my awaitables MySuspendAlways
(line 4) and MySuspendNever
(line 18). I use them in lines 49, 53, and 63. My awaitables mimic the behavior of the predefined awaitables but additionally write a comment. Due to the use of std::cout
, the member functions await_ready
, await_suspend
, and await_resume
cannot be declared as constexpr
.
The function initial_suspend
(line 49) is executed at the beginning of the coroutine and the function final_suspend
at its end (line 53 ...