admin管理员组文章数量:1122846
I want to know a method to pass values from the caller to the coroutine.
My idea:
Any awaiter type must provide a await_resume()
function. This function can return something to the co_await
inside the coroutine.
Is it possible to set the value inside the awaiter to transport data to the coroutine? The question in this case is: How we can get the awaiter object inside the caller?
Example:
#include <coroutine>
#include <iostream>
struct ReturnObject {
struct promise_type {
unsigned value_;
ReturnObject get_return_object()
{
return ReturnObject
{
.h_ = std::coroutine_handle<promise_type>::from_promise(*this)
};
}
std::suspend_never initial_suspend() { return {}; }
std::suspend_never final_suspend() noexcept { return {}; }
void unhandled_exception() {}
};
std::coroutine_handle<promise_type> h_;
operator std::coroutine_handle<promise_type>() const { return h_; }
};
struct MyAwaiter
{
bool suspend;
bool await_ready() const noexcept { return suspend; }
void await_suspend( std::coroutine_handle<> ) const noexcept { std::cout << "My awaiter suspend" << std::endl;}
std::string await_resume() const noexcept { std::cout << "My awaiter resume" << std::endl; return "Test!";}
};
ReturnObject
counter()
{
for (unsigned i = 0;; ++i)
{
std::cout << "i: " << i << std::endl;
std::string ret = co_await MyAwaiter{false};
std::cout << "Ret: " << ret << std::endl;
}
}
int main()
{
std::coroutine_handle<ReturnObject::promise_type> h = counter();
ReturnObject::promise_type &promise = h.promise();
for (int i = 0; i < 3; ++i)
{
std::cout << "Next iteration" << std::endl;
h();
/// how we can get the awaiter object here??? If we can get it, we can modify
/// it to pass data to the coroutine. Is this possible?
}
h.destroy();
}
Maybe I am totally wrong and there is any other way to pass data from the caller to the coroutine. If so: Please give me a hint and in best case a minimal working example.
I want to know a method to pass values from the caller to the coroutine.
My idea:
Any awaiter type must provide a await_resume()
function. This function can return something to the co_await
inside the coroutine.
Is it possible to set the value inside the awaiter to transport data to the coroutine? The question in this case is: How we can get the awaiter object inside the caller?
Example:
#include <coroutine>
#include <iostream>
struct ReturnObject {
struct promise_type {
unsigned value_;
ReturnObject get_return_object()
{
return ReturnObject
{
.h_ = std::coroutine_handle<promise_type>::from_promise(*this)
};
}
std::suspend_never initial_suspend() { return {}; }
std::suspend_never final_suspend() noexcept { return {}; }
void unhandled_exception() {}
};
std::coroutine_handle<promise_type> h_;
operator std::coroutine_handle<promise_type>() const { return h_; }
};
struct MyAwaiter
{
bool suspend;
bool await_ready() const noexcept { return suspend; }
void await_suspend( std::coroutine_handle<> ) const noexcept { std::cout << "My awaiter suspend" << std::endl;}
std::string await_resume() const noexcept { std::cout << "My awaiter resume" << std::endl; return "Test!";}
};
ReturnObject
counter()
{
for (unsigned i = 0;; ++i)
{
std::cout << "i: " << i << std::endl;
std::string ret = co_await MyAwaiter{false};
std::cout << "Ret: " << ret << std::endl;
}
}
int main()
{
std::coroutine_handle<ReturnObject::promise_type> h = counter();
ReturnObject::promise_type &promise = h.promise();
for (int i = 0; i < 3; ++i)
{
std::cout << "Next iteration" << std::endl;
h();
/// how we can get the awaiter object here??? If we can get it, we can modify
/// it to pass data to the coroutine. Is this possible?
}
h.destroy();
}
Maybe I am totally wrong and there is any other way to pass data from the caller to the coroutine. If so: Please give me a hint and in best case a minimal working example.
Share Improve this question asked Nov 22, 2024 at 14:06 KlausKlaus 25.6k9 gold badges65 silver badges129 bronze badges 01 Answer
Reset to default 1await_suspend
accepts a std::coroutine_handle<void>
which you can overload to match std::coroutine_handle<ReturnObject::promise_type>
and it will be called if it is awaited by that promise_type
, and handle.promise()
will give you access to the promise.
void await_suspend( std::coroutine_handle<ReturnObject::promise_type> h) noexcept {
std::cout << "My awaiter suspend on ReturnObject" << std::endl;
h.promise().awaiter = this; // new member in promise_type
}
then in the caller you can get this information from the promise and modify the awaiter.
h.promise().awaiter->data = "foo";
Both the awaiter and the return object have access to the promise_type
, which should be used to store the relevant information, like why the coroutine was suspended, and what it is waiting on, so the caller can respond to the awaiter.
full example
#include <coroutine>
#include <iostream>
struct MyAwaiter;
struct ReturnObject {
struct promise_type {
unsigned value_;
ReturnObject get_return_object()
{
return ReturnObject
{
.h_ = std::coroutine_handle<promise_type>::from_promise(*this)
};
}
MyAwaiter* awaiter = nullptr;
std::suspend_never initial_suspend() { return {}; }
std::suspend_never final_suspend() noexcept { return {}; }
void unhandled_exception() {}
};
std::coroutine_handle<promise_type> h_;
operator std::coroutine_handle<promise_type>() const { return h_; }
};
struct MyAwaiter
{
bool suspend;
bool await_ready() const noexcept { return suspend; }
void await_suspend( std::coroutine_handle<ReturnObject::promise_type> h) noexcept {
std::cout << "My awaiter suspend on ReturnObject" << std::endl;
h.promise().awaiter = this;
}
void await_suspend( std::coroutine_handle<> ) const noexcept { std::cout << "My awaiter suspend" << std::endl;}
std::string data;
std::string await_resume() const noexcept { std::cout << "My awaiter resume" << std::endl; return data;}
};
ReturnObject
counter()
{
for (unsigned i = 0;; ++i)
{
std::cout << "i: " << i << std::endl;
std::string ret = co_await MyAwaiter{false};
std::cout << "Ret: " << ret << std::endl;
}
}
int main()
{
std::coroutine_handle<ReturnObject::promise_type> h = counter();
ReturnObject::promise_type &promise = h.promise();
for (int i = 0; i < 3; ++i)
{
std::cout << "Next iteration" << std::endl;
h.promise().awaiter->data = "foo";
h();
}
h.destroy();
}
godbolt link
本文标签: chow we can pass values to a coroutineStack Overflow
版权声明:本文标题:c++ - how we can pass values to a coroutine - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736303248a1931820.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论