• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

STEllAR-GROUP / hpx / #882

31 Aug 2023 07:44PM UTC coverage: 41.798% (-44.7%) from 86.546%
#882

push

19442 of 46514 relevant lines covered (41.8%)

126375.38 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

66.67
/libs/full/async_distributed/include/hpx/async_distributed/sync.hpp
1
//  Copyright (c) 2007-2023 Hartmut Kaiser
2
//
3
//  SPDX-License-Identifier: BSL-1.0
4
//  Distributed under the Boost Software License, Version 1.0. (See accompanying
5
//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6

7
/// \file sync.hpp
8
/// \page hpx::sync (distributed)
9
/// \headerfile hpx/async.hpp
10

11
#pragma once
12

13
#if defined(DOXYGEN)
14

15
namespace hpx {
16
    // clang-format off
17

18
    /// \brief The distributed implementation of \c hpx::sync can be used by
19
    ///        giving an action instance as argument instead of a function,
20
    ///        and also by providing another argument with the locality ID or
21
    ///        the target ID. The action executes synchronously.
22
    ///
23
    /// \tparam Action The type of action instance
24
    /// \tparam Target The type of target where the action should be executed
25
    /// \tparam Ts     The type of any additional arguments
26
    ///
27
    /// \param action  The action instance to be executed
28
    /// \param target  The target where the action should be executed
29
    /// \param ts      Additional arguments
30
    ///
31
    /// \returns \c hpx::future referring to the shared state created by this call to \c hpx::sync
32
    template <typename Action, typename Target, typename... Ts>
33
    decltype(auto) sync(Action&& action, Target&& target, Ts&&... ts);
34
    // clang-format on
35
}    // namespace hpx
36

37
#else
38

39
#include <hpx/config.hpp>
40
#include <hpx/actions_base/traits/extract_action.hpp>
41
#include <hpx/actions_base/traits/is_client.hpp>
42
#include <hpx/actions_base/traits/is_valid_action.hpp>
43
#include <hpx/assert.hpp>
44
#include <hpx/async_distributed/bind_action.hpp>
45
#include <hpx/async_distributed/detail/sync_implementations.hpp>
46
#include <hpx/async_distributed/sync.hpp>
47
#include <hpx/components/client_base.hpp>
48
#include <hpx/modules/async_base.hpp>
49
#include <hpx/modules/async_local.hpp>
50
#include <hpx/modules/execution.hpp>
51
#include <hpx/modules/executors.hpp>
52
#include <hpx/modules/functional.hpp>
53
#include <hpx/modules/futures.hpp>
54
#include <hpx/naming_base/id_type.hpp>
55

56
#include <type_traits>
57
#include <utility>
58

59
///////////////////////////////////////////////////////////////////////////////
60
namespace hpx::detail {
61

62
    template <typename Action>
63
    struct sync_result
64
    {
65
        using type = traits::promise_local_result_t<
66
            typename traits::extract_action<Action>::remote_result_type>;
67
    };
68

69
    template <typename Action>
70
    using sync_result_t = typename sync_result<Action>::type;
71

72
    ///////////////////////////////////////////////////////////////////////////
73
    template <typename Action>
74
    struct sync_action_client_dispatch
1,181✔
75
    {
76
        template <typename Policy, typename Client, typename Stub,
88✔
77
            typename Data, typename... Ts>
78
        HPX_FORCEINLINE std::enable_if_t<traits::is_launch_policy_v<Policy>,
79
            sync_result_t<Action>>
80
        operator()(components::client_base<Client, Stub, Data> const& c,
81
            Policy const& launch_policy, Ts&&... ts) const
82
        {
83
            HPX_ASSERT(c.is_ready());
84
            return hpx::detail::sync_impl<Action>(
85
                launch_policy, c.get_id(), HPX_FORWARD(Ts, ts)...);
86
        }
87
    };
88

89
    ///////////////////////////////////////////////////////////////////////////
90
    // launch
91
    template <typename Action, typename Policy>
92
    struct sync_action_dispatch<Action, Policy,
93
        std::enable_if_t<traits::is_launch_policy_v<Policy>>>
94
    {
95
        // id_type
96
        template <typename Policy_, typename... Ts>
97
        HPX_FORCEINLINE static sync_result_t<Action> call(
98
            Policy_&& launch_policy, hpx::id_type const& id, Ts&&... ts)
99
        {
100
            return hpx::detail::sync_impl<Action>(
101
                HPX_FORWARD(Policy_, launch_policy), id,
102
                HPX_FORWARD(Ts, ts)...);
103
        }
104

105
        template <typename Policy_, typename Client, typename Stub,
106
            typename Data, typename... Ts>
107
        HPX_FORCEINLINE static sync_result_t<Action> call(
108
            Policy_&& launch_policy,
109
            components::client_base<Client, Stub, Data> const& c, Ts&&... ts)
110
        {
111
            // make sure the action is compatible with the component type
112
            using component_type = typename components::client_base<Client,
113
                Stub, Data>::server_component_type;
114

115
            static_assert(traits::is_valid_action_v<Action, component_type>,
116
                "The action to invoke is not supported by the target");
117

118
            // invoke directly if client is ready
119
            if (c.is_ready())
120
            {
121
                return hpx::detail::sync_impl<Action>(
122
                    HPX_FORWARD(Policy_, launch_policy), c.get_id(),
123
                    HPX_FORWARD(Ts, ts)...);
124
            }
125

126
            // defer invocation otherwise
127
            return c.then(launch_policy,
128
                util::one_shot(
129
                    hpx::bind_back(sync_action_client_dispatch<Action>(),
130
                        launch_policy, HPX_FORWARD(Ts, ts)...)));
131
        }
132
    };
133

134
    // hpx::id_type
135
    template <typename Action>
136
    struct sync_action_dispatch<Action, hpx::id_type>
137
    {
138
        template <typename... Ts>
139
        HPX_FORCEINLINE static decltype(auto) call(
140
            hpx::id_type const& id, Ts&&... ts)
141
        {
142
            return sync_action_dispatch<Action, hpx::launch::sync_policy>::call(
143
                launch::sync, id, HPX_FORWARD(Ts, ts)...);
144
        }
145
    };
146

147
    // component::client
148
    template <typename Action, typename Client>
149
    struct sync_action_dispatch<Action, Client,
150
        std::enable_if_t<traits::is_client_v<Client>>>
151
    {
152
        template <typename Client_, typename Stub, typename Data,
153
            typename... Ts>
154
        HPX_FORCEINLINE static decltype(auto) call(
155
            components::client_base<Client_, Stub, Data> const& c, Ts&&... ts)
156
        {
157
            return sync_action_dispatch<Action, hpx::launch::sync_policy>::call(
158
                launch::sync, c, HPX_FORWARD(Ts, ts)...);
159
        }
160
    };
161

162
    ///////////////////////////////////////////////////////////////////////////
163
    template <typename Action>
164
    struct sync_launch_policy_dispatch<Action,
165
        std::enable_if_t<traits::is_action_v<Action>>>
166
    {
167
        template <typename Policy, typename... Ts>
168
        HPX_FORCEINLINE static decltype(auto) call(
169
            Policy&& launch_policy, Action const&, Ts&&... ts)
170
        {
171
            static_assert(traits::is_launch_policy_v<std::decay_t<Policy>>,
172
                "Policy must be a valid launch policy");
173

174
            return sync<Action>(
175
                HPX_FORWARD(Policy, launch_policy), HPX_FORWARD(Ts, ts)...);
176
        }
177
    };
178
}    // namespace hpx::detail
179

180
namespace hpx {
181

182
    template <typename Action, typename F, typename... Ts>
183
    HPX_FORCEINLINE auto sync(F&& f, Ts&&... ts)
184
        -> decltype(detail::sync_action_dispatch<Action, std::decay_t<F>>::call(
185
            HPX_FORWARD(F, f), HPX_FORWARD(Ts, ts)...))
186
    {
187
        return detail::sync_action_dispatch<Action, std::decay_t<F>>::call(
188
            HPX_FORWARD(F, f), HPX_FORWARD(Ts, ts)...);
189
    }
190
}    // namespace hpx
191

192
///////////////////////////////////////////////////////////////////////////////
193
namespace hpx::detail {
194

195
    ///////////////////////////////////////////////////////////////////////////
196
    // any action
197
    template <typename Action>
198
    struct sync_dispatch<Action, std::enable_if_t<traits::is_action_v<Action>>>
×
199
    {
200
        template <typename Component, typename Signature, typename Derived,
201
            typename... Ts>
202
        HPX_FORCEINLINE static decltype(auto) call(
203
            hpx::actions::basic_action<Component, Signature, Derived> const&,
204
            hpx::id_type const& id, Ts&&... vs)
205
        {
206
            return sync<Derived>(launch::sync, id, HPX_FORWARD(Ts, vs)...);
207
        }
208

209
        template <typename Component, typename Signature, typename Derived,
210
            typename Client, typename Stub, typename Data, typename... Ts>
211
        HPX_FORCEINLINE static decltype(auto) call(
212
            hpx::actions::basic_action<Component, Signature, Derived> const&,
213
            components::client_base<Client, Stub, Data> const& c, Ts&&... vs)
214
        {
215
            using component_type = typename components::client_base<Client,
216
                Stub, Data>::server_component_type;
217

218
            static_assert(traits::is_valid_action_v<Action, component_type>,
219
                "The action to invoke is not supported by the target");
220

221
            return sync<Derived>(
222
                launch::sync, c.get_id(), HPX_FORWARD(Ts, vs)...);
223
        }
224
    };
225

226
    // launch with any action
227
    template <typename Func>
228
    struct sync_dispatch_launch_policy_helper<Func,
229
        std::enable_if_t<traits::is_action_v<Func>>>
230
    {
231
        template <typename Policy_, typename F, typename... Ts>
232
        HPX_FORCEINLINE static auto call(
233
            Policy_&& launch_policy, F&& f, Ts&&... ts)
234
            -> decltype(sync_launch_policy_dispatch<std::decay_t<F>>::call(
235
                HPX_FORWARD(Policy_, launch_policy), HPX_FORWARD(F, f),
236
                HPX_FORWARD(Ts, ts)...))
237
        {
238
            return sync_launch_policy_dispatch<std::decay_t<F>>::call(
239
                HPX_FORWARD(Policy_, launch_policy), HPX_FORWARD(F, f),
240
                HPX_FORWARD(Ts, ts)...);
241
        }
242

243
        template <typename Policy_, typename Component, typename Signature,
244
            typename Derived, typename Client, typename Stub, typename Data,
245
            typename... Ts>
246
        HPX_FORCEINLINE static sync_result_t<Derived> call(
247
            Policy_&& launch_policy,
248
            hpx::actions::basic_action<Component, Signature, Derived> const&,
249
            components::client_base<Client, Stub, Data> const& c, Ts&&... ts)
250
        {
251
            using component_type = typename components::client_base<Client,
252
                Stub, Data>::server_component_type;
253

254
            static_assert(traits::is_valid_action_v<Derived, component_type>,
255
                "The action to invoke is not supported by the target");
256

257
            return sync<Derived>(HPX_FORWARD(Policy_, launch_policy),
258
                c.get_id(), HPX_FORWARD(Ts, ts)...);
259
        }
260
    };
261

262
    // bound action
263
    template <typename Bound>
264
    struct sync_dispatch<Bound, std::enable_if_t<hpx::is_bound_action_v<Bound>>>
265
    {
266
        template <typename Action, typename Is, typename... Ts, typename... Us>
267
        HPX_FORCEINLINE static decltype(auto) call(
268
            hpx::detail::bound_action<Action, Is, Ts...> const& bound,
269
            Us&&... vs)
270
        {
271
            return bound(HPX_FORWARD(Us, vs)...);
272
        }
273
    };
274
}    // namespace hpx::detail
275

276
#endif
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc