/home/users/khuck/src/hpx-lsu/hpx/runtime/components/component_factory.hpp

Line% of fetchesSource
1  
//  Copyright (c) 2007-2015 Hartmut Kaiser
2  
//  Copyright (c) 2011      Bryce Lelbach
3  
//
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 hpx/runtime/components/component_factory.hpp
8  
9  
#ifndef HPX_RUNTIME_COMPONENTS_COMPONENT_FACTORY_HPP
10  
#define HPX_RUNTIME_COMPONENTS_COMPONENT_FACTORY_HPP
11  
12  
#ifdef DOXYGEN
13  
/// \def HPX_REGISTER_COMPONENT(type, name, mode)
14  
///
15  
/// \brief Define a component factory for a component type
16  
///
17  
/// This macro is used create and to register a minimal component factory for
18  
/// a component type which allows it to be remotely created using the
19  
/// \a hpx::new_<> function.
20  
///
21  
/// This macro can be invoked with one, two or three arguments
22  
///
23  
/// \param type The \a type parameter is a (fully decorated) type of the
24  
///             component type for which a factory should be defined.
25  
///
26  
/// \param name The \a name parameter specifies the name to use to register
27  
///             the factory. This should uniquely (system-wide) identify the
28  
///             component type. The \a name parameter must conform to the C++
29  
///             identifier rules (without any namespace).
30  
///             If this parameter is not given, the first parameter is used.
31  
///
32  
/// \param mode The \a mode parameter has to be one of the defined enumeration
33  
///             values of the enumeration \a hpx::components::factory_state_enum.
34  
///             The default for this parameter is
35  
///             \a hpx::components::factory_enabled.
36  
///
37  
#define HPX_REGISTER_COMPONENT(type, name, mode)
38  
39  
#else
40  
41  
#include <hpx/config.hpp>
42  
#include <hpx/runtime/components/component_factory_base.hpp>
43  
#include <hpx/runtime/components/component_registry.hpp>
44  
#include <hpx/runtime/components/component_type.hpp>
45  
#include <hpx/runtime/components/server/create_component.hpp>
46  
#include <hpx/runtime/components/server/destroy_component.hpp>
47  
#include <hpx/runtime/components/unique_component_name.hpp>
48  
#include <hpx/runtime/naming/address.hpp>
49  
#include <hpx/runtime/naming/name.hpp>
50  
#include <hpx/runtime/naming/resolver_client.hpp>
51  
#include <hpx/throw_exception.hpp>
52  
#include <hpx/util/atomic_count.hpp>
53  
#include <hpx/util/detail/count_num_args.hpp>
54  
#include <hpx/util/ini.hpp>
55  
#include <hpx/util/unique_function.hpp>
56  
57  
#include <boost/preprocessor/cat.hpp>
58  
59  
#include <cstddef>
60  
#include <string>
61  
62  
///////////////////////////////////////////////////////////////////////////////
63  
namespace hpx { namespace components
64  
{
65  
    ///////////////////////////////////////////////////////////////////////////
66  
    /// The \a component_factory provides a minimal implementation of a
67  
    /// component's factory. If no additional functionality is required this
68  
    /// type can be used to implement the full set of minimally required
69  
    /// functions to be exposed by a component's factory instance.
70  
    ///
71  
    /// \tparam Component   The component type this factory should be
72  
    ///                     responsible for.
73  
    template <typename Component>
74  
    struct component_factory : public component_factory_base
75  
    {
76  
        /// \brief Construct a new factory instance
77  
        ///
78  
        /// \param global   [in] The pointer to a \a hpx#util#section instance
79  
        ///                 referencing the settings read from the [settings]
80  
        ///                 section of the global configuration file (hpx.ini)
81  
        ///                 This pointer may be nullptr if no such section has
82  
        ///                 been found.
83  
        /// \param local    [in] The pointer to a \a hpx#util#section instance
84  
        ///                 referencing the settings read from the section
85  
        ///                 describing this component type:
86  
        ///                 [hpx.components.\<name\>], where \<name\> is the
87  
        ///                 instance name of the component as given in the
88  
        ///                 configuration files.
89  
        ///
90  
        /// \note The contents of both sections has to be cloned in order to
91  
        ///       save the configuration setting for later use.
92  
        component_factory(util::section const* global,
93  
                util::section const* local, bool isenabled)
94  
          : isenabled_(isenabled), refcnt_(0)
95  
        {
96  
            // store the configuration settings
97  
            if (nullptr != global)
98  
                global_settings_ = *global;
99  
            if (nullptr != local)
100  
                local_settings_ = *local;
101  
        }
102  
103  
        /// Destruct a \a component_factory instance
104  
        ~component_factory() {}
105  
106  
        /// \brief Return the unique identifier of the component type this
107  
        ///        factory is responsible for
108  
        ///
109  
        /// \param locality     [in] The id of the locality this factory
110  
        ///                     is responsible for.
111  
        /// \param agas_client  [in] The AGAS client to use for component id
112  
        ///                     registration (if needed).
113  
        ///
114  
        /// \return Returns the unique identifier of the component type this
115  
        ///         factory instance is responsible for. This function throws
116  
        ///         on any error.
117  
        component_type get_component_type(naming::gid_type const& locality,
118  
            naming::resolver_client& agas_client)
119  
        {
120  
            typedef typename Component::type_holder type_holder;
121  
            if (component_invalid == components::get_component_type<type_holder>())
122  
            {
123  
                // First call to get_component_type, ask AGAS for a unique id.
124  
                if (isenabled_) {
125  
                    component_type const ctype =
126  
                        agas_client.register_factory(locality, get_component_name());
127  
128  
                    if (component_invalid == ctype) {
129  
                        HPX_THROW_EXCEPTION(duplicate_component_id,
130  
                            "component_factory::get_component_type",
131  
                            "the component name " + get_component_name() +
132  
                            " is already in use");
133  
                    }
134  
                    components::set_component_type<type_holder>(ctype);
135  
                }
136  
                else {
137  
                    component_type const ctype =
138  
                        agas_client.get_component_id(get_component_name());
139  
140  
                    components::set_component_type<type_holder>(ctype);
141  
                }
142  
            }
143  
            return components::get_component_type<type_holder>();
144  
        }
145  
146  
        /// \brief Return the name of the component type this factory is
147  
        ///        responsible for
148  
        ///
149  
        /// \return Returns the name of the component type this factory
150  
        ///         instance is responsible for. This function throws on any
151  
        ///         error.
152  
        std::string get_component_name() const
153  
        {
154  
            return unique_component_name<component_factory>::call();
155  
        }
156  
157  
        /// \brief Create one or more new component instances.
158  
        ///
159  
        /// \param count  [in] The number of component instances to
160  
        ///               create. The value of this parameter should not
161  
        ///               be zero.
162  
        ///
163  
        /// \return Returns the GID of the first newly created component
164  
        ///         instance. If more than one component instance has been
165  
        ///         created (\a count > 1) the GID's of all new instances are
166  
        ///         sequential in a row.
167  
        naming::gid_type create(std::size_t count = 1)
168  
        {
169  
            if (isenabled_)
170  
            {
171  
                naming::gid_type id = server::create<Component>(count);
172  
                if (id)
173  
                    ++refcnt_;
174  
                return id;
175  
            }
176  
177  
            HPX_THROW_EXCEPTION(bad_request,
178  
                "component_factory::create",
179  
                "this factory instance is disabled for this locality (" +
180  
                get_component_name() + ")");
181  
            return naming::invalid_gid;
182  
        }
183  
184  
        /// \brief Create one new component instance and initialize it using
185  
        ///        the using the given constructor function.
186  
        ///
187  
        /// \param ctor  [in] The constructor function to call in order to
188  
        ///              initialize the newly allocated object.
189  
        ///
190  
        /// \return   Returns the GID of the first newly created component
191  
        ///           instance.
192  
        naming::gid_type create_with_args(
193  
            util::unique_function_nonser<void(void*)> const& ctor)
194  
        {
195  
            if (isenabled_)
196  
            {
197  
                naming::gid_type id = server::create<Component>(ctor);
198  
                if (id)
199  
                    ++refcnt_;
200  
                return id;
201  
            }
202  
203  
            HPX_THROW_EXCEPTION(bad_request,
204  
                "component_factory::create_with_args",
205  
                "this factory instance is disabled for this locality (" +
206  
                get_component_name() + ")");
207  
            return naming::invalid_gid;
208  
        }
209  
210  
        /// \brief Create one new component instance and initialize it using
211  
        ///        the using the given constructor function. Assign the give
212  
        ///        GID to the new object.
213  
        ///
214  
        /// \param assign_gid [in] The GID to assign to the newly created object.
215  
        /// \param ctor       [in] The constructor function to call in order to
216  
        ///                   initialize the newly allocated object.
217  
        ///
218  
        /// \return   Returns the GID of the first newly created component
219  
        ///           instance (this is the same as assign_gid, if successful).
220  
        naming::gid_type create_with_args(
221  
            naming::gid_type const& assign_gid,
222  
            util::unique_function_nonser<void(void*)> const& ctor)
223  
        {
224  
            if (isenabled_)
225  
            {
226  
                naming::gid_type id =
227  
                    server::create<Component>(assign_gid, ctor);
228  
                if (id)
229  
                    ++refcnt_;
230  
                return id;
231  
            }
232  
233  
            HPX_THROW_EXCEPTION(bad_request,
234  
                "component_factory::create_with_args",
235  
                "this factory instance is disabled for this locality (" +
236  
                get_component_name() + ")");
237  
            return naming::invalid_gid;
238  
        }
239  
240  
        /// \brief Destroy one or more component instances
241  
        ///
242  
        /// \param gid    [in] The gid of the first component instance to
243  
        ///               destroy.
244  
        /// \param addr   [in] The resolved address of the first component
245  
        ///               instance to destroy.
246  
        void destroy(naming::gid_type const& gid,
247  
            naming::address const& addr)
248  
        {
249  
            server::destroy<Component>(gid, addr);
250  
            --refcnt_;
251  
        }
252  
253  
        /// \brief Ask how many instances are alive of the type this factory is
254  
        ///        responsible for
255  
        ///
256  
        /// \return Returns the number of instances of the managed object type
257  
        ///         which are currently alive.
258  
        long instance_count() const
259  
        {
260  
            return refcnt_;
261  
        }
262  
263  
#if defined(HPX_HAVE_SECURITY)
264  
        /// \brief Return the required capabilities necessary to create an
265  
        ///        instance of a component using this factory instance.
266  
        ///
267  
        /// \return Returns required capabilities necessary to create a new
268  
        ///         instance of a component using this factory instance.
269  
        virtual components::security::capability
270  
            get_required_capabilities() const
271  
        {
272  
            using namespace components::security;
273  
            return Component::get_required_capabilities(
274  
                traits::capability<>::capability_create_component);
275  
        }
276  
#endif
277  
278  
    protected:
279  
        util::section global_settings_;
280  
        util::section local_settings_;
281  
        bool isenabled_;
282  
283  
        // count outstanding instances to avoid premature unloading
284  
        util::atomic_count refcnt_;
285  
    };
286  
}}
287  
288  
///////////////////////////////////////////////////////////////////////////////
289  
// This macro is used create and to register a minimal component factory with
290  
// Hpx.Plugin.
291  
#define HPX_REGISTER_MINIMAL_COMPONENT_FACTORY(...)                           \
292  
    HPX_REGISTER_MINIMAL_COMPONENT_FACTORY_(__VA_ARGS__)                      \
293  
/**/
294  
295  
#define HPX_REGISTER_COMPONENT(...)                                           \
296  
    HPX_REGISTER_MINIMAL_COMPONENT_FACTORY_(__VA_ARGS__)                      \
297  
/**/
298  
299  
#define HPX_REGISTER_ENABLED_COMPONENT_FACTORY(ComponentType, componentname)  \
300  
        HPX_REGISTER_MINIMAL_COMPONENT_FACTORY_3(                             \
301  
            ComponentType, componentname, ::hpx::components::factory_enabled) \
302  
        HPX_DEFINE_GET_COMPONENT_TYPE(ComponentType::wrapped_type)            \
303  
/**/
304  
305  
#define HPX_REGISTER_DISABLED_COMPONENT_FACTORY(ComponentType, componentname) \
306  
        HPX_REGISTER_MINIMAL_COMPONENT_FACTORY_3(                             \
307  
            ComponentType, componentname, ::hpx::components::factory_disabled)\
308  
        HPX_DEFINE_GET_COMPONENT_TYPE(ComponentType::wrapped_type)            \
309  
/**/
310  
311  
///////////////////////////////////////////////////////////////////////////////
312  
#define HPX_REGISTER_MINIMAL_COMPONENT_FACTORY_(...)                          \
313  
    HPX_UTIL_EXPAND_(BOOST_PP_CAT(                                            \
314  
        HPX_REGISTER_MINIMAL_COMPONENT_FACTORY_, HPX_UTIL_PP_NARG(__VA_ARGS__)\
315  
    )(__VA_ARGS__))                                                           \
316  
/**/
317  
#define HPX_REGISTER_MINIMAL_COMPONENT_FACTORY_1(ComponentType)               \
318  
    HPX_REGISTER_MINIMAL_COMPONENT_FACTORY_3(                                 \
319  
        ComponentType, ComponentType, ::hpx::components::factory_check)       \
320  
    HPX_DEFINE_GET_COMPONENT_TYPE(ComponentType::wrapped_type)                \
321  
/**/
322  
#define HPX_REGISTER_MINIMAL_COMPONENT_FACTORY_2(ComponentType, componentname)\
323  
    HPX_REGISTER_MINIMAL_COMPONENT_FACTORY_3(                                 \
324  
        ComponentType, componentname, ::hpx::components::factory_check)       \
325  
    HPX_DEFINE_GET_COMPONENT_TYPE(ComponentType::wrapped_type)                \
326  
/**/
327  
#define HPX_REGISTER_MINIMAL_COMPONENT_FACTORY_3(                             \
328  
        ComponentType, componentname, state)                                  \
329  
    HPX_REGISTER_COMPONENT_FACTORY(                                           \
330  
        hpx::components::component_factory<ComponentType>, componentname)     \
331  
    HPX_DEF_UNIQUE_COMPONENT_NAME(                                            \
332  
        hpx::components::component_factory<ComponentType>, componentname)     \
