[exec.spawn] # 33 Execution control library [[exec]](./#exec) ## 33.9 Senders [[exec.snd]](exec.snd#exec.spawn) ### 33.9.13 Sender consumers [[exec.consumers]](exec.consumers#exec.spawn) #### 33.9.13.3 execution​::​spawn [exec.spawn] [1](#1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L5843) spawn attempts to associate the given input sender with the given token's async scope and, on success, eagerly starts the input sender[.](#1.sentence-1) [2](#2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L5848) The name spawn denotes a customization point object[.](#2.sentence-1) For subexpressions sndr, token, and env, - [(2.1)](#2.1) let Sndr be decltype((sndr)), - [(2.2)](#2.2) let Token be remove_cvref_t, and - [(2.3)](#2.3) let Env be remove_cvref_t[.](#2.sentence-2) If any of[sender](exec.snd.concepts#concept:sender "33.9.3 Sender concepts [exec.snd.concepts]"),[scope_token](exec.scope.concepts#concept:scope_token "33.14.1 Execution scope concepts [exec.scope.concepts]"), or[*queryable*](exec.queryable.concept#concept:queryable "33.2.2 queryable concept [exec.queryable.concept]") are not satisfied, the expression spawn(​sndr, token, env) is ill-formed[.](#2.sentence-3) [3](#3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L5863) Let *spawn-state-base* be the exposition-only class: [🔗](#lib:execution::spawn-state-base) namespace std::execution {struct *spawn-state-base* { // *exposition only*virtual void *complete*() noexcept = 0; // *exposition only*};} [4](#4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L5875) Let *spawn-receiver* be the exposition-only class: [🔗](#lib:execution::spawn-receiver) namespace std::execution {struct *spawn-receiver* { // *exposition only*using receiver_concept = receiver_t; *spawn-state-base** *state*; // *exposition only*void set_value() && noexcept { *state*->*complete*(); }void set_stopped() && noexcept { *state*->*complete*(); }};} [5](#5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L5891) Let *spawn-state* be the exposition-only class template: [🔗](#lib:execution::spawn-state) namespace std::execution {templatestruct *spawn-state* : *spawn-state-base* { // *exposition only*using *op-t* = connect_result_t; // *exposition only**spawn-state*(Alloc alloc, Sender&& sndr, Token token); // *exposition only*void *complete*() noexcept override; // *exposition only*void *run*(); // *exposition only*private:using *alloc-t* = // *exposition only*typename allocator_traits::template rebind_alloc<*spawn-state*>; *alloc-t* *alloc*; // *exposition only**op-t* *op*; // *exposition only* Token *token*; // *exposition only*void *destroy*() noexcept; // *exposition only*};} [🔗](#lib:execution::spawn-state,constructor) `spawn-state(Alloc alloc, Sender&& sndr, Token token); ` [6](#6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L5924) *Effects*: Initializes*alloc* with alloc,*token* with token, and*op* with:connect(std::move(sndr), *spawn-receiver*(this)) [🔗](#lib:run,execution::spawn-state) `void run(); ` [7](#7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L5941) *Effects*: Equivalent to:if (*token*.try_associate()) start(*op*);else*destroy*(); [🔗](#lib:complete,execution::spawn-state) `void complete() noexcept override; ` [8](#8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L5958) *Effects*: Equivalent to:auto token = std::move(this->*token*); *destroy*(); token.disassociate(); [🔗](#lib:destroy,execution::spawn-state) `void destroy() noexcept; ` [9](#9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L5975) *Effects*: Equivalent to:auto alloc = std::move(this->*alloc*); allocator_traits<*alloc-t*>::destroy(alloc, this); allocator_traits<*alloc-t*>::deallocate(alloc, this, 1); [10](#10) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L5986) For the expression spawn(sndr, token, env) let new_sender be the expression token.wrap(sndr) and let alloc and senv be defined as follows: - [(10.1)](#10.1) if the expression get_allocator(env) is well-formed, thenalloc is the result of get_allocator(env) andsenv is the expression env, - [(10.2)](#10.2) otherwise if the expression get_allocator(get_env(new_sender)) is well-formed, thenalloc is the result of get_allocator(get_env(new_sender)) andsenv is the expression *JOIN-ENV*(prop(get_allocator, alloc), env), - [(10.3)](#10.3) otherwisealloc is allocator() andsenv is the expression env[.](#10.sentence-1) [11](#11) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L6006) The expression spawn(sndr, token, env) is of type void and has the following effects: - [(11.1)](#11.1) Uses alloc to allocate and construct an object o of type that is a specialization of *spawn-state* fromalloc, write_env(token.wrap(sndr), senv), and token and then invokes o.*run*()[.](#11.sentence-1) If an exception is thrown then any constructed objects are destroyed and any allocated memory is deallocated[.](#11.1.sentence-2) [12](#12) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L6021) The expression spawn(sndr, token) is expression-equivalent tospawn(sndr, token, execution​::​env<>(​))[.](#12.sentence-1)