Skip to content

Commit 6123ba8

Browse files
committed
Update 4007 to take into consideration the Croydon changes (new revision R2)
1 parent 73ec5f5 commit 6123ba8

File tree

1 file changed

+26
-9
lines changed

1 file changed

+26
-9
lines changed

source/network-endeavor/todo/d4007-senders-and-coros.md

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: "Info: Open Issues in `std::execution::task`"
3-
document: D4007R1
4-
date: 2026-03-12
3+
document: P4007R2
4+
date: 2026-04-08
55
reply-to:
66
- "Vinnie Falco <vinnie.falco@gmail.com>"
77
- "Mungo Gill <mungo.gill@me.com>"
@@ -10,12 +10,19 @@ audience: LEWG
1010

1111
## Abstract
1212

13-
`std::execution::task` ([P3552R3](https://wg21.link/p3552r3)<sup>[1]</sup>) has open issues identified by national ballot comments, LWG issues, and published papers. This paper classifies each issue by whether it can be resolved after C++26 ships or whether shipping forecloses the fix.
13+
`std::execution::task` ([P3552R3](https://wg21.link/p3552r3)<sup>[1]</sup>) had open issues identified by national ballot comments, LWG issues, and published papers. Croydon resolved several. This paper classifies each issue by whether it can be resolved after C++26 ships or whether shipping forecloses the fix, and notes which classified issues were addressed at Croydon.
1414

1515
---
1616

1717
## Revision History
1818

19+
### R2: April 2026 (post-Croydon)
20+
21+
* Updated classification to reflect Croydon motions 28-29, 33, 35-38.
22+
Acknowledged issues resolved by P3941R4, P3927R2, P3980R1, and P4151R1.
23+
Rewrote allocator descriptions to credit P3980R1 while preserving
24+
residual frame-allocator concerns.
25+
1926
### R1: March 2026 (prior to Croydon meeting)
2027

2128
* Complete rewrite as an informational classification of open issues.
@@ -42,7 +49,11 @@ This paper asks for nothing.
4249

4350
`task`'s `promise_type` is a class template instantiated in user code. Its `operator new`, allocator selection, stop token storage, environment forwarding, and destruction ordering can change between standard revisions without binary incompatibility. These issues are fixable post-ship: [Unusual Allocator Customisation](https://wg21.link/p3796r1)<sup>[3]</sup>, [Flexible Allocator Position](https://wg21.link/p3796r1)<sup>[3]</sup>, [Shadowing The Environment Allocator](https://wg21.link/p3796r1)<sup>[3]</sup>, [Stop Source Always Created](https://wg21.link/p3796r1)<sup>[3]</sup>, [Stop Token Default Constructible](https://wg21.link/p3796r1)<sup>[3]</sup>, [Task Not Actually Lazily Started](https://wg21.link/p3796r1)<sup>[3]</sup>, [Frame Destroyed Too Late](https://wg21.link/p3796r1)<sup>[3]</sup>, [No Default Arguments](https://wg21.link/p3796r1)<sup>[3]</sup>, [`unhandled_stopped` Not `noexcept`](https://wg21.link/p3796r1)<sup>[3]</sup>, [Environment Design Inefficient](https://wg21.link/p3796r1)<sup>[3]</sup>, [Non-Sender Awaitables Unsupported](https://wg21.link/p3796r1)<sup>[3]</sup>, [Future Language Feature Could Avoid `co_yield`](https://wg21.link/p3796r1)<sup>[3]</sup>, [No TLS Capture/Restore Hook](https://wg21.link/p3796r1)<sup>[3]</sup>, [`return_value`/`return_void` Have No Specification](https://wg21.link/p3796r1)<sup>[3]</sup>, [`co_return { args... }` Unsupported](https://wg21.link/p3796r1)<sup>[3]</sup>, [`change_coroutine_scheduler` Requires Assignable Scheduler](https://wg21.link/p3796r1)<sup>[3]</sup>, [Sender-Unaware Coroutines Cannot `co_await` a `task`](https://wg21.link/p3796r1)<sup>[3]</sup>, [Missing Rvalue Qualification](https://wg21.link/p3796r1)<sup>[3]</sup>, [Parameter Lifetime Is Surprising](https://wg21.link/p3801r0)<sup>[4]</sup>, [No Protection Against Dangling References](https://wg21.link/p3801r0)<sup>[4]</sup>, [`co_yield with_error` Is Clunky](https://wg21.link/p3801r0)<sup>[4]</sup>, [`co_await schedule(sch)` Is an Expensive No-Op](https://wg21.link/p3801r0)<sup>[4]</sup>, [Coroutine Cancellation Is Ad-Hoc](https://wg21.link/p3801r0)<sup>[4]</sup>.
4451

45-
`affine_on` semantics, rescheduling behavior, and algorithm customisation are specification-level concerns. Tightening requirements or adding default implementations does not change any published interface. These issues are fixable post-ship: [`affine_on` Default Implementation Lacks Specification](https://wg21.link/p3796r1)<sup>[3]</sup>, [`affine_on` Semantics Not Clear](https://wg21.link/p3796r1)<sup>[3]</sup>, [`affine_on` Shape May Not Be Correct](https://wg21.link/p3796r1)<sup>[3]</sup>, [`affine_on` Shouldn't Forward Stop Requests](https://wg21.link/p3796r1)<sup>[3]</sup>, [`affine_on` Customisation For Other Senders](https://wg21.link/p3796r1)<sup>[3]</sup>, [Starting a `task` Reschedules Unconditionally](https://wg21.link/p3796r1)<sup>[3]</sup>, [Resuming After a `task` Reschedules Unnecessarily](https://wg21.link/p3796r1)<sup>[3]</sup>, [`bulk` vs. `task_scheduler`](https://wg21.link/p3796r1)<sup>[3]</sup>, [No Completion Scheduler](https://wg21.link/p3796r1)<sup>[3]</sup>, [`with_awaitable_senders` Unused](https://wg21.link/p3796r1)<sup>[3]</sup>.
52+
Of these, Croydon resolved six: Unusual Allocator Customisation, Flexible Allocator Position, and Shadowing The Environment Allocator were addressed by [P3980R1](https://wg21.link/p3980r1)<sup>[5]</sup>; `unhandled_stopped` Not `noexcept`, `change_coroutine_scheduler` Requires Assignable Scheduler (the mechanism was removed entirely), and Missing Rvalue Qualification were addressed by [P3941R4](https://wg21.link/p3941r4)<sup>[15]</sup>. The remaining issues are still open and fixable post-ship.
53+
54+
`affine` semantics (formerly `affine_on`, renamed by [P4151R1](https://wg21.link/p4151r1)<sup>[16]</sup>), rescheduling behavior, and algorithm customization are specification-level concerns. Tightening requirements or adding default implementations does not change any published interface. These issues are fixable post-ship: [`affine_on` Default Implementation Lacks Specification](https://wg21.link/p3796r1)<sup>[3]</sup>, [`affine_on` Semantics Not Clear](https://wg21.link/p3796r1)<sup>[3]</sup>, [`affine_on` Shape May Not Be Correct](https://wg21.link/p3796r1)<sup>[3]</sup>, [`affine_on` Shouldn't Forward Stop Requests](https://wg21.link/p3796r1)<sup>[3]</sup>, [`affine_on` Customisation For Other Senders](https://wg21.link/p3796r1)<sup>[3]</sup>, [Starting a `task` Reschedules Unconditionally](https://wg21.link/p3796r1)<sup>[3]</sup>, [Resuming After a `task` Reschedules Unnecessarily](https://wg21.link/p3796r1)<sup>[3]</sup>, [`bulk` vs. `task_scheduler`](https://wg21.link/p3796r1)<sup>[3]</sup>, [No Completion Scheduler](https://wg21.link/p3796r1)<sup>[3]</sup>, [`with_awaitable_senders` Unused](https://wg21.link/p3796r1)<sup>[3]</sup>.
55+
56+
Of these, Croydon resolved eight. [P3941R4](https://wg21.link/p3941r4)<sup>[15]</sup> rewrote scheduler affinity from scratch - `affine_on` was made unary, `change_coroutine_scheduler` removed, and `get_start_scheduler` introduced - resolving the five `affine_on`/`affine` items and both rescheduling items. [P4151R1](https://wg21.link/p4151r1)<sup>[16]</sup> renamed `affine_on` to `affine`. [P3927R2](https://wg21.link/p3927r2)<sup>[17]</sup> resolved `bulk` vs. `task_scheduler` by giving `task_scheduler` parallel bulk support. Two items remain open: No Completion Scheduler and `with_awaitable_senders` Unused.
4657

4758
---
4859

@@ -52,14 +63,14 @@ The issues in this section are items where shipping forecloses the fix.
5263

5364
| Issue | References | Fixed |
5465
|-----------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-----:|
55-
| Allocator Timing | [P3980R0](https://isocpp.org/files/papers/P3980R0.html)<sup>[5]</sup>, [P3796R1](https://wg21.link/p3796r1)<sup>[3]</sup>, [LWG 4356](https://cplusplus.github.io/LWG/issue4356)<sup>[6]</sup>, [US 254-385](https://github.com/cplusplus/nbballot/issues/960)<sup>[7]</sup> | no |
56-
| Allocator Propagation | [P3980R0](https://isocpp.org/files/papers/P3980R0.html)<sup>[5]</sup>, [P3796R1](https://wg21.link/p3796r1)<sup>[3]</sup> | no |
66+
| Allocator Timing | [P3980R1](https://wg21.link/p3980r1)<sup>[5]</sup>, [P3796R1](https://wg21.link/p3796r1)<sup>[3]</sup>, [LWG 4356](https://cplusplus.github.io/LWG/issue4356)<sup>[6]</sup>, [US 254-385](https://github.com/cplusplus/nbballot/issues/960)<sup>[7]</sup> | partial |
67+
| Allocator Propagation | [P3980R1](https://wg21.link/p3980r1)<sup>[5]</sup>, [P3796R1](https://wg21.link/p3796r1)<sup>[3]</sup> | partial |
5768
| Error Return | [P3950R0](https://wg21.link/p3950r0)<sup>[8]</sup>, [P3801R0](https://wg21.link/p3801r0)<sup>[4]</sup>, [P1713R0](https://wg21.link/p1713r0)<sup>[9]</sup> | no |
5869
| Symmetric Transfer | [P2583R3](https://isocpp.org/files/papers/P2583R3.pdf)<sup>[10]</sup>, [US 246-373](https://github.com/cplusplus/nbballot/issues/948)<sup>[11]</sup>, [LWG 4348](https://cplusplus.github.io/LWG/issue4348)<sup>[12]</sup>, [P3801R0](https://wg21.link/p3801r0)<sup>[4]</sup>, [P3796R1](https://wg21.link/p3796r1)<sup>[3]</sup> | no |
5970

60-
- **Allocator Timing.** `task` does not allow the user to specify an allocator at the launch site for coroutine frame allocation. The coroutine frame is allocated by `operator new` at the call site, before any sender `connect`/`start` machinery runs. The receiver's environment - which carries the allocator - is not yet available at that point. The `allocator_arg` mechanism in [P3552R3](https://wg21.link/p3552r3)<sup>[1]</sup> works around this by requiring the allocator in the coroutine's parameter list, but that locks in a caller-specified approach and forecloses environment-based injection.
71+
- **Allocator Timing.** [P3980R1](https://wg21.link/p3980r1)<sup>[5]</sup> separates frame allocation from environment allocation: the environment allocator is now sourced from `get_allocator(get_env(rcvr))` at `connect` time, resolving environment-based injection. The frame allocator, however, remains call-site-specified via `allocator_arg` in the coroutine parameter list. This is a structural consequence of coroutine allocation timing - the frame is allocated by `operator new` before `connect`/`start` runs, so the receiver's environment is unavailable. Shipping standardizes the two-tier split. A design where frame allocation participates in environment-based propagation is foreclosed without a language change to coroutine allocation.
6172

62-
- **Allocator Propagation.** `task` does not propagate the frame allocator to child tasks. Each child task allocates its frame independently. Shipping without propagation locks in a design where every launch site must specify its allocator explicitly, foreclosing transparent propagation through the coroutine call tree.
73+
- **Allocator Propagation.** [P3980R1](https://wg21.link/p3980r1)<sup>[5]</sup> provides environment allocator propagation: each `task` obtains its environment allocator from `get_allocator(get_env(rcvr))`, so a parent's environment allocator flows to children through the receiver chain. Frame allocator propagation remains absent. Each coroutine call site must independently specify `allocator_arg` to use a non-default frame allocator. In a deep coroutine call tree where frame allocation matters - arena-per-request, pool allocators, device memory - every function signature must carry `allocator_arg` explicitly. Shipping this design forecloses automatic frame allocator propagation through the coroutine call tree.
6374

6475
- **Error Return.** `task` requires `co_yield with_error(e)` to propagate an error to the caller. `co_return` cannot carry an error value because `return_value` and `return_void` are mutually exclusive in the current coroutine specification. Shipping this interface locks in the `co_yield` mechanism and forecloses `co_return`-based error propagation, which would require a language change.
6576

@@ -83,7 +94,7 @@ Papers, issues, and ballot comments referenced in this document.
8394
2. [P4007R0](https://wg21.link/p4007r0) - "Senders and Coroutines" (Vinnie Falco, Mungo Gill, 2026). https://wg21.link/p4007r0
8495
3. [P3796R1](https://wg21.link/p3796r1) - "Coroutine Task Issues" (Dietmar K&uuml;hl, 2025). https://wg21.link/p3796r1
8596
4. [P3801R0](https://wg21.link/p3801r0) - "Concerns about the design of std::execution::task" (Jonathan M&uuml;ller, 2025). https://wg21.link/p3801r0
86-
5. [P3980R0](https://isocpp.org/files/papers/P3980R0.html) - "Task's Allocator Use" (Dietmar K&uuml;hl, 2026). https://isocpp.org/files/papers/P3980R0.html
97+
5. [P3980R1](https://wg21.link/p3980r1) - "Task's Allocator Use" (Dietmar K&uuml;hl, 2026). https://wg21.link/p3980r1
8798
6. [LWG 4356](https://cplusplus.github.io/LWG/issue4356) - "connect() should use get_allocator(get_env(rcvr))". https://cplusplus.github.io/LWG/issue4356
8899
7. [US 254-385](https://github.com/cplusplus/nbballot/issues/960) - C++26 NB ballot comment. https://github.com/cplusplus/nbballot/issues/960
89100
8. [P3950R0](https://wg21.link/p3950r0) - "return_value & return_void Are Not Mutually Exclusive" (Robert Leahy, 2025). https://wg21.link/p3950r0
@@ -97,3 +108,9 @@ Papers, issues, and ballot comments referenced in this document.
97108

98109
14. [C++ Working Draft](https://eel.is/c++draft/) - (Richard Smith, ed.). https://eel.is/c++draft/
99110

111+
### Croydon Papers (R2)
112+
113+
15. [P3941R4](https://wg21.link/p3941r4) - "Scheduler Affinity" (Dietmar K&uuml;hl, 2026). https://wg21.link/p3941r4
114+
16. [P4151R1](https://wg21.link/p4151r1) - "Rename affine_on" (Robert Leahy, 2026). https://wg21.link/p4151r1
115+
17. [P3927R2](https://wg21.link/p3927r2) - "task_scheduler Bulk Execution" (Eric Niebler, 2026). https://wg21.link/p3927r2
116+

0 commit comments

Comments
 (0)