C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Automatic Coroutine Cancellation

From: Arthur O'Dwyer <arthur.j.odwyer_at_[hidden]>
Date: Thu, 9 Apr 2026 09:42:11 -0400
On Sat, Apr 4, 2026 at 5:04 AM Rhidian De Wit via Std-Proposals <
std-proposals_at_[hidden]> wrote:

>
> I've been reading up a bit on C++26 std::execution and I noticed that for
> cancellation we still use the `std::stop_token` approach to be able to
> "cancel" a coroutine by forcing the user to always call `stop_requested()`
> before continuing the coroutine, in addition to needing to pass a
> `std::stop_source` or `std::stop_token` around, making it pretty
> inconvenient to use.
>
> Now, there are ways to make this more automatic, for example, by embedding
> the `std::stop_source` in the coroutine's promise type and checking at
> every suspension / resumption point (`await_suspend()` and `await_resume()`
> respectfully) whether or not the coroutine has been cancelled. If so, you
> can throw an exception and let the coroutine unwind itself.
>
> I was wondering if there is a proposal for such an automatic cancellation
> feature in the works or already present?
>

I am relatively uneducated in this area; but no, I'm not aware of any plan
or proposal to embed a stop_token into every coroutine.
My kneejerk reaction was "That sounds bad! Every suspend point would become
an invisible interruption point — you couldn't hold a resource across a
suspend point without careful planning!"
But then I thought again, and realized that we already have *that*. The
caller is the one who decides whether to resume a coroutine_handle<>; if
the caller decides to destroy() it instead, well, that suspend point just
turned into an invisible abort anyway, from the coroutine's point of view.
Example of safely holding a resource across a suspend:
https://godbolt.org/z/azTW57qf8
Example of unsafely (leakily) holding the same:
https://godbolt.org/z/f4rTG7Kh3

But then I'm afraid I don't understand what feature you're asking for. You
can already "tell a coroutine to unwind itself" by just destroying the
handle you were using to talk to it. Why would you also need a
stop_token/stop_source to be involved? Are you trying to stop someone
*else's* coroutine, like from another thread, without the participation of
its owner? But then what do you expect the coroutine to do — report .done()
despite not having reached the co_return statement, I guess? Which means
what — call .final_suspend() on the promise without having first called
either `.return_value()` or `.return_void()`? Is that something that's
possible to do today (except manually)? Why would I want that?
In particular, adding the ability for the compiler to generate a new and
unusual sequence of calls to my promise type means suddenly there's a lot
more surface area I'd need to cover in my promise types' unit tests to make
sure they're not buggy/leaky even in this new special case.

HTH,
Arthur

Received on 2026-04-09 13:42:26