jbaldwin / libcoro

C++20 coroutine library

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Using std::suspend_always as awaiter does not work

tinkerbeast opened this issue · comments

I was trying out the following code:

coro::task<int> coro_example(int loops) {
  std::cout << "START coro_example\n";
  for (int i = 0; i < loops; ++i) {
    std::cout << "coro_example i=" << i << "\n";
    co_await std::suspend_always{};
  }
  std::cout << "END coro_example\n";
  co_return 42;
}

int main() {
  coro::sync_wait(coro_example(3));
}

My expectation was that it would go through the loop. However it got stuck after the first iteration. The output I get is:

START coro_example
coro_example i=0

You need a runtime, sync_wait isn't a runtime, it just blocks until the coroutine completes. Most of the examples show switching context into a thread pool or io_scheduler to process the results until completion.

The other problem with this example is that there is no trigger with std::suspend_always to restart your coroutine. What is supposed to resume execution? How should sync_wait know that you suspended your coroutine and it should just restart immediately? It doesn't. If you use coro::thread_pool you can call yield() and it will place it on the execution queue to run as soon as a thread is available. I think this is the behavior you are looking for.

@tinkerbeast did this help, are you still interested in using this? Otherwise I'm going to close this due to inactivity.

This helped a little. In your implementation the coroutine, awaiter and execution environment is tightly coupled. What I was looking for is something where I can write my own execution environment using existing coroutines or awaiters. I don't think that will be possible in your implementation.

Sounds like you want to write your own coroutine library in a completely different way where sync wait is an execution environment and the driving thread just repeatedly calls .resume() on the provided coroutines until completion. This probably will work well for non-io tasks, but will struggle when io takes a long time so the execution environment needs to know when to resume for you in those cases. Good luck.