Having played a little with the current implementation of Coroutine TS in Clang, I stumbled upon the asio stackless coroutine implementation. They are described to be Portable Stackless Coroutines in One* Header. Dealing mostly with asynchronous code I wanted to try them as well.
The coroutine block inside the main
function shall await the result asynchronously set by the thread spawned in function foo
. However I am uncertain on how to let execution continue at the point <1>
(after the yield
expression) once the thread set the value.
Using the Coroutine TS I would call the coroutine_handle
, however boost::asio::coroutine
seems not to be callable.
Is this even possible using boost::asio::coroutine
?
#include <thread>
#include <chrono>
#include <boost/asio/coroutine.hpp>
#include <boost/asio/yield.hpp>
#include <cstdio>
using namespace std::chrono_literals;
using coroutine = boost::asio::coroutine;
void foo(coroutine & coro, int & result) {
std::thread([&](){
std::this_thread::sleep_for(1s);
result = 3;
// how to resume at <1>?
}).detach();
}
int main(int, const char**) {
coroutine coro;
int result;
reenter(coro) {
// Wait for result
yield foo(coro, result);
// <1>
std::printf("%d\n", result);
}
std::thread([](){
std::this_thread::sleep_for(2s);
}).join();
return 0;
}
Thanks for your help
First off, stackless coroutines are better described as resumable functions. The problem you're currently having is using main. If you extract your logic to a separate functor it would be possible:
Note that it's not possible to yield from sub functions. This is a limitation of stackless coroutines.
How it works:
Now "start" is done, and you start another thread to wait for. Meanwhile, foo's thread finishes its sleep and call your task again. Now:
foo thread is now done and main is likely still waiting for the 2nd thread.