From Jason Turner

[futures.async]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmphkkqr84b/{from.md → to.md} +46 -56
tmp/tmphkkqr84b/{from.md → to.md} RENAMED
@@ -14,82 +14,64 @@ template<class F, class... Args>
14
  ```
15
 
16
  *Mandates:* The following are all `true`:
17
 
18
  - `is_constructible_v<decay_t<F>, F>`,
19
- - `(is_constructible_v<decay_t<Args>, Args> &&...)`,
20
- - `is_move_constructible_v<decay_t<F>>`,
21
- - `(is_move_constructible_v<decay_t<Args>> &&...)`, and
22
  - `is_invocable_v<decay_t<F>, decay_t<Args>...>`.
23
 
24
- *Preconditions:* `decay_t<F>` and each type in `decay_t<Args>` meet the
25
- *Cpp17MoveConstructible* requirements.
26
-
27
  *Effects:* The first function behaves the same as a call to the second
28
  function with a `policy` argument of `launch::async | launch::deferred`
29
  and the same arguments for `F` and `Args`. The second function creates a
30
  shared state that is associated with the returned `future` object. The
31
  further behavior of the second function depends on the `policy` argument
32
  as follows (if more than one of these conditions applies, the
33
  implementation may choose any of the corresponding policies):
34
 
35
  - If `launch::async` is set in `policy`, calls
36
- `invoke(`*`decay-copy`*`(std::forward<F>(f)),`
37
- *decay-copy*(std::forward\<Args\>(args))...) ([[func.require]],
38
- [[thread.thread.constr]]) as if in a new thread of execution
39
- represented by a `thread` object with the calls to *`decay-copy`*
40
- being evaluated in the thread that called `async`. Any return value is
41
- stored as the result in the shared state. Any exception propagated
42
- from the execution of
43
- `invoke(`*`decay-copy`*`(std::forward<F>(f)), `*`decay-copy`*`(std::forward<Args>(args))...)`
44
  is stored as the exceptional result in the shared state. The `thread`
45
  object is stored in the shared state and affects the behavior of any
46
  asynchronous return objects that reference that state.
47
  - If `launch::deferred` is set in `policy`, stores
48
- *decay-copy*(std::forward\<F\>(f)) and
49
- *decay-copy*(std::forward\<Args\>(args))... in the shared state. These
50
- copies of `f` and `args` constitute a *deferred function*. Invocation
51
- of the deferred function evaluates
52
  `invoke(std::move(g), std::move(xyz))` where `g` is the stored value
53
- of *decay-copy*(std::forward\<F\>(f)) and `xyz` is the stored copy of
54
- *decay-copy*(std::forward\<Args\>(args)).... Any return value is
55
- stored as the result in the shared state. Any exception propagated
56
- from the execution of the deferred function is stored as the
57
- exceptional result in the shared state. The shared state is not made
58
- ready until the function has completed. The first call to a non-timed
59
- waiting function [[futures.state]] on an asynchronous return object
60
- referring to this shared state invokes the deferred function in the
61
- thread that called the waiting function. Once evaluation of
62
  `invoke(std::move(g), std::move(xyz))` begins, the function is no
63
- longer considered deferred. \[*Note 1*: If this policy is specified
64
- together with other policies, such as when using a `policy` value of
65
- `launch::async | launch::deferred`, implementations should defer
66
- invocation or the selection of the policy when no more concurrency can
67
- be effectively exploited. — *end note*]
68
  - If no value is set in the launch policy, or a value is set that is
69
  neither specified in this document nor by the implementation, the
70
  behavior is undefined.
71
 
72
- *Returns:* An object of type
73
- `future<invoke_result_t<decay_t<F>, decay_t<Args>...>``>` that refers to
74
- the shared state created by this call to `async`.
75
 
76
- [*Note 1*: If a future obtained from `async` is moved outside the local
77
- scope, other code that uses the future should be aware that the future’s
78
- destructor can block for the shared state to become
79
- ready. — *end note*]
80
-
81
- *Synchronization:* Regardless of the provided `policy` argument,
82
-
83
- - the invocation of `async` synchronizes with [[intro.multithread]] the
84
- invocation of `f`. \[*Note 2*: This statement applies even when the
85
- corresponding `future` object is moved to another
86
- thread. — *end note*] ; and
87
- - the completion of the function `f` is sequenced
88
- before [[intro.multithread]] the shared state is made ready.
89
- \[*Note 3*: `f` might not be called at all, so its completion might
90
- never happen. — *end note*]
91
 
92
  If the implementation chooses the `launch::async` policy,
93
 
94
  - a call to a waiting function on an asynchronous return object that
95
  shares the shared state created by this `async` call shall block until
@@ -99,20 +81,28 @@ If the implementation chooses the `launch::async` policy,
99
  with [[intro.multithread]] the return from the first function that
100
  successfully detects the ready status of the shared state or with the
101
  return from the last function that releases the shared state,
102
  whichever happens first.
103
 
 
 
 
 
 
 
 
 
104
  *Throws:* `system_error` if `policy == launch::async` and the
105
  implementation is unable to start a new thread, or `std::bad_alloc` if
106
- memory for the internal data structures could not be allocated.
107
 
108
  *Error conditions:*
109
 
110
  - `resource_unavailable_try_again` — if `policy == launch::async` and
111
  the system is unable to start a new thread.
112
 
113
- [*Note 4*: Line \#1 might not result in concurrency because the `async`
114
- call uses the default policy, which may use `launch::deferred`, in which
115
- case the lambda might not be invoked until the `get()` call; in that
116
- case, `work1` and `work2` are called on the same thread and there is no
117
- concurrency. — *end note*]
118
 
 
14
  ```
15
 
16
  *Mandates:* The following are all `true`:
17
 
18
  - `is_constructible_v<decay_t<F>, F>`,
19
+ - `(is_constructible_v<decay_t<Args>, Args> && ...)`, and
 
 
20
  - `is_invocable_v<decay_t<F>, decay_t<Args>...>`.
21
 
 
 
 
22
  *Effects:* The first function behaves the same as a call to the second
23
  function with a `policy` argument of `launch::async | launch::deferred`
24
  and the same arguments for `F` and `Args`. The second function creates a
25
  shared state that is associated with the returned `future` object. The
26
  further behavior of the second function depends on the `policy` argument
27
  as follows (if more than one of these conditions applies, the
28
  implementation may choose any of the corresponding policies):
29
 
30
  - If `launch::async` is set in `policy`, calls
31
+ `invoke(auto(std::forward<F>(f)), auto(std::forward<Args>(args))...)`
32
+ [[func.invoke]], [[thread.thread.constr]] as if in a new thread of
33
+ execution represented by a `thread` object with the values produced by
34
+ `auto` being materialized [[conv.rval]] in the thread that called
35
+ `async`. Any return value is stored as the result in the shared state.
36
+ Any exception propagated from the execution of
37
+ `invoke(auto(std::forward<F>(f)), auto(std::forward<Args>(args))...)`
 
38
  is stored as the exceptional result in the shared state. The `thread`
39
  object is stored in the shared state and affects the behavior of any
40
  asynchronous return objects that reference that state.
41
  - If `launch::deferred` is set in `policy`, stores
42
+ `auto(std::forward<F>(f))` and `auto(std::forward<Args>(args))...` in
43
+ the shared state. These copies of `f` and `args` constitute a
44
+ *deferred function*. Invocation of the deferred function evaluates
 
45
  `invoke(std::move(g), std::move(xyz))` where `g` is the stored value
46
+ of `auto(std::forward<F>(f))` and `xyz` is the stored copy of
47
+ `auto(std::forward<Args>(args))...`. Any return value is stored as the
48
+ result in the shared state. Any exception propagated from the
49
+ execution of the deferred function is stored as the exceptional result
50
+ in the shared state. The shared state is not made ready until the
51
+ function has completed. The first call to a non-timed waiting
52
+ function [[futures.state]] on an asynchronous return object referring
53
+ to this shared state invokes the deferred function in the thread that
54
+ called the waiting function. Once evaluation of
55
  `invoke(std::move(g), std::move(xyz))` begins, the function is no
56
+ longer considered deferred. *Recommended practice:* If this policy is
57
+ specified together with other policies, such as when using a `policy`
58
+ value of `launch::async | launch::deferred`, implementations should
59
+ defer invocation or the selection of the policy when no more
60
+ concurrency can be effectively exploited.
61
  - If no value is set in the launch policy, or a value is set that is
62
  neither specified in this document nor by the implementation, the
63
  behavior is undefined.
64
 
65
+ *Synchronization:* The invocation of `async` synchronizes with the
66
+ invocation of `f`. The completion of the function `f` is sequenced
67
+ before the shared state is made ready.
68
 
69
+ [*Note 1*: These apply regardless of the provided `policy` argument,
70
+ and even if the corresponding `future` object is moved to another
71
+ thread. However, it is possible for `f` not to be called at all, in
72
+ which case its completion never happens. — *end note*]
 
 
 
 
 
 
 
 
 
 
 
73
 
74
  If the implementation chooses the `launch::async` policy,
75
 
76
  - a call to a waiting function on an asynchronous return object that
77
  shares the shared state created by this `async` call shall block until
 
81
  with [[intro.multithread]] the return from the first function that
82
  successfully detects the ready status of the shared state or with the
83
  return from the last function that releases the shared state,
84
  whichever happens first.
85
 
86
+ *Returns:* An object of type
87
+ `future<invoke_result_t<decay_t<F>, decay_t<Args>...>>` that refers to
88
+ the shared state created by this call to `async`.
89
+
90
+ [*Note 2*: If a future obtained from `async` is moved outside the local
91
+ scope, the future’s destructor can block for the shared state to become
92
+ ready. — *end note*]
93
+
94
  *Throws:* `system_error` if `policy == launch::async` and the
95
  implementation is unable to start a new thread, or `std::bad_alloc` if
96
+ memory for the internal data structures cannot be allocated.
97
 
98
  *Error conditions:*
99
 
100
  - `resource_unavailable_try_again` — if `policy == launch::async` and
101
  the system is unable to start a new thread.
102
 
103
+ [*Note 1*: Line \#1 might not result in concurrency because the `async`
104
+ call uses the default policy, which might use `launch::deferred`, in
105
+ which case the lambda might not be invoked until the `get()` call; in
106
+ that case, `work1` and `work2` are called on the same thread and there
107
+ is no concurrency. — *end note*]
108