Cabbas
Cabbas

Reputation: 81

coroutine_handle::done always returns false

I have a very simple coroutine example to understand basics. However, I am stuck to understand why the done method of the handle object still returns false. I call resume and there is no more co_await though. What am I missing here?

#include <coroutine>
#include <iostream>


struct ReturnObject {
    struct promise_type {
        ReturnObject get_return_object() {
            return {std::coroutine_handle<promise_type>::from_promise(*this)};
        }
        std::suspend_never initial_suspend() noexcept { return {}; }
        std::suspend_never final_suspend() noexcept { return {}; }
        void unhandled_exception() {}
        void return_void() noexcept {}
    };
      
    ReturnObject(std::coroutine_handle<> h) : h_{h}{ } 

    std::coroutine_handle<> h_; 
};

ReturnObject foo() {
    std::cout << "1. Hello World!\n";
    co_await std::suspend_always{};
    std::cout << "2. Hello World!\n";
}

int main(int argc, char** argv) {
    ReturnObject ret_object = foo();
    ret_object.h_();
    std::cout << ret_object.h_.done() << std::endl;
    return 0;
}


I call resume and there is no more co_await though but done method always still returns false

Upvotes: 1

Views: 38

Answers (1)

Wutz
Wutz

Reputation: 2964

done is only defined for coroutine handles that represent a suspended coroutine. It will return true if the represented coroutine is suspended at its final suspension point, false otherwise.

Your test coroutine finishes and the final suspension point does not suspend. That means the coroutine is immediately cleaned up and any state freed. So your coroutine handle doesn't represent a coroutine any more, it's gone.

Have final_suspend return suspend_always and you'll see what you expected. But then you'll have to call destroy on the coroutine handle, otherwise you'll leak it.

Upvotes: 2

Related Questions