Line | % of fetches | Source |
---|---|---|
1 | // Copyright (c) 2007-2016 Hartmut Kaiser | |
2 | // | |
3 | // Distributed under the Boost Software License, Version 1.0. (See accompanying | |
4 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
5 | ||
6 | #if !defined(HPX_APPLY_IMPLEMENTATIONS_APR_13_2015_0945AM) | |
7 | #define HPX_APPLY_IMPLEMENTATIONS_APR_13_2015_0945AM | |
8 | ||
9 | #include <hpx/config.hpp> | |
10 | #include <hpx/runtime/agas/interface.hpp> | |
11 | #include <hpx/runtime/applier/detail/apply_implementations_fwd.hpp> | |
12 | #include <hpx/runtime/naming/address.hpp> | |
13 | #include <hpx/runtime/naming/id_type.hpp> | |
14 | #include <hpx/runtime/parcelset/parcel.hpp> | |
15 | #include <hpx/runtime_fwd.hpp> | |
16 | #include <hpx/throw_exception.hpp> | |
17 | #include <hpx/traits/action_is_target_valid.hpp> | |
18 | #include <hpx/traits/action_was_object_migrated.hpp> | |
19 | #include <hpx/traits/component_supports_migration.hpp> | |
20 | #include <hpx/traits/is_continuation.hpp> | |
21 | ||
22 | #include <boost/format.hpp> | |
23 | ||
24 | #include <type_traits> | |
25 | #include <utility> | |
26 | ||
27 | namespace hpx { namespace detail | |
28 | { | |
29 | template <typename Action, typename Continuation, typename ...Ts> | |
30 | typename std::enable_if< | |
31 | traits::is_continuation<Continuation>::value, bool | |
32 | >::type | |
33 | apply_impl(Continuation && c, hpx::id_type const& id, | |
34 | threads::thread_priority priority, Ts&&... vs) | |
35 | { | |
36 | if (!traits::action_is_target_valid<Action>::call(id)) { | |
37 | HPX_THROW_EXCEPTION(bad_parameter, "hpx::detail::apply_impl", | |
38 | boost::str(boost::format( | |
39 | "the target (destination) does not match the action type (%s)" | |
40 | ) % hpx::actions::detail::get_action_name<Action>())); | |
41 | return false; | |
42 | } | |
43 | ||
44 | std::pair<bool, components::pinned_ptr> r; | |
45 | ||
46 | // Determine whether the id is local or remote | |
47 | naming::address addr; | |
48 | if (agas::is_local_address_cached(id, addr)) | |
49 | { | |
50 | typedef typename Action::component_type component_type; | |
51 | if (traits::component_supports_migration<component_type>::call()) | |
52 | { | |
53 | r = traits::action_was_object_migrated<Action>::call( | |
54 | id, addr.address_); | |
55 | if (!r.first) | |
56 | { | |
57 | return applier::detail::apply_l_p<Action>( | |
58 | std::forward<Continuation>(c), id, std::move(addr), | |
59 | priority, std::forward<Ts>(vs)...); | |
60 | } | |
61 | } | |
62 | else | |
63 | { | |
64 | return applier::detail::apply_l_p<Action>( | |
65 | std::forward<Continuation>(c), id, std::move(addr), | |
66 | priority, std::forward<Ts>(vs)...); | |
67 | } | |
68 | } | |
69 | ||
70 | // apply remotely | |
71 | return applier::detail::apply_r_p<Action>(std::move(addr), | |
72 | std::forward<Continuation>(c), id, priority, std::forward<Ts>(vs)...); | |
73 | } | |
74 | template <typename Action, typename Continuation, typename ...Ts> | |
75 | typename std::enable_if< | |
76 | traits::is_continuation<Continuation>::value, bool | |
77 | >::type | |
78 | apply_impl(Continuation && c, hpx::id_type const& id, naming::address&& addr, | |
79 | threads::thread_priority priority, Ts&&... vs) | |
80 | { | |
81 | // Determine whether the id is local or remote | |
82 | if(addr) | |
83 | { | |
84 | if (!traits::action_is_target_valid<Action>::call(id)) { | |
85 | HPX_THROW_EXCEPTION(bad_parameter, "hpx::detail::apply_impl", | |
86 | boost::str(boost::format( | |
87 | "the target (destination) does not match the action type (%s)" | |
88 | ) % hpx::actions::detail::get_action_name<Action>())); | |
89 | return false; | |
90 | } | |
91 | ||
92 | std::pair<bool, components::pinned_ptr> r; | |
93 | if(addr.locality_ == hpx::get_locality()) | |
94 | { | |
95 | typedef typename Action::component_type component_type; | |
96 | if (traits::component_supports_migration<component_type>::call()) | |
97 | { | |
98 | r = traits::action_was_object_migrated<Action>::call( | |
99 | id, addr.address_); | |
100 | if (!r.first) | |
101 | { | |
102 | return applier::detail::apply_l_p<Action>( | |
103 | std::forward<Continuation>(c), id, std::move(addr), | |
104 | priority, std::forward<Ts>(vs)...); | |
105 | } | |
106 | } | |
107 | else | |
108 | { | |
109 | return applier::detail::apply_l_p<Action>( | |
110 | std::forward<Continuation>(c), id, std::move(addr), | |
111 | priority, std::forward<Ts>(vs)...); | |
112 | } | |
113 | } | |
114 | // object was migrated or is not local | |
115 | else | |
116 | { | |
117 | // apply remotely | |
118 | return applier::detail::apply_r_p<Action>(std::move(addr), | |
119 | std::forward<Continuation>(c), id, priority, | |
120 | std::forward<Ts>(vs)...); | |
121 | } | |
122 | } | |
123 | return | |
124 | apply_impl<Action>(std::forward<Continuation>(c), | |
125 | id, priority, std::forward<Ts>(vs)...); | |
126 | } | |
127 | ||
128 | template <typename Action, typename ...Ts> | |
129 | bool apply_impl(hpx::id_type const& id, threads::thread_priority priority, | |
130 | Ts &&... vs) | |
131 | { | |
132 | if (!traits::action_is_target_valid<Action>::call(id)) { | |
133 | HPX_THROW_EXCEPTION(bad_parameter, "hpx::detail::apply_impl", | |
134 | boost::str(boost::format( | |
135 | "the target (destination) does not match the action type (%s)" | |
136 | ) % hpx::actions::detail::get_action_name<Action>())); | |
137 | return false; | |
138 | } | |
139 | ||
140 | std::pair<bool, components::pinned_ptr> r; | |
141 | ||
142 | // Determine whether the id is local or remote | |
143 | naming::address addr; | |
144 | if (agas::is_local_address_cached(id, addr)) | |
145 | { | |
146 | typedef typename Action::component_type component_type; | |
147 | if (traits::component_supports_migration<component_type>::call()) | |
148 | { | |
149 | r = traits::action_was_object_migrated<Action>::call( | |
150 | id, addr.address_); | |
151 | if (!r.first) | |
152 | { | |
153 | return applier::detail::apply_l_p<Action>( | |
154 | id, std::move(addr), priority, std::forward<Ts>(vs)...); | |
155 | } | |
156 | } | |
157 | else | |
158 | { | |
159 | return applier::detail::apply_l_p<Action>( | |
160 | id, std::move(addr), priority, std::forward<Ts>(vs)...); | |
161 | } | |
162 | } | |
163 | ||
164 | // apply remotely | |
165 | return applier::detail::apply_r_p<Action>(std::move(addr), | |
166 | id, priority, std::forward<Ts>(vs)...); | |
167 | } | |
168 | ||
169 | template <typename Action, typename ...Ts> | |
170 | bool apply_impl(hpx::id_type const& id, naming::address&& addr, | |
171 | threads::thread_priority priority, Ts &&... vs) | |
172 | { | |
173 | // Determine whether the id is local or remote | |
174 | if(addr) | |
175 | { | |
176 | if (!traits::action_is_target_valid<Action>::call(id)) { | |
177 | HPX_THROW_EXCEPTION(bad_parameter, "hpx::detail::apply_impl", | |
178 | boost::str(boost::format( | |
179 | "the target (destination) does not match the action type (%s)" | |
180 | ) % hpx::actions::detail::get_action_name<Action>())); | |
181 | return false; | |
182 | } | |
183 | ||
184 | std::pair<bool, components::pinned_ptr> r; | |
185 | if(addr.locality_ == hpx::get_locality()) | |
186 | { | |
187 | typedef typename Action::component_type component_type; | |
188 | if (traits::component_supports_migration<component_type>::call()) | |
189 | { | |
190 | r = traits::action_was_object_migrated<Action>::call( | |
191 | id, addr.address_); | |
192 | if (!r.first) | |
193 | { | |
194 | return applier::detail::apply_l_p<Action>( | |
195 | id, std::move(addr), priority, std::forward<Ts>(vs)...); | |
196 | } | |
197 | } | |
198 | else | |
199 | { | |
200 | return applier::detail::apply_l_p<Action>( | |
201 | id, std::move(addr), priority, std::forward<Ts>(vs)...); | |
202 | } | |
203 | } | |
204 | // object was migrated or is not local | |
205 | else | |
206 | { | |
207 | // apply remotely | |
208 | return applier::detail::apply_r_p<Action>(std::move(addr), | |
209 | id, priority, std::forward<Ts>(vs)...); | |
210 | } | |
211 | } | |
212 | return apply_impl<Action>(id, priority, std::forward<Ts>(vs)...); | |
213 | } | |
214 | ||
215 | template <typename Action, typename Continuation, typename Callback, typename ...Ts> | |
216 | typename std::enable_if< | |
217 | traits::is_continuation<Continuation>::value, bool | |
218 | >::type | |
219 | apply_cb_impl(Continuation && c, hpx::id_type const& id, | |
220 | threads::thread_priority priority, Callback&& cb, Ts&&... vs) | |
221 | { | |
222 | if (!traits::action_is_target_valid<Action>::call(id)) { | |
223 | HPX_THROW_EXCEPTION(bad_parameter, "hpx::detail::apply_cb_impl", | |
224 | boost::str(boost::format( | |
225 | "the target (destination) does not match the action type (%s)" | |
226 | ) % hpx::actions::detail::get_action_name<Action>())); | |
227 | return false; | |
228 | } | |
229 | ||
230 | std::pair<bool, components::pinned_ptr> r; | |
231 | ||
232 | // Determine whether the id is local or remote | |
233 | naming::address addr; | |
234 | if (agas::is_local_address_cached(id, addr)) | |
235 | { | |
236 | typedef typename Action::component_type component_type; | |
237 | if (traits::component_supports_migration<component_type>::call()) | |
238 | { | |
239 | r = traits::action_was_object_migrated<Action>::call( | |
240 | id, addr.address_); | |
241 | if (!r.first) | |
242 | { | |
243 | bool result = applier::detail::apply_l_p<Action>( | |
244 | std::forward<Continuation>(c), id, std::move(addr), | |
245 | priority, std::forward<Ts>(vs)...); | |
246 | ||
247 | // invoke callback | |
248 | cb(boost::system::error_code(), parcelset::parcel()); | |
249 | return result; | |
250 | } | |
251 | } | |
252 | else | |
253 | { | |
254 | bool result = applier::detail::apply_l_p<Action>( | |
255 | std::forward<Continuation>(c), id, std::move(addr), | |
256 | priority, std::forward<Ts>(vs)...); | |
257 | ||
258 | // invoke callback | |
259 | cb(boost::system::error_code(), parcelset::parcel()); | |
260 | return result; | |
261 | } | |
262 | } | |
263 | ||
264 | // apply remotely | |
265 | return applier::detail::apply_r_p_cb<Action>(std::move(addr), | |
266 | std::forward<Continuation>(c), id, | |
267 | priority, std::forward<Callback>(cb), std::forward<Ts>(vs)...); | |
268 | } | |
269 | ||
270 | template <typename Action, typename Callback, typename ...Ts> | |
271 | bool apply_cb_impl(hpx::id_type const& id, | |
272 | threads::thread_priority priority, Callback&& cb, Ts&&... vs) | |
273 | { | |
274 | if (!traits::action_is_target_valid<Action>::call(id)) { | |
275 | HPX_THROW_EXCEPTION(bad_parameter, "hpx::detail::apply_cb_impl", | |
276 | boost::str(boost::format( | |
277 | "the target (destination) does not match the action type (%s)" | |
278 | ) % hpx::actions::detail::get_action_name<Action>())); | |
279 | return false; | |
280 | } | |
281 | ||
282 | std::pair<bool, components::pinned_ptr> r; | |
283 | ||
284 | // Determine whether the id is local or remote | |
285 | naming::address addr; | |
286 | if (agas::is_local_address_cached(id, addr)) | |
287 | { | |
288 | typedef typename Action::component_type component_type; | |
289 | if (traits::component_supports_migration<component_type>::call()) | |
290 | { | |
291 | r = traits::action_was_object_migrated<Action>::call( | |
292 | id, addr.address_); | |
293 | if (!r.first) | |
294 | { | |
295 | bool result = applier::detail::apply_l_p<Action>( | |
296 | id, std::move(addr), priority, std::forward<Ts>(vs)...); | |
297 | ||
298 | // invoke callback | |
299 | cb(boost::system::error_code(), parcelset::parcel()); | |
300 | return result; | |
301 | } | |
302 | } | |
303 | else | |
304 | { | |
305 | bool result = applier::detail::apply_l_p<Action>( | |
306 | id, std::move(addr), priority, std::forward<Ts>(vs)...); | |
307 | ||
308 | // invoke callback | |
309 | cb(boost::system::error_code(), parcelset::parcel()); | |
310 | return result; | |
311 | } | |
312 | } | |
313 | ||
314 | // apply remotely | |
315 | return applier::detail::apply_r_p_cb<Action>(std::move(addr), id, | |
316 | priority, std::forward<Callback>(cb), std::forward<Ts>(vs)...); | |
317 | } | |
318 | }} | |
319 | ||
320 | #endif | |
321 |
Copyright (c) 2006-2012 Rogue Wave Software, Inc. All Rights Reserved.
Patents pending.