lewissbaker / cppcoro

A library of C++ coroutine abstractions for the coroutines TS
MIT License
3.36k stars 462 forks source link

Question: task lifecycle and final_suspend #193

Open obhi-d opened 3 years ago

obhi-d commented 3 years ago

Hello,

First thanks for the awesome library. I have a question regarding lifecycle of cppcoro::task<> object. Imagine a scenario where a function is producing a task, and launching them in a thread pool:

cppcoro::task<void> do_something_on_threadpool(cppcoro::static_thread_pool& tp)
{
  // First schedule the coroutine onto the threadpool.
  co_await tp.schedule();

  // When it resumes, this coroutine is now running on the threadpool.
  do_something();
}

// executing in MainThread
void producer(cppcoro::static_thread_pool& tp)
{
  cppcoro::task<void> task0 = do_something_on_threadpool(tp);
  // wait for the tasks
  co_await task0;
}

In this case, lets assume for task0, we enter final_suspend from some other thread T0, and reach final_awaiter. This would mean the coroutine .done() will return true, Now lets say we are in MainThread, and try to execute co_await task0; So now, if I want to set producer() as the continuation in co_await, await_ready() will return true, and the continuation will not be set. Lets say this happens, and we return from the function i.e. we exit the scope of cppcoro::task and the task coroutine gets destroyed. Now lets say, thread T0 starts working on final_suspend(...), it will try to access the task state that was already destroyed in MainThread resulting in SEGFAULT.

Please correct me if I am wrong about this.

Thanks, obhi