[exec.async.ops] # 33 Execution control library [[exec]](./#exec) ## 33.3 Asynchronous operations [exec.async.ops] [1](#1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L172) An [*execution resource*](#def:resource,execution "33.3 Asynchronous operations [exec.async.ops]") is a program entity that manages a (possibly dynamic) set of execution agents ([[thread.req.lockable.general]](thread.req.lockable.general "32.2.5.1 General")), which it uses to execute parallel work on behalf of callers[.](#1.sentence-1) [*Example [1](#example-1)*: The currently active thread, a system-provided thread pool, and uses of an API associated with an external hardware accelerator are all examples of execution resources[.](#1.sentence-2) — *end example*] Execution resources execute asynchronous operations[.](#1.sentence-3) An execution resource is either valid or invalid[.](#1.sentence-4) [2](#2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L185) An [*asynchronous operation*](#def:operation,asynchronous "33.3 Asynchronous operations [exec.async.ops]") is a distinct unit of program execution that - [(2.1)](#2.1) is explicitly created; - [(2.2)](#2.2) can be explicitly started once at most; - [(2.3)](#2.3) once started, eventually completes exactly once with a (possibly empty) set of result datums and in exactly one of three [*dispositions*](#def:disposition "33.3 Asynchronous operations [exec.async.ops]"): success, failure, or cancellation; * [(2.3.1)](#2.3.1) A successful completion, also known as a [*value completion*](#def:completion,value "33.3 Asynchronous operations [exec.async.ops]"), can have an arbitrary number of result datums[.](#2.3.1.sentence-1) * [(2.3.2)](#2.3.2) A failure completion, also known as an [*error completion*](#def:completion,error "33.3 Asynchronous operations [exec.async.ops]"), has a single result datum[.](#2.3.2.sentence-1) * [(2.3.3)](#2.3.3) A cancellation completion, also known as a [*stopped completion*](#def:completion,stopped "33.3 Asynchronous operations [exec.async.ops]"), has no result datum[.](#2.3.3.sentence-1) An asynchronous operation's [*async result*](#def:result,async "33.3 Asynchronous operations [exec.async.ops]") is its disposition and its (possibly empty) set of result datums[.](#2.3.sentence-2) - [(2.4)](#2.4) can complete on a different execution resource than the execution resource on which it started; and - [(2.5)](#2.5) can create and start other asynchronous operations called [*child operations*](#def:operations,child "33.3 Asynchronous operations [exec.async.ops]")[.](#2.5.sentence-1) A child operation is an asynchronous operation that is created by the parent operation and, if started, completes before the parent operation completes[.](#2.5.sentence-2) A [*parent operation*](#def:operation,parent "33.3 Asynchronous operations [exec.async.ops]") is the asynchronous operation that created a particular child operation[.](#2.5.sentence-3) [*Note [1](#note-1)*: An asynchronous operation can execute synchronously; that is, it can complete during the execution of its start operation on the thread of execution that started it[.](#2.sentence-2) — *end note*] [3](#3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L229) An asynchronous operation has associated state known as its [*operation state*](#def:state,operation "33.3 Asynchronous operations [exec.async.ops]")[.](#3.sentence-1) [4](#4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L233) An asynchronous operation has an associated environment[.](#4.sentence-1) An [*environment*](#def:environment "33.3 Asynchronous operations [exec.async.ops]") is a queryable object ([[exec.queryable]](exec.queryable "33.2 Queries and queryables")) representing the execution-time properties of the operation's caller[.](#4.sentence-2) The caller of an asynchronous operation is its parent operation or the function that created it[.](#4.sentence-3) [5](#5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L240) An asynchronous operation has an associated receiver[.](#5.sentence-1) A [*receiver*](#def:receiver "33.3 Asynchronous operations [exec.async.ops]") is an aggregation of three handlers for the three asynchronous completion dispositions: - [(5.1)](#5.1) a value completion handler for a value completion, - [(5.2)](#5.2) an error completion handler for an error completion, and - [(5.3)](#5.3) a stopped completion handler for a stopped completion[.](#5.sentence-2) A receiver has an associated environment[.](#5.sentence-3) An asynchronous operation's operation state owns the operation's receiver[.](#5.sentence-4) The environment of an asynchronous operation is equal to its receiver's environment[.](#5.sentence-5) [6](#6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L254) For each completion disposition, there is a [*completion function*](#def:function,completion "33.3 Asynchronous operations [exec.async.ops]")[.](#6.sentence-1) A completion function is a customization point object ([[customization.point.object]](customization.point.object "16.3.3.3.5 Customization Point Object types")) that accepts an asynchronous operation's receiver as the first argument and the result datums of the asynchronous operation as additional arguments[.](#6.sentence-2) The value completion function invokes the receiver's value completion handler with the value result datums; likewise for the error completion function and the stopped completion function[.](#6.sentence-3) A completion function has an associated type known as its [*completion tag*](#def:tag,completion "33.3 Asynchronous operations [exec.async.ops]") that is the unqualified type of the completion function[.](#6.sentence-4) A valid invocation of a completion function is called a [*completion operation*](#def:operation,completion "33.3 Asynchronous operations [exec.async.ops]")[.](#6.sentence-5) [7](#7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L269) The [*lifetime of an asynchronous operation*](#def:lifetime_of_an_asynchronous_operation "33.3 Asynchronous operations [exec.async.ops]"), also known as the operation's [*async lifetime*](#def:async_lifetime "33.3 Asynchronous operations [exec.async.ops]"), begins when its start operation begins executing and ends when its completion operation begins executing[.](#7.sentence-1) If the lifetime of an asynchronous operation's associated operation state ends before the lifetime of the asynchronous operation, the behavior is undefined[.](#7.sentence-2) After an asynchronous operation executes a completion operation, its associated operation state is invalid[.](#7.sentence-3) Accessing any part of an invalid operation state is undefined behavior[.](#7.sentence-4) [8](#8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L281) An asynchronous operation shall not execute a completion operation before its start operation has begun executing[.](#8.sentence-1) After its start operation has begun executing, exactly one completion operation shall execute[.](#8.sentence-2) The lifetime of an asynchronous operation's operation state can end during the execution of the completion operation[.](#8.sentence-3) [9](#9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L289) A [*sender*](#def:sender "33.3 Asynchronous operations [exec.async.ops]") is a factory for one or more asynchronous operations[.](#9.sentence-1) [*Connecting*](#def:connect "33.3 Asynchronous operations [exec.async.ops]") a sender and a receiver creates an asynchronous operation[.](#9.sentence-2) The asynchronous operation's associated receiver is equal to the receiver used to create it, and its associated environment is equal to the environment associated with the receiver used to create it[.](#9.sentence-3) The lifetime of an asynchronous operation's associated operation state does not depend on the lifetimes of either the sender or the receiver from which it was created[.](#9.sentence-4) A sender is started when it is connected to a receiver and the resulting asynchronous operation is started[.](#9.sentence-5) A sender's async result is the async result of the asynchronous operation created by connecting it to a receiver[.](#9.sentence-6) A sender sends its results by way of the asynchronous operation(s) it produces, and a receiver receives those results[.](#9.sentence-7) A sender is either valid or invalid; it becomes invalid when its parent sender (see below) becomes invalid[.](#9.sentence-8) [10](#10) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L309) A [*scheduler*](#def:scheduler "33.3 Asynchronous operations [exec.async.ops]") is an abstraction of an execution resource with a uniform, generic interface for scheduling work onto that resource[.](#10.sentence-1) It is a factory for senders whose asynchronous operations execute value completion operations on an execution agent belonging to the scheduler's associated execution resource[.](#10.sentence-2) A [*schedule-expression*](#def:schedule-expression "33.3 Asynchronous operations [exec.async.ops]") obtains such a sender from a scheduler[.](#10.sentence-3) A [*schedule sender*](#def:schedule_sender "33.3 Asynchronous operations [exec.async.ops]") is the result of a schedule expression[.](#10.sentence-4) On success, an asynchronous operation produced by a schedule sender executes a value completion operation with an empty set of result datums[.](#10.sentence-5) Multiple schedulers can refer to the same execution resource[.](#10.sentence-6) A scheduler can be valid or invalid[.](#10.sentence-7) A scheduler becomes invalid when the execution resource to which it refers becomes invalid, as do any schedule senders obtained from the scheduler, and any operation states obtained from those senders[.](#10.sentence-8) [11](#11) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L327) An asynchronous operation has one or more associated completion schedulers for each of its possible dispositions[.](#11.sentence-1) A [*completion scheduler*](#def:completion_scheduler "33.3 Asynchronous operations [exec.async.ops]") is a scheduler whose associated execution resource is used to execute a completion operation for an asynchronous operation[.](#11.sentence-2) A value completion scheduler is a scheduler on which an asynchronous operation's value completion operation can execute[.](#11.sentence-3) Likewise for error completion schedulers and stopped completion schedulers[.](#11.sentence-4) [12](#12) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L337) A sender has an associated queryable object ([[exec.queryable]](exec.queryable "33.2 Queries and queryables")) known as its [*attributes*](#def:attribute "33.3 Asynchronous operations [exec.async.ops]") that describes various characteristics of the sender and of the asynchronous operation(s) it produces[.](#12.sentence-1) For each disposition, there is a query object for reading the associated completion scheduler from a sender's attributes; i.e., a value completion scheduler query object for reading a sender's value completion scheduler, etc[.](#12.sentence-2) If a completion scheduler query is well-formed, the returned completion scheduler is unique for that disposition for any asynchronous operation the sender creates[.](#12.sentence-3) A schedule sender is required to have a value completion scheduler attribute whose value is equal to the scheduler that produced the schedule sender[.](#12.sentence-4) [13](#13) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L353) A [*completion signature*](#def:completion_signature "33.3 Asynchronous operations [exec.async.ops]") is a function type that describes a completion operation[.](#13.sentence-1) An asynchronous operation has a finite set of possible completion signatures corresponding to the completion operations that the asynchronous operation potentially evaluates ([[basic.def.odr]](basic.def.odr "6.3 One-definition rule"))[.](#13.sentence-2) For a completion function set, receiver rcvr, and pack of arguments args, let c be the completion operation set(rcvr, args...), and let F be the function type decltype(auto(set))(decltype((args))...)[.](#13.sentence-3) A completion signature Sig is associated with c if and only if*MATCHING-SIG*(Sig, F) is true ([[exec.general]](exec.general "33.1 General"))[.](#13.sentence-4) Together, a sender type and an environment type Env determine the set of completion signatures of an asynchronous operation that results from connecting the sender with a receiver that has an environment of type Env[.](#13.sentence-5) The type of the receiver does not affect an asynchronous operation's completion signatures, only the type of the receiver's environment[.](#13.sentence-6) A [*non-dependent sender*](#def:sender,non-dependent "33.3 Asynchronous operations [exec.async.ops]") is a sender type whose completion signatures are knowable independent of an execution environment[.](#13.sentence-7) [14](#14) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L379) A sender algorithm is a function that takes and/or returns a sender[.](#14.sentence-1) There are three categories of sender algorithms: - [(14.1)](#14.1) A [*sender factory*](#def:sender_factory "33.3 Asynchronous operations [exec.async.ops]") is a function that takes non-senders as arguments and that returns a sender[.](#14.1.sentence-1) - [(14.2)](#14.2) A [*sender adaptor*](#def:sender_adaptor "33.3 Asynchronous operations [exec.async.ops]") is a function that constructs and returns a parent sender from a set of one or more child senders and a (possibly empty) set of additional arguments[.](#14.2.sentence-1) An asynchronous operation created by a parent sender is a parent operation to the child operations created by the child senders[.](#14.2.sentence-2) - [(14.3)](#14.3) A [*sender consumer*](#def:sender_consumer "33.3 Asynchronous operations [exec.async.ops]") is a function that takes one or more senders and a (possibly empty) set of additional arguments, and whose return type is not the type of a sender[.](#14.3.sentence-1)