Skip to content

when_all hangs in finally when triggered by stop #1849

@jessmorecroft

Description

@jessmorecroft

This is a strange one - when_all doesn't seem to complete properly when used in finally triggered by a stop, as shown here:

    execpools::asio_thread_pool pool(1);

    boost::asio::steady_timer timer1(pool.get_executor());
    boost::asio::steady_timer timer2(pool.get_executor());
    timer1.expires_after(std::chrono::seconds(2));
    timer2.expires_after(std::chrono::seconds(1));

    auto result = sync_wait(starts_on(
        pool.get_scheduler(),
        when_any(
            timer1.async_wait(asioexec::use_sender) | then([] { return 41; }) |
                finally(sequence(
                    just() | then([] { fmt::println("before when_all"); }),
                    when_all(
                        just() | then([] { fmt::println("in finally 1"); }),
                        just() | then([] { fmt::println("in finally 2"); })),
                    just() | then([] { fmt::println("after when_all"); }))),
            timer2.async_wait(asioexec::use_sender) |
                then([] { return 42; }))));

    fmt::println("result: {}", result);

This outputs:

before when_all
in finally 1
in finally 2
(hangs)

If I change this to swap the timer durations, so our finally will be invoked as a consequence of a non-stopped completion, it completes as expected:

.....
    timer1.expires_after(std::chrono::seconds(1));
    timer2.expires_after(std::chrono::seconds(2));
.....

Output:

before when_all
in finally 1
in finally 2
after when_all
result: optional((41))

I have been trawling finally and when_all but can't figure it out. Is my usage wrong in some way perhaps..?

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