Document number | P0746R0 |
Date | 2017-07-13 |
Project | Programming Language C++, Library Working Group |
Reply-to | Jonathan Wakely <cxx@kayari.org>, Michael McLaughlin <mikebmcl@gmail.com> |
This paper presents proposed changes in response to one of the National Body comments for PDTS 19216 from N4643.
Without knowing more about what kind of executor is being used, a user will have difficulty deciding which of the three functions to use to add a task to an executor. It is preferable to limit the options for adding tasks to a generic executor. Concrete executors can add additional functions if required.
Proposed change: Remove the defer function from executors, as that is the least well-defined. This would match the existing Boost ASIO implementation.
This was discussed by LEWG in Kona and rejected, then discussed again in Toronto due to the P0703R0 paper. LEWG preferred to keep the defer
function but add normative recommendation to distinguish it from post
. The wording below was provided by Michael McLaughlin.
The change is to split the row for post
and defer
into two rows,
with differing normative wording.
The revised wording for post
says "The executor may begin f1
's progress before the call to post
completes."
The revised wording for defer
says "The executor should not begin f1
's progress before the call to defer
completes."
Changes are relative to N4656.
Modify 13.2.2 [async.reqmts.executor] Table 4 as shown:
expression
x1.post(std::move(f), a)
x1.defer(std::move(f), a)
type
[Drafting note: empty cell]
assertion/note pre/post-condition
Effects: Creates an object
f1
initialized withDECAY_COPY
(forward<Func>(f))
in the current thread of execution. Callsf1()
at most once. The executor shall not block forward progress of the caller pending completion off1()
. The executor may begin f1's progress before the call topost
completes. Executor implementations should use the supplied allocator to allocate any memory required to store the function object. Prior to invoking the function object, the executor shall deallocate any memory allocated. [Note: Executors defined in this Technical Specification always use the supplied allocator unless otherwise specified. --end note]
Synchronization: The invocation ofpost
orsynchronizes with (C++Std [intro.multithread]) the invocation ofdefer
f1
.[Note: Although the requirements placed ondefer
are identical topost
, the use ofpost
conveys a preference that the caller does not block the first step off1
's progress, whereasdefer
conveys a preference that the caller does block the first step off1
. One use ofdefer
is to convey the intention of the caller thatf1
is a continuation of the current call context. The executor may use this information to optimize or otherwise adjust the way in whichf1
is invoked. --end note]expression
x1.defer(std::move(f), a)
type
[Drafting note: empty cell]
assertion/note pre/post-condition
Effects: Creates an object
f1
initialized withDECAY_COPY
(forward<Func>(f))
in the current thread of execution. Callsf1()
at most once. The executor shall not block forward progress of the caller pending completion off1()
. The executor should not beginf1
's progress before the call todefer
completes. [Note: One use ofdefer
is to convey the intention of the caller thatf1
is a continuation of the current call context. The executor may use this information to optimize or otherwise adjust the way in whichf1
is invoked. --end note] Executor implementations should use the supplied allocator to allocate any memory required to store the function object. Prior to invoking the function object, the executor shall deallocate any memory allocated. [Note: Executors defined in this Technical Specification always use the supplied allocator unless otherwise specified. --end note]
Synchronization: The invocation ofdefer
synchronizes with (C++Std [intro.multithread]) the invocation off1
.