...

/

Case Study IV: Various Job Workflows

Case Study IV: Various Job Workflows

Discuss the job workflow, started in the section about the 'co_await' keyword.

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.

Press + to interact
#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 ...