1 //  Copyright (c) 2007-2015 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_LCOS_ASYNC_COLOCATED_FEB_01_2014_0105PM)
7 #define HPX_LCOS_ASYNC_COLOCATED_FEB_01_2014_0105PM
8 
9 #include <hpx/config.hpp>
10 #include <hpx/lcos/async_continue_fwd.hpp>
11 #include <hpx/lcos/async_fwd.hpp>
12 #include <hpx/lcos/detail/async_colocated_fwd.hpp>
13 #include <hpx/lcos/future.hpp>
14 #include <hpx/runtime/actions/action_support.hpp>
15 #include <hpx/runtime/agas/primary_namespace.hpp>
16 #include <hpx/runtime/agas/server/primary_namespace.hpp>
17 #include <hpx/runtime/naming/name.hpp>
18 #include <hpx/traits/extract_action.hpp>
19 #include <hpx/traits/is_continuation.hpp>
20 #include <hpx/traits/promise_local_result.hpp>
21 #include <hpx/util/bind.hpp>
22 #include <hpx/util/bind_action.hpp>
23 #include <hpx/util/functional/colocated_helpers.hpp>
24 #include <hpx/util/unique_function.hpp>
25 
26 #include <type_traits>
27 #include <utility>
28 
29 namespace hpx { namespace detail
30 {
31     template <typename Tuple>
32     struct async_colocated_bound_tuple;
33 
34     template <typename ...Ts>
35     struct async_colocated_bound_tuple<util::tuple<Ts...> >
36     {
37         typedef
38             util::tuple<
39                 hpx::util::detail::bound<
40                     hpx::util::functional::extract_locality
41                   , hpx::util::detail::placeholder<2ul>
42                   , hpx::id_type
43                 >
44               , Ts...
45             >
46             type;
47     };
48 }}
49 
50 #define HPX_REGISTER_ASYNC_COLOCATED_DECLARATION(Action, Name)                \
51     HPX_UTIL_REGISTER_UNIQUE_FUNCTION_DECLARATION(                            \
52         void (hpx::naming::id_type, hpx::naming::id_type)                     \
53       , (hpx::util::functional::detail::async_continuation_impl<              \
54             hpx::util::detail::bound_action<                                  \
55                 Action                                                        \
56               , hpx::detail::async_colocated_bound_tuple<                     \
57                     Action ::arguments_type                                   \
58                 >::type                                                       \
59             >,                                                                \
60             hpx::util::unused_type                                            \
61         >)                                                                    \
62       , Name                                                                  \
63     );                                                                        \
64 /**/
65 
66 #define HPX_REGISTER_ASYNC_COLOCATED(Action, Name)                            \
67     HPX_UTIL_REGISTER_UNIQUE_FUNCTION(                                        \
68         void (hpx::naming::id_type, hpx::naming::id_type)                     \
69       , (hpx::util::functional::detail::async_continuation_impl<              \
70             hpx::util::detail::bound_action<                                  \
71                 Action                                                        \
72               , hpx::detail::async_colocated_bound_tuple<                     \
73                     Action ::arguments_type                                   \
74                 >::type                                                       \
75             >,                                                                \
76             hpx::util::unused_type                                            \
77         >)                                                                    \
78       , Name                                                                  \
79     );                                                                        \
80 /**/
81 
82 namespace hpx { namespace detail
83 {
84     ///////////////////////////////////////////////////////////////////////////
85     template <typename Action, typename ...Ts>
86     lcos::future<
87         typename traits::promise_local_result<
88             typename hpx::traits::extract_action<Action>::remote_result_type
89         >::type>
async_colocated(naming::id_type const & gid,Ts &&...vs)90     async_colocated(naming::id_type const& gid, Ts&&... vs)
91     {
92         // Attach the requested action as a continuation to a resolve_async
93         // call on the locality responsible for the target gid.
94         naming::id_type service_target(
95             agas::primary_namespace::get_service_instance(gid.get_gid())
96           , naming::id_type::unmanaged);
97 
98         typedef
99             typename hpx::traits::extract_action<Action>::remote_result_type
100             remote_result_type;
101         typedef agas::server::primary_namespace::colocate_action action_type;
102 
103         using util::placeholders::_2;
104         return detail::async_continue_r<action_type, remote_result_type>(
105             util::functional::async_continuation(
106                 util::bind<Action>(
107                     util::bind(util::functional::extract_locality(), _2, gid)
108                   , std::forward<Ts>(vs)...)
109                 ), service_target, gid.get_gid());
110     }
111 
112     template <
113         typename Component, typename Signature, typename Derived,
114         typename ...Ts>
115     lcos::future<
116         typename traits::promise_local_result<
117             typename hpx::traits::extract_action<Derived>::remote_result_type
118         >::type>
async_colocated(hpx::actions::basic_action<Component,Signature,Derived>,naming::id_type const & gid,Ts &&...vs)119     async_colocated(
120         hpx::actions::basic_action<Component, Signature, Derived> /*act*/
121       , naming::id_type const& gid, Ts&&... vs)
122     {
123         return async_colocated<Derived>(gid, std::forward<Ts>(vs)...);
124     }
125 
126     ///////////////////////////////////////////////////////////////////////////
127     template <typename Action, typename Continuation, typename ...Ts>
128     typename std::enable_if<
129         traits::is_continuation<Continuation>::value,
130         lcos::future<
131             typename traits::promise_local_result<
132                 typename hpx::traits::extract_action<Action>::remote_result_type
133             >::type
134         >
135     >::type
async_colocated(Continuation && cont,naming::id_type const & gid,Ts &&...vs)136     async_colocated(Continuation && cont,
137         naming::id_type const& gid, Ts&&... vs)
138     {
139         // Attach the requested action as a continuation to a resolve_async
140         // call on the locality responsible for the target gid.
141         naming::id_type service_target(
142             agas::primary_namespace::get_service_instance(gid.get_gid())
143           , naming::id_type::unmanaged);
144 
145         typedef
146             typename hpx::traits::extract_action<Action>::remote_result_type
147         remote_result_type;
148         typedef agas::server::primary_namespace::colocate_action action_type;
149 
150         using util::placeholders::_2;
151         return detail::async_continue_r<action_type, remote_result_type>(
152             util::functional::async_continuation(
153                 util::bind<Action>(
154                     util::bind(util::functional::extract_locality(), _2, gid)
155                       , std::forward<Ts>(vs)...)
156                   , std::forward<Continuation>(cont))
157               , service_target, gid.get_gid());
158     }
159 
160     template <
161         typename Continuation,
162         typename Component, typename Signature, typename Derived,
163         typename ...Ts>
164     typename std::enable_if<
165         traits::is_continuation<Continuation>::value,
166         lcos::future<
167             typename traits::promise_local_result<
168                 typename hpx::traits::extract_action<Derived>::remote_result_type
169             >::type
170         >
171     >::type
async_colocated(Continuation && cont,hpx::actions::basic_action<Component,Signature,Derived>,naming::id_type const & gid,Ts &&...vs)172     async_colocated(
173         Continuation && cont
174       , hpx::actions::basic_action<Component, Signature, Derived> /*act*/
175       , naming::id_type const& gid, Ts&&... vs)
176     {
177         return async_colocated<Derived>(std::forward<Continuation>(cont), gid,
178             std::forward<Ts>(vs)...);
179     }
180 }}
181 
182 #endif
183