This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of New status.
task's stop source is always createdSection: 33.13.6.5 [task.promise] Status: New Submitter: Dietmar Kühl Opened: 2025-09-01 Last modified: 2026-03-23
Priority: 2
View other active issues in [task.promise].
View all other issues in [task.promise].
View all issues with New status.
Discussion:
Addresses US 257-382
The type task<...>::promise_type has exposition-only
members source and token.
These can be interpreted as always existing which would be a
performance issue for former and an unnecessary constraints for the
latter (because stop tokens aren't required to be default constructible).
The intent is that the stop token obtained from the
get_stop_token query of the receiver's environment is
used. Only if this type is different from the task's
stop_token_type a stop source of type
stop_source_type needs to be created when the
get_stop_token query is used on the promise type's
environment. The stop token doesn't need to be stored at all: it
can either be obtained from the receiver's environment or from the
stop source. The fix is to show the stop source as an optionally
present member of of the operation state and it should be of type
std::optional<stop_source_type> to imply that
it is only created when accessed.
[2025-10-17; Reflector poll.]
Set priority to 2 after reflector poll.
Proposed resolution:
This wording is relative to N5032.
Change the synopsis in 33.13.6.4 [task.state] to include an optional<stop_source_type> member
and an exposition-only function to get a stop token:
namespace std::execution {
template<class T, class Environment>
template<receiver Rcvr>
class task<T, Environment>::state { // exposition only
public:
using operation_state_concept = operation_state_t;
template<class R>
state(coroutine_handle<promise_type> h, R&& rr);
~state();
void start() & noexcept;
stop_token_type get-stop-token(); // exposition only
private:
using own-env-t = see below; // exposition only
coroutine_handle<promise_type> handle; // exposition only
remove_cvref_t<Rcvr> rcvr; // exposition only
optional<stop_source_type> source; // exposition only
own-env-t own-env; // exposition only
Environment environment; // exposition only
};
}
In 33.13.6.4 [task.state] change paragraph 4 into two paragraphs:
one for start() and one for get-stop-token()
such that the initialization of source is in
the second paragraph:
void start() & noexcept;-4- Effects: Let
prombe the objecthandle.promise(). AssociatesSTATE(prom),RCVR(prom), andSCHED(prom)with *this as follows:-4.1- --
STATE(prom)is*this.-4.2- --
RCVR(prom)isrcvr.-4.3- --
SCHED(prom)is the object initialized withscheduler_type(get_scheduler(get_env(rcvr)))if that expression is valid andscheduler_type()otherwise. If neither of these expressions is valid, the program is ill-formed.
Letstbeget_stop_token(get_env(rcvr)). Initializesprom.tokenandprom.sourcesuch that
-4.4- --;prom.token.stop_requested()returnsst.stop_requested()
-4.5- --prom.token.stop_possible()returnsst.stop_possible(); and
-4.6- -- for typesFnandInitsuch that bothinvocable<Fn>andconstructible_from<Fn, Init> are modeled,stop_token_type::callback_type<Fn> modelsstoppable-callback-for<Fn, stop_token_type, Init>.-5- After that invokes
handle.resume().stop_token_type get-stop-token();-6- Effects: If
same_as<decltype(declval<stop_source_type>().get_token()), decltype(get_stop_token(get_env(rcvr)))>istruereturnsget_stop_token(get_env(rcvr)). Otherwise, ifsource.has_value()isfalse, initializessourcesuch that
- -6.1- --
source->stop_requested()returnsget_stop_token(get_env(rcvr))->stop_requested(); and- -6.2- --
source->stop_possible()returnsget_stop_token(get_env(rcvr))->stop_possible()Finally, returns
source->get_token().
Remove token and source from the synopsis of promise_type in 33.13.6.5 [task.promise]:
namespace std::execution {
template<class T, class Environment>
class task<T, Environment>::promise_type {
public:
...
private:
using error-variant = see below; // exposition only
allocator_type alloc; // exposition only
stop_source_type source; // exposition only
stop_token_type token; // exposition only
optional<T> result; // exposition only; present only if is_void_v<T> is false
error-variant errors; // exposition only
};
}
Change the specification of get_env in 33.13.6.5 [task.promise] paragraph 16.3 to use STATE(*this).get-stop-token():
unspecified get_env() const noexcept;-16- Returns: An object
envsuch that queries are forwarded as follows:-16.1- --
env.query(get_scheduler)returnsscheduler_type(SCHED(*this)).-16.2- --
env.query(get_allocator)returnsalloc.-16.3- --
env.query(get_stop_token)returnstokenSTATE(*this).get-stop-token().-16.4- -- For any other query
qand argumentsa...a call toenv.query(q, a...)returnsSTATE(*this).if this expression is well-formed andenvironmentienvironment.query(q, a...)forwarding_query(q)is well-formed and istrue. Otherwiseenv.query(q, a...)is ill-formed.