C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Automatic Coroutine Cancellation

From: Rhidian De Wit <rhidiandewit_at_[hidden]>
Date: Thu, 9 Apr 2026 18:07:08 +0200
>
> 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!"

That's indeed the goal you might have. Now, of course, holding a resource
across suspension points is completely acceptable, as long as you're
following RAII principles (so your 2nd example of using a raw memory
allocation is unsafe by modern C++ standards). The reason I think having a
more automatic form of cancellation is a good thing is because it's useful
to have built-in ways to cancel a long-running operation, such as a file
download/upload, a long asynchronous wait, ...
Right now, if we would *want* to cancel (for any reason) we're forced to
use the very verbose *std::stop_source* and *std::stop_token*.

What I'd like is to have a standardised promise type for coroutines which
*could* support cancellation. I don't see a reason forcing every user to
create their own promise type or rely on libraries for promise types. If
the standard is providing a runtime, then we should provide a promise as
well, and in my opinion, that promise should be able to be cancelled.
Mind you, I don't think this promise should cancel itself by default
(although there's also some benefits to that), but as a first
implementation, this standard provided promise could provide a
*cancel()* function,
which will cancel the coroutine at the earliest opportunity.

Op do 9 apr 2026 om 15:42 schreef Arthur O'Dwyer <arthur.j.odwyer_at_[hidden]
>:

> 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
>


-- 
Rhidian De Wit
Software Engineer - Barco

Received on 2026-04-09 18:07:21