333  
    template struct hpx::components::component_factory<ComponentType>;        \
334  
    HPX_REGISTER_MINIMAL_COMPONENT_REGISTRY_3(                                \
335  
        ComponentType, componentname, state)                                  \
336  
/**/
337  
338  
///////////////////////////////////////////////////////////////////////////////
339  
#define HPX_REGISTER_MINIMAL_COMPONENT_FACTORY_DYNAMIC(...)                   \
340  
    HPX_REGISTER_MINIMAL_COMPONENT_FACTORY_DYNAMIC_(__VA_ARGS__)              \
341  
/**/
342  
343  
// same as above, just a better name
344  
345  
/// This macro is used create and to register a minimal component factory for
346  
/// a component type which allows it to be remotely created using the
347  
/// hpx::new_<> function.
348  
/// This macro can be invoked with one, two or three arguments
349  
#define HPX_REGISTER_COMPONENT_DYNAMIC(...)                                   \
350  
    HPX_REGISTER_MINIMAL_COMPONENT_FACTORY_DYNAMIC_(__VA_ARGS__)              \
351  
/**/
352  
353  
#define HPX_REGISTER_ENABLED_COMPONENT_FACTORY_DYNAMIC(ComponentType,         \
354  
            componentname)                                                    \
355  
        HPX_REGISTER_MINIMAL_COMPONENT_FACTORY_DYNAMIC_3(                     \
356  
            ComponentType, componentname, ::hpx::components::factory_enabled) \
357  
        HPX_DEFINE_GET_COMPONENT_TYPE(ComponentType::wrapped_type)            \
358  
/**/
359  
360  
#define HPX_REGISTER_DISABLED_COMPONENT_FACTORY_DYNAMIC(ComponentType,        \
361  
            componentname)                                                    \
362  
        HPX_REGISTER_MINIMAL_COMPONENT_FACTORY_DYNAMIC_3(                     \
363  
            ComponentType, componentname, ::hpx::components::factory_disabled)\
364  
        HPX_DEFINE_GET_COMPONENT_TYPE(ComponentType::wrapped_type)            \
365  
/**/
366  
367  
368  
#define HPX_REGISTER_MINIMAL_COMPONENT_FACTORY_DYNAMIC_(...)                  \
369  
    HPX_UTIL_EXPAND_(BOOST_PP_CAT(                                            \
370  
        HPX_REGISTER_MINIMAL_COMPONENT_FACTORY_DYNAMIC_,                      \
371  
            HPX_UTIL_PP_NARG(__VA_ARGS__)                                     \
372  
    )(__VA_ARGS__))                                                           \
373  
/**/
374  
#define HPX_REGISTER_MINIMAL_COMPONENT_FACTORY_DYNAMIC_1(ComponentType)       \
375  
    HPX_REGISTER_MINIMAL_COMPONENT_FACTORY_DYNAMIC_3(                         \
376  
        ComponentType, ComponentType, ::hpx::components::factory_check)       \
377  
    HPX_DEFINE_GET_COMPONENT_TYPE(ComponentType::wrapped_type)                \
378  
/**/
379  
#define HPX_REGISTER_MINIMAL_COMPONENT_FACTORY_DYNAMIC_2(ComponentType,       \
380  
        componentname)                                                        \
381  
    HPX_REGISTER_MINIMAL_COMPONENT_FACTORY_DYNAMIC_3(                         \
382  
        ComponentType, componentname, ::hpx::components::factory_check)       \
383  
    HPX_DEFINE_GET_COMPONENT_TYPE(ComponentType::wrapped_type)                \
384  
/**/
385  
#define HPX_REGISTER_MINIMAL_COMPONENT_FACTORY_DYNAMIC_3(                     \
386  
        ComponentType, componentname, state)                                  \
387  
    HPX_REGISTER_COMPONENT_FACTORY_DYNAMIC(                                   \
388  
        hpx::components::component_factory<ComponentType>, componentname)     \
389  
    HPX_DEF_UNIQUE_COMPONENT_NAME(                                            \
390  
        hpx::components::component_factory<ComponentType>, componentname)     \
391  
    template struct hpx::components::component_factory<ComponentType>;        \
392  
    HPX_REGISTER_MINIMAL_COMPONENT_REGISTRY_DYNAMIC_3(                        \
393  
        ComponentType, componentname, state)                                  \
394  
/**/
395  
396  
#endif
397  
398  
#endif /*HPX_RUNTIME_COMPONENTS_COMPONENT_FACTORY_HPP*/
399  

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