/home/users/khuck/src/hpx-lsu/hpx/runtime/applier/detail/apply_implementations.hpp

Line% of fetchesSource
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.