/home/users/khuck/src/hpx-lsu/hpx/lcos/async.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_LCOS_ASYNC_SEP_28_2011_0840AM)
7  
#define HPX_LCOS_ASYNC_SEP_28_2011_0840AM
8  
9  
#include <hpx/config.hpp>
10  
#include <hpx/lcos/async_fwd.hpp>
11  
#include <hpx/lcos/detail/async_implementations.hpp>
12  
#include <hpx/lcos/future.hpp>
13  
#include <hpx/runtime/components/client_base.hpp>
14  
#include <hpx/runtime/launch_policy.hpp>
15  
#include <hpx/runtime/naming/id_type.hpp>
16  
#include <hpx/traits/extract_action.hpp>
17  
#include <hpx/traits/is_action.hpp>
18  
#include <hpx/traits/is_client.hpp>
19  
#include <hpx/traits/is_distribution_policy.hpp>
20  
#include <hpx/traits/is_launch_policy.hpp>
21  
#include <hpx/traits/is_valid_action.hpp>
22  
#include <hpx/traits/promise_local_result.hpp>
23  
#include <hpx/util/bind.hpp>
24  
25  
#include <type_traits>
26  
#include <utility>
27  
28  
///////////////////////////////////////////////////////////////////////////////
29  
namespace hpx { namespace detail
30  
{
31  
    ///////////////////////////////////////////////////////////////////////////
32  
    template <typename Action>
33  
    struct async_action_client_dispatch
34  
    {
35  
        template <typename Client, typename Stub, typename ...Ts>
36  
        HPX_FORCEINLINE lcos::future<
37  
            typename traits::promise_local_result<
38  
                typename traits::extract_action<
39  
                    Action
40  
                >::remote_result_type
41  
            >::type>
42  
        operator()(launch launch_policy,
43  
            components::client_base<Client, Stub> const& c, Ts &&... ts) const
44  
        {
45  
            HPX_ASSERT(c.is_ready());
46  
            return hpx::detail::async_impl<Action>(launch_policy, c.get_id(),
47  
                std::forward<Ts>(ts)...);
48  
        }
49  
    };
50  
51  
    ///////////////////////////////////////////////////////////////////////////
52  
    // launch
53  
    template <typename Action, typename Policy>
54  
    struct async_action_dispatch<Action, Policy,
55  
        typename std::enable_if<
56  
            traits::is_launch_policy<Policy>::value
57  
        >::type>
58  
    {
59  
        // id_type
60  
        template <typename ...Ts>
61  
        HPX_FORCEINLINE static
62  
        lcos::future<
63  
            typename traits::promise_local_result<
64  
                typename hpx::traits::extract_action<
65  
                    Action
66  
                >::remote_result_type
67  
            >::type>
68  
        call(Policy launch_policy, naming::id_type const& id, Ts&&... ts)
69  
        {
70  
            return hpx::detail::async_impl<Action>(launch_policy, id,
71  
                std::forward<Ts>(ts)...);
72  
        }
73  
74  
        template <typename Client, typename Stub, typename ...Ts>
75  
        HPX_FORCEINLINE static
76  
        lcos::future<
77  
            typename traits::promise_local_result<
78  
                typename traits::extract_action<
79  
                    Action
80  
                >::remote_result_type
81  
            >::type>
82  
        call(Policy launch_policy,
83  
            components::client_base<Client, Stub> c, Ts&&... ts)
84  
        {
85  
            // make sure the action is compatible with the component type
86  
            typedef typename components::client_base<
87  
                    Client, Stub
88  
                >::server_component_type component_type;
89  
90  
            typedef traits::is_valid_action<Action, component_type> is_valid;
91  
            static_assert(is_valid::value,
92  
                "The action to invoke is not supported by the target");
93  
94  
            // invoke directly if client is ready
95  
            if (c.is_ready())
96  
            {
97  
                return hpx::detail::async_impl<Action>(
98  
                    launch_policy, c.get_id(), std::forward<Ts>(ts)...);
99  
            }
100  
101  
            // defer invocation otherwise
102  
            return c.then(util::bind(
103  
                util::one_shot(async_action_client_dispatch<Action>()),
104  
                launch_policy, c, std::forward<Ts>(ts)...
105  
            ));
106  
        }
107  
108  
        // distribution policy
109  
        template <typename DistPolicy, typename ...Ts>
110  
        HPX_FORCEINLINE static
111  
        typename std::enable_if<
112  
            traits::is_distribution_policy<DistPolicy>::value,
113  
            lcos::future<
114  
                typename traits::promise_local_result<
115  
                    typename hpx::traits::extract_action<
116  
                        Action
117  
                    >::remote_result_type
118  
                >::type
119  
            >
120  
        >::type
121  
        call(Policy launch_policy,
122  
            DistPolicy const& policy, Ts&&... ts)
123  
        {
124  
            return policy.template async<Action>(launch_policy,
125  
                std::forward<Ts>(ts)...);
126  
        }
127  
    };
128  
129  
    // naming::id_type
130  
    template <typename Action>
131  
    struct async_action_dispatch<Action, naming::id_type>
132  
    {
133  
        template <typename ...Ts>
134  
        HPX_FORCEINLINE static
135  
        lcos::future<
136  
            typename traits::promise_local_result<
137  
                typename hpx::traits::extract_action<
138  
                    Action
139  
                >::remote_result_type
140  
            >::type>
141  
        call(naming::id_type const& id, Ts&&... ts)
142  
        {
143  
            return async_action_dispatch<
144  
                    Action, hpx::detail::async_policy
145  
                >::call(launch::async, id, std::forward<Ts>(ts)...);
146  
        }
147  
    };
148  
149  
    // component::client
150  
    template <typename Action, typename Client>
151  
    struct async_action_dispatch<Action, Client,
152  
        typename std::enable_if<
153  
            traits::is_client<Client>::value
154  
        >::type>
155  
    {
156  
        template <typename Client_, typename Stub, typename ...Ts>
157  
        HPX_FORCEINLINE static
158  
        lcos::future<
159  
            typename traits::promise_local_result<
160  
                typename traits::extract_action<
161  
                    Action
162  
                >::remote_result_type
163  
            >::type>
164  
        call(components::client_base<Client_, Stub> const& c, Ts&&... ts)
165  
        {
166  
            return async_action_dispatch<
167  
                    Action, hpx::detail::async_policy
168  
                >::call(launch::async, c, std::forward<Ts>(ts)...);
169  
        }
170  
    };
171  
172  
    // distribution policy
173  
    template <typename Action, typename Policy>
174  
    struct async_action_dispatch<Action, Policy,
175  
        typename std::enable_if<
176  
            traits::is_distribution_policy<Policy>::value
177  
        >::type>
178  
    {
179  
        template <typename DistPolicy, typename ...Ts>
180  
        HPX_FORCEINLINE static
181  
        lcos::future<
182  
            typename traits::promise_local_result<
183  
                typename hpx::traits::extract_action<
184  
                    Action
185  
                >::remote_result_type
186  
            >::type>
187  
        call(DistPolicy const& policy, Ts&&... ts)
188  
        {
189  
            return async_action_dispatch<
190  
                    Action, hpx::detail::async_policy
191  
                >::call(launch::async, policy, std::forward<Ts>(ts)...);
192  
        }
193  
    };
194  
195  
    ///////////////////////////////////////////////////////////////////////////
196  
    template <typename Action>
197  
    struct async_launch_policy_dispatch<Action,
198  
        typename std::enable_if<
199  
            traits::is_action<Action>::value
200  
        >::type>
201  
    {
202  
        typedef typename traits::promise_local_result<
203  
                typename hpx::traits::extract_action<
204  
                    Action
205  
                >::remote_result_type
206  
            >::type result_type;
207  
208  
        template <typename Policy, typename ...Ts>
209  
        HPX_FORCEINLINE static
210  
        lcos::future<result_type>
211  
        call(Policy launch_policy, Action const&, Ts &&... ts)
212  
        {
213  
            static_assert(traits::is_launch_policy<Policy>::value,
214  
                "Policy must be a valid launch policy");
215  
            return async<Action>(launch_policy, std::forward<Ts>(ts)...);
216  
        }
217  
    };
218  
}}
219  
220  
namespace hpx
221  
{
222  
    template <typename Action, typename F, typename ...Ts>
223  
    HPX_FORCEINLINE
224  
    auto async(F && f, Ts &&... ts)
225  
    ->  decltype(detail::async_action_dispatch<
226  
                    Action, typename util::decay<F>::type
227  
            >::call(std::forward<F>(f), std::forward<Ts>(ts)...))
228  
    {
229  
        return detail::async_action_dispatch<
230  
                Action, typename util::decay<F>::type
231  
            >::call(std::forward<F>(f), std::forward<Ts>(ts)...);
232  
    }
233  
}
234  
235  
///////////////////////////////////////////////////////////////////////////////
236  
namespace hpx { namespace detail
237  
{
238  
    ///////////////////////////////////////////////////////////////////////////
239  
    // any action
240  
    template <typename Action>
241  
    struct async_dispatch<Action,
242  
        typename std::enable_if<
243  
            traits::is_action<Action>::value
244  
        >::type>
245  
    {
246  
        template <
247  
            typename Component, typename Signature, typename Derived,
248  
            typename ...Ts>
249  
        HPX_FORCEINLINE static lcos::future<
250  
            typename traits::promise_local_result<
251  
                typename hpx::traits::extract_action<
252  
                    Derived
253  
                >::remote_result_type
254  
            >::type>
255  
        call(hpx::actions::basic_action<Component, Signature, Derived> const&,
256  
            naming::id_type const& id, Ts&&... vs)
257  
        {
258  
            return async<Derived>(launch::async, id, std::forward<Ts>(vs)...);
259  
        }
260  
261  
        template <
262  
            typename Component, typename Signature, typename Derived,
263  
            typename Client, typename Stub, typename ...Ts>
264  
        HPX_FORCEINLINE static lcos::future<
265  
            typename traits::promise_local_result<
266  
                typename traits::extract_action<
267  
                    Derived
268  
                >::remote_result_type
269  
            >::type>
270  
        call(hpx::actions::basic_action<Component, Signature, Derived> const&,
271  
            components::client_base<Client, Stub> const& c, Ts&&... vs)
272  
        {
273  
            typedef typename components::client_base<
274  
                    Client, Stub
275  
                >::server_component_type component_type;
276  
277  
            typedef traits::is_valid_action<Derived, component_type> is_valid;
278  
            static_assert(is_valid::value,
279  
                "The action to invoke is not supported by the target");
280  
281  
            return async<Derived>(launch::async, c.get_id(),
282  
                std::forward<Ts>(vs)...);
283  
        }
284  
285  
        template <
286  
            typename Component, typename Signature, typename Derived,
287  
            typename DistPolicy, typename ...Ts>
288  
        HPX_FORCEINLINE static lcos::future<
289  
            typename traits::promise_local_result<
290  
                typename hpx::traits::extract_action<
291  
                    Derived
292  
                >::remote_result_type
293  
            >::type>
294  
        call(hpx::actions::basic_action<Component, Signature, Derived> const&,
295  
            DistPolicy const& policy, Ts&&... vs)
296  
        {
297  
            return async<Derived>(policy, std::forward<Ts>(vs)...);
298  
        }
299  
    };
300  
301  
    // launch with any action
302  
    template <typename Policy>
303  
    struct async_dispatch<Policy,
304  
        typename std::enable_if<
305  
            traits::is_launch_policy<Policy>::value
306  
        >::type>
307  
    {
308  
        template <typename F, typename ...Ts>
309  
        HPX_FORCEINLINE static auto
310  
        call(Policy launch_policy, F && f, Ts &&... ts)
311  
        ->  decltype(detail::async_launch_policy_dispatch<
312  
                typename util::decay<F>::type
313  
            >::call(launch_policy, std::forward<F>(f), std::forward<Ts>(ts)...))
314  
        {
315  
            return detail::async_launch_policy_dispatch<
316  
                typename util::decay<F>::type
317  
            >::call(launch_policy, std::forward<F>(f), std::forward<Ts>(ts)...);
318  
        }
319  
320  
        template <typename Component, typename Signature, typename Derived,
321  
            typename Client, typename Stub, typename ...Ts>
322  
        HPX_FORCEINLINE static
323  
        lcos::future<
324  
            typename traits::promise_local_result<
325  
                typename traits::extract_action<
326  
                    Derived
327  
                >::remote_result_type
328  
            >::type>
329  
        call(Policy launch_policy,
330  
            hpx::actions::basic_action<Component, Signature, Derived> const&,
331  
            components::client_base<Client, Stub> const& c, Ts&&... ts)
332  
        {
333  
            typedef typename components::client_base<
334  
                    Client, Stub
335  
                >::server_component_type component_type;
336  
337  
            typedef traits::is_valid_action<Derived, component_type> is_valid;
338  
            static_assert(is_valid::value,
339  
                "The action to invoke is not supported by the target");
340  
341  
            return async<Derived>(launch_policy, c.get_id(),
342  
                std::forward<Ts>(ts)...);
343  
        }
344  
345  
        template <typename Component, typename Signature, typename Derived,
346  
            typename DistPolicy, typename ...Ts>
347  
        HPX_FORCEINLINE static
348  
        typename std::enable_if<
349  
            traits::is_distribution_policy<DistPolicy>::value,
350  
            lcos::future<
351  
                typename traits::promise_local_result<
352  
                    typename traits::extract_action<
353  
                        Derived
354  
                    >::remote_result_type
355  
                >::type>
356  
        >::type
357  
        call(Policy launch_policy,
358  
            hpx::actions::basic_action<Component, Signature, Derived> const&,
359  
            DistPolicy const& policy, Ts&&... ts)
360  
        {
361  
            return async<Derived>(launch_policy, policy,
362  
                std::forward<Ts>(ts)...);
363  
        }
364  
    };
365  
}}
366  
367  
#endif
368  
369  

Copyright (c) 2006-2012 Rogue Wave Software, Inc. All Rights Reserved.
Patents pending.