• 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

35.0
/libs/full/runtime_distributed/include/hpx/runtime_distributed/server/runtime_support.hpp
1
//  Copyright (c) 2007-2021 Hartmut Kaiser
2
//  Copyright (c) 2011 Bryce Lelbach
3
//  Copyright (c) 2011-2017 Thomas Heller
4
//
5
//  SPDX-License-Identifier: BSL-1.0
6
//  Distributed under the Boost Software License, Version 1.0. (See accompanying
7
//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8

9
#pragma once
10

11
#include <hpx/config.hpp>
12
#include <hpx/actions/transfer_action.hpp>
13
#include <hpx/actions_base/component_action.hpp>
14
#include <hpx/actions_base/traits/action_does_termination_detection.hpp>
15
#include <hpx/agas/agas_fwd.hpp>
16
#include <hpx/assert.hpp>
17
#include <hpx/async_distributed/transfer_continuation_action.hpp>
18
#include <hpx/components_base/component_type.hpp>
19
#include <hpx/components_base/server/create_component.hpp>
20
#include <hpx/components_base/traits/is_component.hpp>
21
#include <hpx/modules/errors.hpp>
22
#include <hpx/modules/plugin.hpp>
23
#include <hpx/modules/program_options.hpp>
24
#include <hpx/modules/runtime_configuration.hpp>
25
#include <hpx/modules/synchronization.hpp>
26
#include <hpx/parcelset_base/locality.hpp>
27
#include <hpx/performance_counters/counters.hpp>
28
#include <hpx/plugin_factories/plugin_factory_base.hpp>
29
#include <hpx/runtime_components/components_fwd.hpp>
30
#include <hpx/runtime_distributed/find_here.hpp>
31

32
#include <atomic>
33
#include <condition_variable>
34
#include <cstddef>
35
#include <cstdint>
36
#include <list>
37
#include <map>
38
#include <memory>
39
#include <mutex>
40
#include <set>
41
#include <string>
42
#include <thread>
43
#include <type_traits>
44
#include <utility>
45
#include <vector>
46

47
#include <hpx/config/warnings_prefix.hpp>
48

49
namespace hpx::components::server {
50

51
    ///////////////////////////////////////////////////////////////////////////
52
    class runtime_support
53
    {
54
    private:
55
        using plugin_map_mutex_type = hpx::spinlock;
56

57
        struct plugin_factory
58
        {
59
            plugin_factory(
32✔
60
                std::shared_ptr<plugins::plugin_factory_base> const& f,
61
                hpx::util::plugin::dll const& d, bool enabled)
62
              : first(f)
63
              , second(d)
64
              , isenabled(enabled)
32✔
65
            {
32✔
66
            }
32✔
67

68
            std::shared_ptr<plugins::plugin_factory_base> first;
69
            hpx::util::plugin::dll const& second;
70
            bool isenabled;
71
        };
72
        using plugin_factory_type = plugin_factory;
73
        using plugin_map_type = std::map<std::string, plugin_factory_type>;
74

75
        using modules_map_type = std::map<std::string, hpx::util::plugin::dll>;
76
        using static_modules_type = std::vector<static_factory_load_data_type>;
77

78
    public:
79
        using type_holder = runtime_support;
80

81
        static component_type get_component_type()
82
        {
83
            return components::get_component_type<runtime_support>();
84
        }
85
        static void set_component_type(component_type t)
86
        {
87
            components::set_component_type<runtime_support>(t);
88
        }
89

90
        // constructor
91
        explicit runtime_support(hpx::util::runtime_configuration& cfg);
92

93
        ~runtime_support()
94
        {
95
            tidy();
32✔
96
        }
97

32✔
98
        /// \brief finalize() will be called just before the instance gets
32✔
99
        ///        destructed
100
        static constexpr void finalize() {}
101

102
        void delete_function_lists();
103
        void tidy();
104

105
        // This component type requires valid locality id for its actions to
106
        // be invoked
107
        static bool is_target_valid(hpx::id_type const& id)
108
        {
109
            return naming::is_locality(id);
110
        }
111

112
        ///////////////////////////////////////////////////////////////////////
113
        // exposed functionality of this component
114

115
        /// \brief Actions to create new objects
116
        template <typename Component>
117
        naming::gid_type create_component();
118

119
        template <typename Component, typename T, typename... Ts>
120
        naming::gid_type create_component(T v, Ts... vs);
121

122
        template <typename Component, typename... Ts>
123
        std::vector<naming::gid_type> bulk_create_component(
124
            std::size_t count, Ts... vs);
125

126
        template <typename Component, typename... Ts>
127
        std::vector<naming::gid_type> bulk_create_component_with_count(
128
            std::size_t count, Ts... vs);
129

130
        template <typename Component>
131
        naming::gid_type copy_create_component(
132
            std::shared_ptr<Component> const& p, bool);
133

134
        template <typename Component>
135
        naming::gid_type migrate_component_to_here(
136
            std::shared_ptr<Component> const& p, hpx::id_type);
137

138
        /// \brief Gracefully shutdown this runtime system instance
139
        void shutdown(double timeout, hpx::id_type const& respond_to);
140

141
        /// \brief Gracefully shutdown runtime system instances on all localities
142
        void shutdown_all(double timeout);
143

144
        /// \brief Shutdown this runtime system instance
145
        [[noreturn]] void terminate(hpx::id_type const& respond_to);
146

147
        void terminate_act(hpx::id_type const& id)
148
        {
149
            terminate(id);
150
        }
151

152
        /// \brief Shutdown runtime system instances on all localities
×
153
        [[noreturn]] void terminate_all();
154

×
155
        void terminate_all_act()
156
        {
157
            terminate_all();
158
        }
159

160
        /// \brief Retrieve configuration information
×
161
        util::section get_config();
162

×
163
        /// \brief Load all components on this locality.
164
        int load_components();
165

166
        void call_startup_functions(bool pre_startup);
167
        void call_shutdown_functions(bool pre_shutdown);
168

169
        /// \brief Force a garbage collection operation in the AGAS layer.
170
        void garbage_collect();
171

172
        /// \brief Create the given performance counter instance.
173
        naming::gid_type create_performance_counter(
174
            performance_counters::counter_info const& info);
175

176
        /// \brief Remove the given locality from our connection cache
177
        void remove_from_connection_cache(
178
            naming::gid_type const& gid, parcelset::endpoints_type const& eps);
179

180
        /// \brief termination detection
181
#if defined(HPX_HAVE_NETWORKING)
182
        void dijkstra_termination(std::uint32_t initiating_locality_id,
183
            std::uint32_t num_localities, bool dijkstra_token);
184
#endif
185

186
        ///////////////////////////////////////////////////////////////////////
187
        // Each of the exposed functions needs to be encapsulated into an action
188
        // type, allowing to generate all require boilerplate code for threads,
189
        // serialization, etc.
190
        HPX_DEFINE_COMPONENT_ACTION(runtime_support, load_components)
191
        HPX_DEFINE_COMPONENT_ACTION(runtime_support, call_startup_functions)
192
        HPX_DEFINE_COMPONENT_ACTION(runtime_support, call_shutdown_functions)
193
        HPX_DEFINE_COMPONENT_ACTION(runtime_support, shutdown)
194
        HPX_DEFINE_COMPONENT_ACTION(runtime_support, shutdown_all)
195
        HPX_DEFINE_COMPONENT_ACTION(
196
            runtime_support, terminate_act, terminate_action)
197
        HPX_DEFINE_COMPONENT_ACTION(
198
            runtime_support, terminate_all_act, terminate_all_action)
199

200
        // even if this is not a short/minimal action, we still execute it
201
        // directly to avoid a deadlock condition inside the thread manager
202
        // waiting for this thread to finish, which waits for the thread
203
        // manager to exit
204
        HPX_DEFINE_COMPONENT_DIRECT_ACTION(runtime_support, get_config)
205

206
        HPX_DEFINE_COMPONENT_ACTION(runtime_support, garbage_collect)
207
        HPX_DEFINE_COMPONENT_ACTION(runtime_support, create_performance_counter)
208
        HPX_DEFINE_COMPONENT_ACTION(
209
            runtime_support, remove_from_connection_cache)
210

211
#if defined(HPX_HAVE_NETWORKING)
212
        HPX_DEFINE_COMPONENT_ACTION(runtime_support, dijkstra_termination)
213
#endif
214

215
        ///////////////////////////////////////////////////////////////////////
216
        /// \brief Start the runtime_support component
217
        void run();
218

219
        /// \brief Wait for the runtime_support component to notify the calling
220
        ///        thread.
221
        ///
222
        /// This function will be called from the main thread, causing it to
223
        /// block while the HPX functionality is executed. The main thread will
224
        /// block until the shutdown_action is executed, which in turn notifies
225
        /// all waiting threads.
226
        void wait();
227

228
        /// \brief Notify all waiting (blocking) threads allowing the system to
229
        ///        be properly stopped.
230
        ///
231
        /// \note      This function can be called from any thread.
232
        void stop(double timeout, hpx::id_type const& respond_to,
233
            bool remove_from_remote_caches);
234

235
        /// called locally only
236
        void stopped();
237
        void notify_waiting_main();
238

239
        bool was_stopped() const
240
        {
241
            return stop_called_;
242
        }
243

244
        void add_pre_startup_function(startup_function_type f);
245
        void add_startup_function(startup_function_type f);
246
        void add_pre_shutdown_function(shutdown_function_type f);
247
        void add_shutdown_function(shutdown_function_type f);
248

249
        void remove_here_from_connection_cache();
250
        void remove_here_from_console_connection_cache();
251

252
#if defined(HPX_HAVE_NETWORKING)
253
        ///////////////////////////////////////////////////////////////////////
254
        void register_message_handler(char const* message_handler_type,
255
            char const* action, error_code& ec);
256

257
        parcelset::policies::message_handler* create_message_handler(
258
            char const* message_handler_type, char const* action,
259
            parcelset::parcelport* pp, std::size_t num_messages,
260
            std::size_t interval, error_code& ec);
261
        serialization::binary_filter* create_binary_filter(
262
            char const* binary_filter_type, bool compress,
263
            serialization::binary_filter* next_filter, error_code& ec);
264

265
        // notify of message being sent
266
        void dijkstra_make_black();
267
#endif
268

269
    protected:
270
        // Load all components from the ini files found in the configuration
271
        int load_components(util::section& ini, naming::gid_type const& prefix,
272
            agas::addressing_service& agas_client,
273
            hpx::program_options::options_description& options,
274
            std::set<std::string>& startup_handled);
275

276
#if !defined(HPX_HAVE_STATIC_LINKING)
277
        bool load_component(hpx::util::plugin::dll& d, util::section& ini,
278
            std::string const& instance, std::string const& component,
279
            filesystem::path const& lib, naming::gid_type const& prefix,
280
            agas::addressing_service& agas_client, bool isdefault,
281
            bool isenabled, hpx::program_options::options_description& options,
282
            std::set<std::string>& startup_handled);
283
        bool load_component_dynamic(util::section& ini,
284
            std::string const& instance, std::string const& component,
285
            filesystem::path lib, naming::gid_type const& prefix,
286
            agas::addressing_service& agas_client, bool isdefault,
287
            bool isenabled, hpx::program_options::options_description& options,
288
            std::set<std::string>& startup_handled);
289

290
        bool load_startup_shutdown_functions(
291
            hpx::util::plugin::dll& d, error_code& ec);
292
        bool load_commandline_options(hpx::util::plugin::dll& d,
293
            hpx::program_options::options_description& options, error_code& ec);
294
#endif
295

296
        bool load_component_static(util::section& ini,
297
            std::string const& instance, std::string const& component,
298
            filesystem::path const& lib, naming::gid_type const& prefix,
299
            agas::addressing_service& agas_client, bool isdefault,
300
            bool isenabled, hpx::program_options::options_description& options,
301
            std::set<std::string>& startup_handled);
302
        bool load_startup_shutdown_functions_static(
303
            std::string const& mod, error_code& ec);
304
        bool load_commandline_options_static(std::string const& mod,
305
            hpx::program_options::options_description& options, error_code& ec);
306

307
        // Load all plugins from the ini files found in the configuration
308
        bool load_plugins(util::section& ini,
309
            hpx::program_options::options_description& options,
310
            std::set<std::string>& startup_handled);
311

312
#if !defined(HPX_HAVE_STATIC_LINKING)
313
        bool load_plugin(hpx::util::plugin::dll& d, util::section& ini,
314
            std::string const& instance, std::string const& component,
315
            filesystem::path const& lib, bool isenabled,
316
            hpx::program_options::options_description& options,
317
            std::set<std::string>& startup_handled);
318
        bool load_plugin_dynamic(util::section& ini,
319
            std::string const& instance, std::string const& component,
320
            filesystem::path lib, bool isenabled,
321
            hpx::program_options::options_description& options,
322
            std::set<std::string>& startup_handled);
323
#endif
324

325
        // the name says it all
326
        std::size_t dijkstra_termination_detection(
327
            std::vector<hpx::id_type> const& locality_ids);
328

329
#if defined(HPX_HAVE_NETWORKING)
330
        void send_dijkstra_termination_token(std::uint32_t target_locality_id,
331
            std::uint32_t initiating_locality_id, std::uint32_t num_localities,
332
            bool dijkstra_token);
333
#endif
334

335
    private:
336
        std::mutex mtx_;
337
        std::condition_variable wait_condition_;
338
        std::condition_variable stop_condition_;
339
        bool stop_called_;
340
        bool stop_done_;
341
        bool terminated_;
342
        std::thread::id main_thread_id_;
343
        std::atomic<bool> shutdown_all_invoked_;
344

345
#if defined(HPX_HAVE_NETWORKING)
346
        using dijkstra_mtx_type = hpx::spinlock;
347
        dijkstra_mtx_type dijkstra_mtx_;
348
        std::unique_ptr<hpx::latch> dijkstra_cond_;
349
        std::atomic<bool> dijkstra_color_;    // false: white, true: black
350
#endif
351

352
        plugin_map_mutex_type p_mtx_;
353

354
        plugin_map_type plugins_;
355
        modules_map_type& modules_;
356
        static_modules_type static_modules_;
357

358
        hpx::spinlock globals_mtx_;
359
        std::list<startup_function_type> pre_startup_functions_;
360
        std::list<startup_function_type> startup_functions_;
361
        std::list<shutdown_function_type> pre_shutdown_functions_;
362
        std::list<shutdown_function_type> shutdown_functions_;
363
    };
364

365
    ///////////////////////////////////////////////////////////////////////////
366
    // Functions wrapped by create_component actions below
367
#if defined(__NVCC__)
368
    template <typename Component>
369
    naming::gid_type runtime_support::create_component()
370
    {
371
        HPX_ASSERT(false);
372
        return naming::gid_type();
373
    }
374

375
    template <typename Component, typename T, typename... Ts>
376
    naming::gid_type runtime_support::create_component(T v, Ts... vs)
377
    {
378
        HPX_ASSERT(false);
379
        return naming::gid_type();
380
    }
381
#else
382
    template <typename Component>
383
    naming::gid_type runtime_support::create_component()
384
    {
385
        components::component_type const type =
386
            components::get_component_type<typename Component::wrapped_type>();
387

388
        using wrapping_type = typename Component::wrapping_type;
×
389
        naming::gid_type id = create<wrapping_type>();
390
        LRT_(info).format("successfully created component {} of type: {}", id,
391
            components::get_component_type_name(type));
392

393
        return id;
394
    }
×
395

×
396
    template <typename Component, typename T, typename... Ts>
397
    naming::gid_type runtime_support::create_component(T v, Ts... vs)
398
    {
×
399
        components::component_type const type =
400
            components::get_component_type<typename Component::wrapped_type>();
401

402
        using wrapping_type = typename Component::wrapping_type;
×
403
        // Note, T and Ts can't be (non-const) references, and parameters
404
        // should be moved to allow for move-only constructor argument
405
        // types.
406
        naming::gid_type id =
407
            create<wrapping_type>(HPX_MOVE(v), HPX_MOVE(vs)...);
408

409
        LRT_(info).format("successfully created component {} of type: {}", id,
410
            components::get_component_type_name(type));
411

×
412
        return id;
413
    }
414
#endif
×
415

416
    template <typename Component, typename... Ts>
417
    std::vector<naming::gid_type> runtime_support::bulk_create_component(
×
418
        std::size_t count, Ts... vs)
419
    {
420
        components::component_type const type =
421
            components::get_component_type<typename Component::wrapped_type>();
422

×
423
        std::vector<naming::gid_type> ids;
424
        ids.reserve(count);
425

426
        using wrapping_type = typename Component::wrapping_type;
427
        for (std::size_t i = 0; i != count; ++i)
428
        {
×
429
            ids.push_back(create<wrapping_type>(vs...));
×
430
        }
431

432
        LRT_(info).format("successfully created {} component(s) of type: {}",
×
433
            count, components::get_component_type_name(type));
434

×
435
        return ids;
436
    }
437

×
438
    namespace detail {
439

440
        template <typename Component, typename... Ts>
×
441
        std::vector<naming::gid_type> bulk_create_component_with_count_helper(
442
            std::size_t count, std::size_t first, Ts... vs)
443
        {
444
            components::component_type const type =
1✔
445
                components::get_component_type<
446
                    typename Component::wrapped_type>();
447

448
            std::vector<naming::gid_type> ids;
449
            ids.reserve(count);
450

1✔
451
            using wrapping_type = typename Component::wrapping_type;
1✔
452
            for (std::size_t i = 0; i != count; ++i)
453
            {
454
                ids.push_back(create<wrapping_type>(first + i, vs...));
2✔
455
            }
456

2✔
457
            LRT_(info).format(
458
                "successfully created {} component(s) of type: {}", count,
459
                components::get_component_type_name(type));
1✔
460

461
            return ids;
462
        }
1✔
463
    }    // namespace detail
464

465
    template <typename Component, typename... Ts>
466
    std::vector<naming::gid_type>
×
467
    runtime_support::bulk_create_component_with_count(
468
        std::size_t count, Ts... vs)
469
    {
470
        return detail::bulk_create_component_with_count_helper<Component>(
471
            count, HPX_MOVE(vs)...);
472
    }
473

×
474
    template <typename Component>
475
    naming::gid_type runtime_support::copy_create_component(
×
476
        std::shared_ptr<Component> const& p, bool local_op)
477
    {
×
478
        components::component_type const type =
479
            components::get_component_type<typename Component::wrapped_type>();
480

481
        using wrapping_type = typename Component::wrapping_type;
×
482
        naming::gid_type id;
483

484
        if (!local_op)
×
485
        {
486
            id = create<wrapping_type>(HPX_MOVE(*p));
487
        }
×
488
        else
489
        {
490
            id = create<wrapping_type>(*p);
491
        }
492

493
        LRT_(info).format("successfully created component {} of type: {}", id,
494
            components::get_component_type_name(type));
495

496
        return id;
497
    }
498

499
    ///////////////////////////////////////////////////////////////////////////
500
    template <typename Component>
501
    naming::gid_type runtime_support::migrate_component_to_here(
502
        std::shared_ptr<Component> const& p, hpx::id_type to_migrate)
503
    {
504
        components::component_type const type =
505
            components::get_component_type<typename Component::wrapped_type>();
506

507
        // create a local instance by copying the bits and remapping the id in
508
        // AGAS
509
        naming::gid_type migrated_id = to_migrate.get_gid();
510

511
        using wrapping_type = typename Component::wrapping_type;
512
        typename wrapping_type::derived_type* new_instance = nullptr;
513

514
        naming::gid_type id = create_migrated<wrapping_type>(
515
            migrated_id, reinterpret_cast<void**>(&new_instance), HPX_MOVE(*p));
516

517
        // sanity checks
518
        if (!id || new_instance == nullptr)
519
        {
520
            // we should not get here (id should not be invalid)
521
            HPX_THROW_EXCEPTION(hpx::error::invalid_status,
522
                "runtime_support::migrate_component_to_here",
523
                "could not create copy of given component");
524
        }
525
        if (id != migrated_id)
526
        {
527
            // we should not get here either (the ids should be the same)
528
            HPX_THROW_EXCEPTION(hpx::error::invalid_status,
529
                "runtime_support::migrate_component_to_here",
530
                "could not create copy of given component (the new id is "
531
                "different from the original id)");
532
        }
533

534
        LRT_(info).format(
535
            "successfully migrated component {} of type: {} to locality: {}",
536
            id, components::get_component_type_name(type), find_here());
537

538
        // At this point the object has been fully migrated. We now remove
539
        // the object from the AGAS table of migrated objects. This is
540
        // necessary as this object might have been migrated off this locality
541
        // before it was migrated back.
542
        agas::unmark_as_migrated(id, [&] {
543
            // inform the newly created component that it has been migrated
544
            new_instance->on_migrated();
545
        });
546

547
        to_migrate.make_unmanaged();
548

549
        return id;
550
    }
551
}    // namespace hpx::components::server
552

553
#include <hpx/config/warnings_suffix.hpp>
554

555
HPX_ACTION_USES_LARGE_STACK(
556
    hpx::components::server::runtime_support::load_components_action)
557
HPX_ACTION_USES_MEDIUM_STACK(
558
    hpx::components::server::runtime_support::call_startup_functions_action)
559
HPX_ACTION_USES_MEDIUM_STACK(
560
    hpx::components::server::runtime_support::call_shutdown_functions_action)
561
HPX_ACTION_USES_MEDIUM_STACK(
562
    hpx::components::server::runtime_support::shutdown_action)
563
HPX_ACTION_USES_MEDIUM_STACK(
564
    hpx::components::server::runtime_support::shutdown_all_action)
565
HPX_ACTION_USES_MEDIUM_STACK(
566
    hpx::components::server::runtime_support::create_performance_counter_action)
567
#if defined(HPX_HAVE_NETWORKING)
568
HPX_ACTION_USES_MEDIUM_STACK(
569
    hpx::components::server::runtime_support::dijkstra_termination_action)
570
#endif
571

572
HPX_REGISTER_ACTION_DECLARATION(
573
    hpx::components::server::runtime_support::load_components_action,
574
    load_components_action)
575
HPX_REGISTER_ACTION_DECLARATION(
576
    hpx::components::server::runtime_support::call_startup_functions_action,
577
    call_startup_functions_action)
578
HPX_REGISTER_ACTION_DECLARATION(
579
    hpx::components::server::runtime_support::call_shutdown_functions_action,
580
    call_shutdown_functions_action)
581
HPX_REGISTER_ACTION_DECLARATION(
582
    hpx::components::server::runtime_support::shutdown_action, shutdown_action)
583
HPX_REGISTER_ACTION_DECLARATION(
584
    hpx::components::server::runtime_support::shutdown_all_action,
585
    shutdown_all_action)
586
HPX_REGISTER_ACTION_DECLARATION(
587
    hpx::components::server::runtime_support::terminate_action,
588
    terminate_action)
589
HPX_REGISTER_ACTION_DECLARATION(
590
    hpx::components::server::runtime_support::terminate_all_action,
591
    terminate_all_action)
592
HPX_REGISTER_ACTION_DECLARATION(
593
    hpx::components::server::runtime_support::get_config_action,
594
    get_config_action)
595
HPX_REGISTER_ACTION_DECLARATION(
596
    hpx::components::server::runtime_support::garbage_collect_action,
597
    garbage_collect_action)
598
HPX_REGISTER_ACTION_DECLARATION(
599
    hpx::components::server::runtime_support::create_performance_counter_action,
600
    create_performance_counter_action)
601
HPX_REGISTER_ACTION_DECLARATION(hpx::components::server::runtime_support::
602
                                    remove_from_connection_cache_action,
603
    remove_from_connection_cache_action)
604
#if defined(HPX_HAVE_NETWORKING)
605
HPX_REGISTER_ACTION_DECLARATION(
606
    hpx::components::server::runtime_support::dijkstra_termination_action,
607
    dijkstra_termination_action)
608
#endif
609

610
namespace hpx::components::server {
611

612
    template <typename Component, typename... Ts>
613
    struct create_component_action
614
      : ::hpx::actions::action<naming::gid_type (runtime_support::*)(Ts...),
615
            &runtime_support::create_component<Component, Ts...>,
616
            create_component_action<Component, Ts...>>
617
    {
618
    };
619

620
    template <typename Component>
621
    struct create_component_action<Component>
622
      : ::hpx::actions::action<naming::gid_type (runtime_support::*)(),
623
            &runtime_support::create_component<Component>,
624
            create_component_action<Component>>
625
    {
626
    };
627

628
    template <typename Component, typename... Ts>
629
    struct create_component_direct_action
630
      : ::hpx::actions::direct_action<naming::gid_type (runtime_support::*)(
631
                                          Ts...),
632
            &runtime_support::create_component<Component, Ts...>,
633
            create_component_direct_action<Component, Ts...>>
634
    {
635
    };
636

637
    template <typename Component>
638
    struct create_component_direct_action<Component>
639
      : ::hpx::actions::direct_action<naming::gid_type (runtime_support::*)(),
640
            &runtime_support::create_component<Component>,
641
            create_component_direct_action<Component>>
642
    {
643
    };
644

645
    ///////////////////////////////////////////////////////////////////////////
646
    template <bool WithCount, typename Component, typename... Ts>
647
    struct bulk_create_component_action
648
      : ::hpx::actions::action<std::vector<naming::gid_type> (
649
                                   runtime_support::*)(std::size_t, Ts...),
650
            &runtime_support::bulk_create_component<Component, Ts...>,
651
            bulk_create_component_action<WithCount, Component, Ts...>>
652
    {
653
    };
654

655
    template <typename Component, typename... Ts>
656
    struct bulk_create_component_action<true, Component, Ts...>
657
      : ::hpx::actions::action<std::vector<naming::gid_type> (
658
                                   runtime_support::*)(std::size_t, Ts...),
659
            &runtime_support::bulk_create_component_with_count<Component,
660
                Ts...>,
661
            bulk_create_component_action<true, Component, Ts...>>
662
    {
663
    };
664

665
    template <bool WithCount, typename Component, typename... Ts>
666
    struct bulk_create_component_direct_action
667
      : ::hpx::actions::direct_action<std::vector<naming::gid_type> (
668
                                          runtime_support::*)(
669
                                          std::size_t, Ts...),
670
            &runtime_support::bulk_create_component<Component, Ts...>,
671
            bulk_create_component_direct_action<WithCount, Component, Ts...>>
672
    {
673
    };
674

675
    template <typename Component, typename... Ts>
676
    struct bulk_create_component_direct_action<true, Component, Ts...>
677
      : ::hpx::actions::direct_action<std::vector<naming::gid_type> (
678
                                          runtime_support::*)(
679
                                          std::size_t, Ts...),
680
            &runtime_support::bulk_create_component_with_count<Component,
681
                Ts...>,
682
            bulk_create_component_direct_action<true, Component, Ts...>>
683
    {
684
    };
685

686
    ///////////////////////////////////////////////////////////////////////////
687
    template <typename Component>
688
    struct copy_create_component_action
689
      : ::hpx::actions::action<naming::gid_type (runtime_support::*)(
690
                                   std::shared_ptr<Component> const&, bool),
691
            &runtime_support::copy_create_component<Component>,
692
            copy_create_component_action<Component>>
693
    {
694
    };
695
    template <typename Component>
696
    struct migrate_component_here_action
697
      : ::hpx::actions::action<naming::gid_type (runtime_support::*)(
698
                                   std::shared_ptr<Component> const&,
699
                                   hpx::id_type),
700
            &runtime_support::migrate_component_to_here<Component>,
701
            migrate_component_here_action<Component>>
702
    {
703
    };
704
}    // namespace hpx::components::server
705

706
///////////////////////////////////////////////////////////////////////////
707
// Termination detection does not make this locality black
708
#if !defined(HPX_COMPUTE_DEVICE_CODE) && defined(HPX_HAVE_NETWORKING)
709
template <>
710
struct hpx::traits::action_does_termination_detection<
711
    hpx::components::server::runtime_support::dijkstra_termination_action>
712
{
713
    static constexpr bool call() noexcept
714
    {
715
        return true;
716
    }
717
};
718
#endif
719

720
// runtime_support is a (hand-rolled) component
721
template <>
722
struct hpx::traits::is_component<hpx::components::server::runtime_support>
723
  : std::true_type
724
{
725
};
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