The following code doesn't work as my expectation.
#include <iostream>
#include <coroutine>
#include <vector>
struct symmetic_awaitable
{
std::coroutine_handle<> _next_h;
symmetic_awaitable(std::coroutine_handle<> h) : _next_h(h) {}
constexpr bool await_ready() const noexcept { return false; }
std::coroutine_handle<> await_suspend(std::coroutine_handle<>) const noexcept
{
return _next_h;
}
constexpr void await_resume() const noexcept {}
};
struct return_object : std::coroutine_handle<>
{
struct promise_type
{
return_object get_return_object()
{
return std::coroutine_handle<promise_type>::from_promise(*this);
}
std::suspend_always initial_suspend() noexcept { return {}; }
std::suspend_always final_suspend() noexcept { return {}; }
void return_void() {}
void unhandled_exception() {}
};
return_object(std::coroutine_handle<promise_type> h) : std::coroutine_handle<>(h) {}
};
std::vector<return_object> co_list;
return_object fa()
{
std::cout << "fa1" << std::endl;
co_await symmetic_awaitable(co_list[1]);
std::cout << "fa2" << std::endl;
co_return;
}
return_object fb()
{
std::cout << "fb1" << std::endl;
co_await symmetic_awaitable(co_list[2]);
std::cout << "fb2" << std::endl;
co_await std::suspend_always{};
std::cout << "fb3" << std::endl;
co_return;
}
return_object fc()
{
std::cout << "fc1" << std::endl;
co_await symmetic_awaitable(co_list[1]);
std::cout << "fc2" << std::endl;
co_return;
}
int main()
{
auto a = fa();
auto b = fb();
auto c = fc();
co_list.push_back(a);
co_list.push_back(b);
co_list.push_back(c);
a.resume();
std::cout << "end" << std::endl;
a.destroy();
b.destroy();
c.destroy();
}
I think the output will be
fa1
fb1
fc1
fb2
fa2
end
But the actual output is
fa1
fb1
fc1
fb2
end
Then I replace all co_await symmetic_awaitable(co_list[i]) with co_list[i].resume. The ouput is very strange
fa1
fb1
fc1
fb1
fc1
..... // the following is infinite loop of "fb1 fc1"
.....
.....
The C++20 coroutine shadow too many details, such that the code can't work normally as my expectation unless I know them all clearly.
Here are my questions after I read cppreference:
1. What's the defference of "caller" and "resumer" ?
a call b.resume(), then a is the resumer or caller of b ?
2. What's the exact meanning of "suspended" ?
a call b.resume(), then a is suspended or running? a resume b through co_await, then a is suspended or running ?