P3941R2 — Scheduler Affinity
(14 items)
Concurrency Working Group (SG1), Library Evolution Working Group (LEWG), Library Working Group (LWG)
This paper addresses concerns about the affine_on algorithm used by std::execution::task to ensure coroutines resume on the same scheduler after co_await. The key changes proposed are: removing the scheduler parameter from affine_on so it obtains the scheduler from the receiver's environment via get_scheduler (or a new get_start_scheduler query), requiring that schedulers used with affine_on be infallible (only completing with set_value when given an unstoppable stop token), adding a customization mechanism allowing child senders to opt out of rescheduling, and removing change_coroutine_scheduler due to its problematic semantics.
- Section 4, cb7/cb9 transform_sender body — Variable t is declared only as a parameter of the requires-expression and is not in scope in the if constexpr branch body. The return statement return t.affine_on(child, ev); references an undeclared identifier. Appears in both the get_start_scheduler and get_scheduler wording variants. [1]
- Section 4, cb6 impls-for lambda (get_start_scheduler version) — After applying the diff that deletes struck-through data, the lambda parameter list becomes [](const auto&], const auto& child) -- the stray ] produces a syntax error. The comma after data must also be part of the deletion. [2]
- Section 4, cb8 impls-for lambda (get_scheduler version) — Same stray ] syntax error as in the get_start_scheduler variant. Deletion of data must also remove the trailing comma. [3]
- Section 3.3, second paragraph — scheduler(sch) should be schedule(sch). scheduler is a concept, not a callable; the same paragraph correctly uses schedule(sch) one sentence earlier. [4]
- Section 3.3, item 3 (run_loop discussion) — never_stoptoken should be never_stop_token (with underscore). The standard type is never_stop_token per [stoptoken.never]. [5]
- Section 3.5, last paragraph — change_routine_scheduler should be change_coroutine_scheduler. Missing co; the rest of the paper uses the correct spelling. [6]
- Section 3.3, paragraph referencing US 235-363 — used be is a typo for used by. [7]
- Section 3.3, final paragraph before subsection 3.3.1 — expect should be expected. [8]
- Section 3.1, paragraph following the two affine_on call forms — is no moved should be is now moved. [9]
- Introductory paragraph (before Section 1) — Missing word to -- should read is to impose. [10]
- Sections 3.1 and 3.2 — P3718r0 uses lowercase r inconsistent with WG21 convention and with earlier references in the same paper that write P3718R0. [11]
- Section 3.2, ordered list — Both list items are closed with (italic end tag) instead of (list item end tag), producing malformed HTML. [12]
- Section 3.6, final paragraph — LWG issue link text shows only LWG but links to issue 4344. All other LWG issue references in the paper include the full number. Should read LWG4344. [13]
References — Anthropic Citations API
[1]
"The gist of this proposal is impose constraints on `affine_on`"
"The gist of this proposal is impose constraints on `affine_on`"
[2]
"P3718r0 proposed to add this exact requirement to [exec.get.scheduler] which is no moved to this proposal."
"P3718r0 proposed to add this exact requirement to [exec.get.scheduler] which is no moved to this proposal."
[3]
"P3718r0 proposed to add this exact requirement and P3718r0 proposed that `get_scheduler` should be required"
"P3718r0 proposed to add this exact requirement and P3718r0 proposed that `get_scheduler` should be required"
[4]
"if it obtained an operation state `os` from `connect(scheduler(sch), rcvr)`"
"if it obtained an operation state `os` from `connect(scheduler(sch), rcvr)`"
[5]
"it can provide a `never_stoptoken` and this scheduler won't complete with `set_stopped()`"
"it can provide a `never_stoptoken` and this scheduler won't complete with `set_stopped()`"
[6]
"`affine_on` can still guarantee that execution resumes on the expect execution agent"
"`affine_on` can still guarantee that execution resumes on the expect execution agent"
[7]
"clarifies that the scheduling operation used be `affine_on` needs to be always successful."
"clarifies that the scheduling operation used be `affine_on` needs to be always successful."
[8]
"the inherent cost of having the possibility of having `change_routine_scheduler` can't be removed later"
"the inherent cost of having the possibility of having `change_routine_scheduler` can't be removed later"
[9]
"[](const auto&`~~`data`~~`], const auto& child) noexcept -> decltype(auto)"
"[](const auto&`~~`data`~~`], const auto& child) noexcept -> decltype(auto)"
[10]
"[](const auto&`~~`data`~~`], const auto& child) noexcept -> decltype(auto)"
"[](const auto&`~~`data`~~`], const auto& child) noexcept -> decltype(auto)"
[11]
"if constexpr (requires(const child_tag_t& t){ t.affine_on(child, ev); }) / return t.affine_on(child, ev);"
"if constexpr (requires(const child_tag_t& t){ t.affine_on(child, ev); }) / return t.affine_on(child, ev);"
[12]
"if constexpr (requires(const child_tag_t& t){ t.affine_on(child, ev); }) / return t.affine_on(child, ev);"
"if constexpr (requires(const child_tag_t& t){ t.affine_on(child, ev); }) / return t.affine_on(child, ev);"
[13]
"The `get_scheduler` query is used to get a scheduler to schedule new work on. and The `get_scheduler` query is used to get the scheduler an operation was `start`ed on."
"The `get_scheduler` query is used to get a scheduler to schedule new work on. and The `get_scheduler` query is used to get the scheduler an operation was `start`ed on."
[14]
"(LWG; the proposed resolution in this issue is incomplete)"
"(LWG; the proposed resolution in this issue is incomplete)"
Summary: P3941R2 proposes an affine_on sender adaptor that constrains where a sender's completion runs, ensuring execution resumes on the scheduler associated with the sender rather than allowing arbitrary migration. It also addresses related changes to get_start_scheduler, infallible scheduler requirements, and coroutine scheduler integration.
Pipeline: Discovery (Anthropic Opus + Citations API) → Verification Gate (OpenRouter Opus) → Report Writer (OpenRouter Opus)
Provenance: All references are machine-verified character positions from the Anthropic Citations API — deterministic, exact substrings, not model-generated quotes.
Provenance: All references are machine-verified character positions from the Anthropic Citations API — deterministic, exact substrings, not model-generated quotes.