From Jason Turner

[futures.async]

Diff to HTML by rtfpessoa

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