Line | % of fetches | Source |
---|---|---|
1 | // Copyright (c) 2007-2015 Hartmut Kaiser | |
2 | // Copyright (c) 2016 Thomas Heller | |
3 | // Copyright (c) 2011 Bryce Adelstein-Lelbach | |
4 | // | |
5 | // Distributed under the Boost Software License, Version 1.0. (See accompanying | |
6 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
7 | ||
8 | #ifndef HPX_LCOS_PROMISE_HPP | |
9 | #define HPX_LCOS_PROMISE_HPP | |
10 | ||
11 | #include <hpx/config.hpp> | |
12 | #include <hpx/lcos/detail/promise_base.hpp> | |
13 | ||
14 | #include <boost/exception_ptr.hpp> | |
15 | ||
16 | #include <utility> | |
17 | ||
18 | namespace hpx { | |
19 | namespace lcos { | |
20 | /////////////////////////////////////////////////////////////////////////// | |
21 | /// A promise can be used by a single \a thread to invoke a | |
22 | /// (remote) action and wait for the result. The result is expected to be | |
23 | /// sent back to the promise using the LCO's set_event action | |
24 | /// | |
25 | /// A promise is one of the simplest synchronization primitives | |
26 | /// provided by HPX. It allows to synchronize on a eager evaluated remote | |
27 | /// operation returning a result of the type \a Result. The \a promise | |
28 | /// allows to synchronize exactly one \a thread (the one passed during | |
29 | /// construction time). | |
30 | /// | |
31 | /// \code | |
32 | /// // Create the promise (the expected result is a id_type) | |
33 | /// lcos::promise<naming::id_type> p; | |
34 | /// | |
35 | /// // Get the associated future | |
36 | /// future<naming::id_type> f = p.get_future(); | |
37 | /// | |
38 | /// // initiate the action supplying the promise as a | |
39 | /// // continuation | |
40 | /// apply<some_action>(new continuation(p.get_id()), ...); | |
41 | /// | |
42 | /// // Wait for the result to be returned, yielding control | |
43 | /// // in the meantime. | |
44 | /// naming::id_type result = f.get(); | |
45 | /// // ... | |
46 | /// \endcode | |
47 | /// | |
48 | /// \tparam Result The template parameter \a Result defines the type this | |
49 | /// promise is expected to return from | |
50 | /// \a promise#get. | |
51 | /// \tparam RemoteResult The template parameter \a RemoteResult defines the | |
52 | /// type this promise is expected to receive | |
53 | /// from the remote action. | |
54 | /// | |
55 | /// \note The action executed by the promise must return a value | |
56 | /// of a type convertible to the type as specified by the | |
57 | /// template parameter \a RemoteResult | |
58 | /////////////////////////////////////////////////////////////////////////// | |
59 | template <typename Result, typename RemoteResult> | |
60 | class promise | |
61 | : public detail::promise_base< | |
62 | Result, RemoteResult, detail::promise_data<Result> > | |
63 | { | |
64 | HPX_MOVABLE_ONLY(promise); | |
65 | ||
66 | typedef detail::promise_base< | |
67 | Result, RemoteResult, detail::promise_data<Result> | |
68 | > base_type; | |
69 | ||
70 | public: | |
71 | // Effects: constructs a promise object and a shared state. | |
72 | promise() | |
73 | : base_type() | |
74 | {} | |
75 | ||
76 | // Effects: constructs a new promise object and transfers ownership of | |
77 | // the shared state of other (if any) to the newly- | |
78 | // constructed object. | |
79 | // Postcondition: other has no shared state. | |
80 | promise(promise&& other) HPX_NOEXCEPT : base_type(std::move(other)) | |
81 | {} | |
82 | ||
83 | // Effects: Abandons any shared state | |
84 | ~promise() | |
85 | { | |
86 | } | |
87 | ||
88 | // Effects: Abandons any shared state (30.6.4) and then as if | |
89 | // promise(std::move(other)).swap(*this). | |
90 | // Returns: *this. | |
91 | promise& operator=(promise&& other) HPX_NOEXCEPT | |
92 | { | |
93 | base_type::operator=(std::move(other)); | |
94 | return *this; | |
95 | } | |
96 | ||
97 | // Effects: Exchanges the shared state of *this and other. | |
98 | // Postcondition: *this has the shared state (if any) that other had | |
99 | // prior to the call to swap. other has the shared state | |
100 | // (if any) that *this had prior to the call to swap. | |
101 | void swap(promise& other) HPX_NOEXCEPT | |
102 | { | |
103 | base_type::swap(other); | |
104 | } | |
105 | ||
106 | // Returns: true only if *this refers to a shared state. | |
107 | using base_type::valid; | |
108 | ||
109 | // Returns: A future<Result> object with the same shared state as *this. | |
110 | // Throws: future_error if *this has no shared state or if get_future | |
111 | // has already been called on a promise with the same shared | |
112 | // state as *this. | |
113 | // Error conditions: | |
114 | // - future_already_retrieved if get_future has already been called | |
115 | // on a promise with the same shared state as *this. | |
116 | // - no_state if *this has no shared state. | |
117 | using base_type::get_future; | |
118 | ||
119 | // Effects: atomically stores the value r in the shared state and makes | |
120 | // that state ready (30.6.4). | |
121 | // Throws: | |
122 | // - future_error if its shared state already has a stored value or | |
123 | // exception. | |
124 | // Error conditions: | |
125 | // - promise_already_satisfied if its shared state already has a | |
126 | // stored value or exception. | |
127 | // - no_state if *this has no shared state. | |
128 | using base_type::set_value; | |
129 | ||
130 | // Effects: atomically stores the exception pointer p in the shared | |
131 | // state and makes that state ready (30.6.4). | |
132 | // Throws: future_error if its shared state already has a stored value | |
133 | // or exception. | |
134 | // Error conditions: | |
135 | // - promise_already_satisfied if its shared state already has a | |
136 | // stored value or exception. | |
137 | // - no_state if *this has no shared state. | |
138 | using base_type::set_exception; | |
139 | }; | |
140 | ||
141 | template <> | |
142 | class promise<void, hpx::util::unused_type> | |
143 | : public detail::promise_base< | |
144 | void, hpx::util::unused_type, detail::promise_data<void> > | |
145 | { | |
146 | HPX_MOVABLE_ONLY(promise); | |
147 | ||
148 | typedef detail::promise_base< | |
149 | void, hpx::util::unused_type, detail::promise_data<void> | |
150 | > base_type; | |
151 | ||
152 | public: | |
153 | // Effects: constructs a promise object and a shared state. | |
154 | promise() | |
155 | : base_type() | |
156 | {} | |
157 | ||
158 | // Effects: constructs a new promise object and transfers ownership of | |
159 | // the shared state of other (if any) to the newly- | |
160 | // constructed object. | |
161 | // Postcondition: other has no shared state. | |
162 | promise(promise&& other) HPX_NOEXCEPT : base_type(std::move(other)) | |
163 | {} | |
164 | ||
165 | // Effects: Abandons any shared state | |
166 | ~promise() | |
167 | {} | |
168 | ||
169 | // Effects: Abandons any shared state (30.6.4) and then as if | |
170 | // promise(std::move(other)).swap(*this). | |
171 | // Returns: *this. | |
172 | promise& operator=(promise&& other) HPX_NOEXCEPT | |
173 | { | |
174 | base_type::operator=(std::move(other)); | |
175 | return *this; | |
176 | } | |
177 | ||
178 | // Effects: Exchanges the shared state of *this and other. | |
179 | // Postcondition: *this has the shared state (if any) that other had | |
180 | // prior to the call to swap. other has the shared state | |
181 | // (if any) that *this had prior to the call to swap. | |
182 | void swap(promise& other) HPX_NOEXCEPT | |
183 | { | |
184 | base_type::swap(other); | |
185 | } | |
186 | ||
187 | // Returns: true only if *this refers to a shared state. | |
188 | using base_type::valid; | |
189 | ||
190 | // Returns: A future<Result> object with the same shared state as *this. | |
191 | // Throws: future_error if *this has no shared state or if get_future | |
192 | // has already been called on a promise with the same shared | |
193 | // state as *this. | |
194 | // Error conditions: | |
195 | // - future_already_retrieved if get_future has already been called | |
196 | // on a promise with the same shared state as *this. | |
197 | // - no_state if *this has no shared state. | |
198 | using base_type::get_future; | |
199 | ||
200 | // Effects: atomically stores the value r in the shared state and makes | |
201 | // that state ready (30.6.4). | |
202 | // Throws: | |
203 | // - future_error if its shared state already has a stored value or | |
204 | // exception, or | |
205 | // - any exception thrown by the constructor selected to copy an | |
206 | // object of R. | |
207 | // Error conditions: | |
208 | // - promise_already_satisfied if its shared state already has a | |
209 | // stored value or exception. | |
210 | // - no_state if *this has no shared state. | |
211 | void set_value(error_code& ec = throws) | |
212 | { | |
213 | base_type::set_value(hpx::util::unused, ec); | |
214 | } | |
215 | ||
216 | // Effects: atomically stores the exception pointer p in the shared | |
217 | // state and makes that state ready (30.6.4). | |
218 | // Throws: future_error if its shared state already has a stored value | |
219 | // or exception. | |
220 | // Error conditions: | |
221 | // - promise_already_satisfied if its shared state already has a | |
222 | // stored value or exception. | |
223 | // - no_state if *this has no shared state. | |
224 | using base_type::set_exception; | |
225 | }; | |
226 | ||
227 | template <typename Result, typename RemoteResult> | |
228 | void swap(promise<Result, RemoteResult>& x, | |
229 | promise<Result, RemoteResult>& y) HPX_NOEXCEPT | |
230 | { | |
231 | x.swap(y); | |
232 | } | |
233 | }} | |
234 | ||
235 | #endif /*HPX_LCOS_PROMISE_HPP*/ | |
236 |
Copyright (c) 2006-2012 Rogue Wave Software, Inc. All Rights Reserved.
Patents pending.