Skip to content

Generator local scope resources are not cleaned up after coroutine object going out of scope #221

Open
@SidneyCogdill

Description

@SidneyCogdill

I would have expected the local scope resources within a generator coroutine to be cleaned up at coroutine object destruction, but it didn't.

cobalt::generator<int> gg()
{
    boost::scope::defer_guard release = [&] { std::println("exiting gg"); };

    co_yield 10;
    co_yield 11;
    co_return 12;
}

cobalt::task<void> t12()
{
    {
        auto gen = gg();
        co_await gen;
    } // <- `gen` out of scope here, `release` should be destructed but it doesn't.
    std::println("gen is out of scope");
}

cobalt::main co_main(int, char **)
{
    {
        co_await t12();
    }
    std::println("t12 is out of scope");
    co_return 0;
}

Expected order:

exiting gg
gen is out of scope
t12 is out of scope

Actual order:

gen is out of scope
t12 is out of scope
exiting gg

This is very surprising (considering that co_await-ing does have proper cancellation support that cleans up the local scope objects) and it has caused a nasty bug that took me hours to diagnose.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions