| 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
f1initialized 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 topostcompletes. 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 ofpostorsynchronizes with (C++Std [intro.multithread]) the invocation ofdeferf1.[Note: Although the requirements placed ondeferare identical topost, the use ofpostconveys a preference that the caller does not block the first step off1's progress, whereasdeferconveys a preference that the caller does block the first step off1. One use ofdeferis to convey the intention of the caller thatf1is a continuation of the current call context. The executor may use this information to optimize or otherwise adjust the way in whichf1is invoked. --end note]expression
x1.defer(std::move(f), a)type
[Drafting note: empty cell]
assertion/note pre/post-condition
Effects: Creates an object
f1initialized 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 todefercompletes. [Note: One use ofdeferis to convey the intention of the caller thatf1is a continuation of the current call context. The executor may use this information to optimize or otherwise adjust the way in whichf1is 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 ofdefersynchronizes with (C++Std [intro.multithread]) the invocation off1.