Line | % of fetches | Source |
---|---|---|
1 | // Copyright (c) 2007-2016 Hartmut Kaiser | |
2 | // Copyright (c) 2011 Thomas Heller | |
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 | #if !defined(HPX_COMPONENTS_MANAGED_COMPONENT_BASE_JUN_04_2008_0902PM) | |
8 | #define HPX_COMPONENTS_MANAGED_COMPONENT_BASE_JUN_04_2008_0902PM | |
9 | ||
10 | #include <hpx/config.hpp> | |
11 | ||
12 | #include <hpx/runtime/components/component_type.hpp> | |
13 | #include <hpx/runtime/components/server/create_component_fwd.hpp> | |
14 | #include <hpx/runtime/components/server/wrapper_heap.hpp> | |
15 | #include <hpx/runtime/components/server/wrapper_heap_list.hpp> | |
16 | #include <hpx/runtime/components_fwd.hpp> | |
17 | #include <hpx/throw_exception.hpp> | |
18 | #include <hpx/traits/is_component.hpp> | |
19 | #include <hpx/traits/managed_component_policies.hpp> | |
20 | #include <hpx/util/reinitializable_static.hpp> | |
21 | #include <hpx/util/unique_function.hpp> | |
22 | ||
23 | #include <cstddef> | |
24 | #include <cstdint> | |
25 | #include <sstream> | |
26 | #include <stdexcept> | |
27 | #include <type_traits> | |
28 | #include <utility> | |
29 | ||
30 | /////////////////////////////////////////////////////////////////////////////// | |
31 | namespace hpx { namespace components | |
32 | { | |
33 | template <typename Component, typename Derived> | |
34 | class managed_component; | |
35 | ||
36 | /////////////////////////////////////////////////////////////////////////// | |
37 | namespace detail_adl_barrier | |
38 | { | |
39 | template <typename BackPtrTag> | |
40 | struct init; | |
41 | ||
42 | template <> | |
43 | struct init<traits::construct_with_back_ptr> | |
44 | { | |
45 | template <typename Component, typename Managed> | |
46 | static void call(Component* component, Managed* this_) | |
47 | { | |
48 | } | |
49 | ||
50 | template <typename Component, typename Managed, typename ...Ts> | |
51 | static void call_new(Component*& component, Managed* this_, Ts&&... vs) | |
52 | { | |
53 | typedef typename Managed::wrapped_type wrapped_type; | |
54 | component = new wrapped_type(this_, std::forward<Ts>(vs)...); | |
55 | } | |
56 | }; | |
57 | ||
58 | template <> | |
59 | struct init<traits::construct_without_back_ptr> | |
60 | { | |
61 | template <typename Component, typename Managed> | |
62 | static void call(Component* component, Managed* this_) | |
63 | { | |
64 | component->set_back_ptr(this_); | |
65 | } | |
66 | ||
67 | template <typename Component, typename Managed, typename ...Ts> | |
68 | static void call_new(Component*& component, Managed* this_, Ts&&... vs) | |
69 | { | |
70 | typedef typename Managed::wrapped_type wrapped_type; | |
71 | component = new wrapped_type(std::forward<Ts>(vs)...); | |
72 | component->set_back_ptr(this_); | |
73 | } | |
74 | }; | |
75 | ||
76 | /////////////////////////////////////////////////////////////////////// | |
77 | // This is used by the component implementation to decide whether to | |
78 | // delete the managed_component instance it depends on. | |
79 | template <typename DtorTag> | |
80 | struct destroy_backptr; | |
81 | ||
82 | template <> | |
83 | struct destroy_backptr<traits::managed_object_is_lifetime_controlled> | |
84 | { | |
85 | template <typename BackPtr> | |
86 | static void call(BackPtr* back_ptr) | |
87 | { | |
88 | // The managed_component's controls the lifetime of the | |
89 | // component implementation. | |
90 | delete back_ptr; | |
91 | } | |
92 | }; | |
93 | ||
94 | template <> | |
95 | struct destroy_backptr<traits::managed_object_controls_lifetime> | |
96 | { | |
97 | template <typename BackPtr> | |
98 | static void call(BackPtr*) | |
99 | { | |
100 | // The managed_component's lifetime is controlled by the | |
101 | // component implementation. Do nothing. | |
102 | } | |
103 | }; | |
104 | ||
105 | /////////////////////////////////////////////////////////////////////// | |
106 | // This is used by the managed_component to decide whether to | |
107 | // delete the component implementation depending on it. | |
108 | template <typename DtorTag> | |
109 | struct manage_lifetime; | |
110 | ||
111 | template <> | |
112 | struct manage_lifetime<traits::managed_object_is_lifetime_controlled> | |
113 | { | |
114 | template <typename Component> | |
115 | static void call(Component*) | |
116 | { | |
117 | // The managed_component's lifetime is controlled by the | |
118 | // component implementation. Do nothing. | |
119 | } | |
120 | ||
121 | template <typename Component> | |
122 | static void addref(Component* component) | |
123 | { | |
124 | intrusive_ptr_add_ref(component); | |
125 | } | |
126 | ||
127 | template <typename Component> | |
128 | static void release(Component* component) | |
129 | { | |
130 | intrusive_ptr_release(component); | |
131 | } | |
132 | }; | |
133 | ||
134 | template <> | |
135 | struct manage_lifetime<traits::managed_object_controls_lifetime> | |
136 | { | |
137 | template <typename Component> | |
138 | static void call(Component* component) | |
139 | { | |
140 | // The managed_component controls the lifetime of the | |
141 | // component implementation. | |
142 | component->finalize(); | |
143 | delete component; | |
144 | } | |
145 | ||
146 | template <typename Component> | |
147 | static void addref(Component*) | |
148 | { | |
149 | } | |
150 | ||
151 | template <typename Component> | |
152 | static void release(Component*) | |
153 | { | |
154 | } | |
155 | }; | |
156 | } | |
157 | ||
158 | /////////////////////////////////////////////////////////////////////////// | |
159 | template <typename Component, typename Wrapper, | |
160 | typename CtorPolicy, typename DtorPolicy> | |
161 | class managed_component_base | |
162 | : public traits::detail::managed_component_tag | |
163 | { | |
164 | HPX_NON_COPYABLE(managed_component_base); | |
165 | ||
166 | private: | |
167 | Component& derived() | |
168 | { | |
169 | return static_cast<Component&>(*this); | |
170 | } | |
171 | Component const& derived() const | |
172 | { | |
173 | return static_cast<Component const&>(*this); | |
174 | } | |
175 | ||
176 | public: | |
177 | typedef typename std::conditional< | |
178 | std::is_same<Component, detail::this_type>::value, | |
179 | managed_component_base, Component | |
180 | >::type this_component_type; | |
181 | ||
182 | typedef this_component_type wrapped_type; | |
183 | ||
184 | typedef void has_managed_component_base; | |
185 | typedef CtorPolicy ctor_policy; | |
186 | typedef DtorPolicy dtor_policy; | |
187 | ||
188 | // make sure that we have a back_ptr whenever we need to control the | |
189 | // lifetime of the managed_component | |
190 | static_assert(( | |
191 | std::is_same<ctor_policy, traits::construct_without_back_ptr>::value || | |
192 | std::is_same<dtor_policy, | |
193 | traits::managed_object_controls_lifetime>::value), | |
194 | "std::is_same<ctor_policy, traits::construct_without_back_ptr>::value || " | |
195 | "std::is_same<dtor_policy, " | |
196 | "traits::managed_object_controls_lifetime>::value"); | |
197 | ||
198 | managed_component_base() | |
199 | : back_ptr_(nullptr) | |
200 | {} | |
201 | ||
202 | managed_component_base(managed_component<Component, Wrapper>* back_ptr) | |
203 | : back_ptr_(back_ptr) | |
204 | { | |
205 | HPX_ASSERT(back_ptr); | |
206 | } | |
207 | ||
208 | // The implementation of the component is responsible for deleting the | |
209 | // actual managed component object | |
210 | ~managed_component_base() | |
211 | { | |
212 | detail_adl_barrier::destroy_backptr<dtor_policy>::call(back_ptr_); | |
213 | } | |
214 | ||
215 | // components must contain a typedef for wrapping_type defining the | |
216 | // managed_component type used to encapsulate instances of this | |
217 | // component | |
218 | typedef managed_component<Component, Wrapper> wrapping_type; | |
219 | typedef Component base_type_holder; | |
220 | ||
221 | /// \brief finalize() will be called just before the instance gets | |
222 | /// destructed | |
223 | void finalize() {} | |
224 | ||
225 | // This exposes the component type | |
226 | static component_type get_component_type() | |
227 | { | |
228 | return components::get_component_type<Component>(); | |
229 | } | |
230 | static void set_component_type(component_type type) | |
231 | { | |
232 | components::set_component_type<Component>(type); | |
233 | } | |
234 | ||
235 | naming::id_type get_unmanaged_id() const; | |
236 | naming::id_type get_id() const; | |
237 | ||
238 | #if defined(HPX_HAVE_COMPONENT_GET_GID_COMPATIBILITY) | |
239 | naming::id_type get_gid() const | |
240 | { | |
241 | return get_unmanaged_id(); | |
242 | } | |
243 | #endif | |
244 | ||
245 | protected: | |
246 | naming::gid_type get_base_gid() const; | |
247 | ||
248 | public: | |
249 | // Pinning functionality | |
250 | void pin() {} | |
251 | void unpin() {} | |
252 | std::uint32_t pin_count() const { return 0; } | |
253 | ||
254 | void mark_as_migrated() | |
255 | { | |
256 | // If this assertion is triggered then this component instance is | |
257 | // being migrated even if the component type has not been enabled | |
258 | // to support migration. | |
259 | HPX_ASSERT(false); | |
260 | } | |
261 | ||
262 | protected: | |
263 | template <typename> | |
264 | friend struct detail_adl_barrier::init; | |
265 | ||
266 | void set_back_ptr(components::managed_component<Component, Wrapper>* bp) | |
267 | { | |
268 | HPX_ASSERT(nullptr == back_ptr_); | |
269 | HPX_ASSERT(bp); | |
270 | back_ptr_ = bp; | |
271 | } | |
272 | ||
273 | private: | |
274 | managed_component<Component, Wrapper>* back_ptr_; | |
275 | }; | |
276 | ||
277 | /////////////////////////////////////////////////////////////////////////// | |
278 | namespace detail | |
279 | { | |
280 | /////////////////////////////////////////////////////////////////////// | |
281 | template <typename Component, typename Derived> | |
282 | struct heap_factory | |
283 | { | |
284 | // the memory for the wrappers is managed by a one_size_heap_list | |
285 | typedef detail::wrapper_heap_list< | |
286 | detail::fixed_wrapper_heap<Derived> > heap_type; | |
287 | ||
288 | typedef detail::fixed_wrapper_heap<Derived> block_type; | |
289 | typedef Derived value_type; | |
290 | ||
291 | private: | |
292 | struct wrapper_heap_tag {}; | |
293 | ||
294 | static heap_type& get_heap() | |
295 | { | |
296 | // ensure thread-safe initialization | |
297 | util::reinitializable_static< | |
298 | heap_type, wrapper_heap_tag | |
299 | > heap(components::get_component_type<Component>()); | |
300 | return heap.get(); | |
301 | } | |
302 | ||
303 | public: | |
304 | static void* alloc(std::size_t count = 1) | |
305 | { | |
306 | return get_heap().alloc(count); | |
307 | } | |
308 | static void free(void* p, std::size_t count = 1) | |
309 | { | |
310 | get_heap().free(p, count); | |
311 | } | |
312 | static naming::gid_type get_gid(void* p) | |
313 | { | |
314 | return get_heap().get_gid(p); | |
315 | } | |
316 | }; | |
317 | } | |
318 | // reference counting | |
319 | template <typename Component, typename Derived> | |
320 | void intrusive_ptr_add_ref(managed_component<Component, Derived>* p) | |
321 | { | |
322 | detail_adl_barrier::manage_lifetime< | |
323 | typename traits::managed_component_dtor_policy<Component>::type | |
324 | >::addref(p->component_); | |
325 | } | |
326 | template <typename Component, typename Derived> | |
327 | void intrusive_ptr_release(managed_component<Component, Derived>* p) | |
328 | { | |
329 | detail_adl_barrier::manage_lifetime< | |
330 | typename traits::managed_component_dtor_policy<Component>::type | |
331 | >::release(p->component_); | |
332 | } | |
333 | ||
334 | /////////////////////////////////////////////////////////////////////////// | |
335 | /// The managed_component template is used as a indirection layer | |
336 | /// for components allowing to gracefully handle the access to non-existing | |
337 | /// components. | |
338 | /// | |
339 | /// Additionally it provides memory management capabilities for the | |
340 | /// wrapping instances, and it integrates the memory management with the | |
341 | /// AGAS service. Every instance of a managed_component gets assigned | |
342 | /// a global id. | |
343 | /// The provided memory management allocates the managed_component | |
344 | /// instances from a special heap, ensuring fast allocation and avoids a | |
345 | /// full network round trip to the AGAS service for each of the allocated | |
346 | /// instances. | |
347 | /// | |
348 | /// \tparam Component | |
349 | /// \tparam Derived | |
350 | /// | |
351 | template <typename Component, typename Derived> | |
352 | class managed_component | |
353 | { | |
354 | HPX_NON_COPYABLE(managed_component); | |
355 | ||
356 | public: | |
357 | typedef typename std::conditional< | |
358 | std::is_same<Derived, detail::this_type>::value, | |
359 | managed_component, Derived | |
360 | >::type derived_type; | |
361 | ||
362 | typedef Component wrapped_type; | |
363 | typedef Component type_holder; | |
364 | typedef typename Component::base_type_holder base_type_holder; | |
365 | ||
366 | typedef detail::heap_factory<Component, derived_type> heap_type; | |
367 | typedef typename heap_type::value_type value_type; | |
368 | ||
369 | /// \brief Construct a managed_component instance holding a | |
370 | /// wrapped instance. This constructor takes ownership of the | |
371 | /// passed pointer. | |
372 | /// | |
373 | /// \param c [in] The pointer to the wrapped instance. The | |
374 | /// managed_component takes ownership of this pointer. | |
375 | explicit managed_component(Component* comp) | |
376 | : component_(comp) | |
377 | { | |
378 | detail_adl_barrier::init< | |
379 | typename traits::managed_component_ctor_policy<Component>::type | |
380 | >::call(component_, this); | |
381 | intrusive_ptr_add_ref(this); | |
382 | } | |
383 | ||
384 | public: | |
385 | /// \brief Construct a managed_component instance holding a new wrapped | |
386 | /// instance | |
387 | template <typename ...Ts> | |
388 | managed_component(Ts&&... vs) | |
389 | : component_(nullptr) | |
390 | { | |
391 | detail_adl_barrier::init< | |
392 | typename traits::managed_component_ctor_policy<Component>::type | |
393 | >::call_new(component_, this, std::forward<Ts>(vs)...); | |
394 | intrusive_ptr_add_ref(this); | |
395 | } | |
396 | ||
397 | public: | |
398 | /// \brief The destructor releases any wrapped instances | |
399 | ~managed_component() | |
400 | { | |
401 | intrusive_ptr_release(this); | |
402 | detail_adl_barrier::manage_lifetime< | |
403 | typename traits::managed_component_dtor_policy<Component>::type | |
404 | >::call(component_); | |
405 | } | |
406 | ||
407 | /// \brief finalize() will be called just before the instance gets | |
408 | /// destructed | |
409 | void finalize() {} // finalize the wrapped component in our destructor | |
410 | ||
411 | static component_type get_component_type() | |
412 | { | |
413 | return components::get_component_type<wrapped_type>(); | |
414 | } | |
415 | static void set_component_type(component_type t) | |
416 | { | |
417 | components::set_component_type<wrapped_type>(t); | |
418 | } | |
419 | ||
420 | /// \brief Return a pointer to the wrapped instance | |
421 | /// \note Caller must check validity of returned pointer | |
422 | Component* get() | |
423 | { | |
424 | return component_; | |
425 | } | |
426 | Component const* get() const | |
427 | { | |
428 | return component_; | |
429 | } | |
430 | ||
431 | Component* get_checked() | |
432 | { | |
433 | if (!component_) { | |
434 | std::ostringstream strm; | |
435 | strm << "component is nullptr (" | |
436 | << components::get_component_type_name( | |
437 | components::get_component_type<wrapped_type>()) | |
438 | << ") gid(" << get_base_gid() << ")"; | |
439 | HPX_THROW_EXCEPTION(invalid_status, | |
440 | "managed_component<Component, Derived>::get_checked", | |
441 | strm.str()); | |
442 | } | |
443 | return get(); | |
444 | } | |
445 | ||
446 | Component const* get_checked() const | |
447 | { | |
448 | if (!component_) { | |
449 | std::ostringstream strm; | |
450 | strm << "component is nullptr (" | |
451 | << components::get_component_type_name( | |
452 | components::get_component_type<wrapped_type>()) | |
453 | << ") gid(" << get_base_gid() << ")"; | |
454 | HPX_THROW_EXCEPTION(invalid_status, | |
455 | "managed_component<Component, Derived>::get_checked", | |
456 | strm.str()); | |
457 | } | |
458 | return get(); | |
459 | } | |
460 | ||
461 | public: | |
462 | /// \brief The memory for managed_component objects is managed by | |
463 | /// a class specific allocator. This allocator uses a one size | |
464 | /// heap implementation, ensuring fast memory allocation. | |
465 | /// Additionally the heap registers the allocated | |
466 | /// managed_component instance with the AGAS service. | |
467 | /// | |
468 | /// \param size [in] The parameter \a size is supplied by the | |
469 | /// compiler and contains the number of bytes to allocate. | |
470 | static void* operator new(std::size_t size) | |
471 | { | |
472 | if (size > sizeof(managed_component)) | |
473 | return ::operator new(size); | |
474 | void* p = heap_type::alloc(); | |
475 | if (nullptr == p) { | |
476 | HPX_THROW_STD_EXCEPTION(std::bad_alloc(), | |
477 | "managed_component::operator new(std::size_t size)"); | |
478 | } | |
479 | return p; | |
480 | } | |
481 | static void operator delete(void* p, std::size_t size) | |
482 | { | |
483 | if (nullptr == p) | |
484 | return; // do nothing if given a nullptr pointer | |
485 | ||
486 | if (size != sizeof(managed_component)) { | |
487 | ::operator delete(p); | |
488 | return; | |
489 | } | |
490 | heap_type::free(p); | |
491 | } | |
492 | ||
493 | /// \brief The placement operator new has to be overloaded as well | |
494 | /// (the global placement operators are hidden because of the | |
495 | /// new/delete overloads above). | |
496 | static void* operator new(std::size_t, void *p) | |
497 | { | |
498 | return p; | |
499 | } | |
500 | /// \brief This operator delete is called only if the placement new | |
501 | /// fails. | |
502 | static void operator delete(void*, void*) | |
503 | {} | |
504 | ||
505 | /// \brief The function \a create is used for allocation and | |
506 | // initialization of arrays of wrappers. | |
507 | static value_type* create(std::size_t count = 1) | |
508 | { | |
509 | // allocate the memory | |
510 | void* p = heap_type::alloc(count); | |
511 | if (nullptr == p) { | |
512 | HPX_THROW_STD_EXCEPTION(std::bad_alloc(), | |
513 | "managed_component::create"); | |
514 | } | |
515 | ||
516 | if (1 == count) | |
517 | return new (p) value_type(); | |
518 | ||
519 | // call constructors | |
520 | std::size_t succeeded = 0; | |
521 | try { | |
522 | value_type* curr = reinterpret_cast<value_type*>(p); | |
523 | for (std::size_t i = 0; i != count; ++i, ++curr) { | |
524 | // call placement new, might throw | |
525 | new (curr) value_type(); | |
526 | ++succeeded; | |
527 | } | |
528 | } | |
529 | catch (...) { | |
530 | // call destructors for successfully constructed objects | |
531 | value_type* curr = reinterpret_cast<value_type*>(p); | |
532 | for (std::size_t i = 0; i != succeeded; ++i) | |
533 | { | |
534 | curr->finalize(); | |
535 | curr->~derived_type(); | |
536 | ++curr; | |
537 | } | |
538 | heap_type::free(p, count); // free memory | |
539 | throw; // rethrow | |
540 | } | |
541 | return reinterpret_cast<value_type*>(p); | |
542 | } | |
543 | ||
544 | /// \brief The function \a destroy is used for deletion and | |
545 | // de-allocation of arrays of wrappers | |
546 | static void destroy(value_type* p, std::size_t count = 1) | |
547 | { | |
548 | if (nullptr == p || 0 == count) | |
549 | return; // do nothing if given a nullptr pointer | |
550 | ||
551 | // call destructors for all managed_component instances | |
552 | value_type* curr = p; | |
553 | for (std::size_t i = 0; i != count; ++i) | |
554 | { | |
555 | curr->finalize(); | |
556 | curr->~derived_type(); | |
557 | ++curr; | |
558 | } | |
559 | ||
560 | // free memory itself | |
561 | heap_type::free(p, count); | |
562 | } | |
563 | ||
564 | #if defined(HPX_HAVE_SECURITY) | |
565 | static components::security::capability get_required_capabilities( | |
566 | components::security::traits::capability<>::capabilities caps) | |
567 | { | |
568 | return components::default_component_creation_capabilities(caps); | |
569 | } | |
570 | #endif | |
571 | ||
572 | public: | |
573 | /////////////////////////////////////////////////////////////////////// | |
574 | // The managed_component behaves just like the wrapped object | |
575 | Component* operator-> () | |
576 | { | |
577 | return get_checked(); | |
578 | } | |
579 | ||
580 | Component const* operator-> () const | |
581 | { | |
582 | return get_checked(); | |
583 | } | |
584 | ||
585 | /////////////////////////////////////////////////////////////////////// | |
586 | Component& operator* () | |
587 | { | |
588 | return *get_checked(); | |
589 | } | |
590 | ||
591 | Component const& operator* () const | |
592 | { | |
593 | return *get_checked(); | |
594 | } | |
595 | ||
596 | /////////////////////////////////////////////////////////////////////// | |
597 | /// \brief Return the global id of this \a future instance | |
598 | naming::id_type get_unmanaged_id() const | |
599 | { | |
600 | return naming::id_type(get_base_gid(), naming::id_type::unmanaged); | |
601 | } | |
602 | ||
603 | #if defined(HPX_HAVE_COMPONENT_GET_GID_COMPATIBILITY) | |
604 | naming::id_type get_gid() const | |
605 | { | |
606 | return get_unmanaged_id(); | |
607 | } | |
608 | #endif | |
609 | ||
610 | #if defined(HPX_HAVE_CXX11_EXTENDED_FRIEND_DECLARATIONS) && !defined(__CUDACC__) | |
611 | private: | |
612 | // declare friends which are allowed to access get_base_gid() | |
613 | friend Component; | |
614 | ||
615 | template <typename Component_, typename Wrapper_, | |
616 | typename CtorPolicy, typename DtorPolicy> | |
617 | friend class managed_component_base; | |
618 | ||
619 | template <typename Component_> | |
620 | friend naming::gid_type server::create(std::size_t count); | |
621 | ||
622 | template <typename Component_> | |
623 | friend naming::gid_type server::create( | |
624 | util::unique_function_nonser<void(void*)> const& ctor); | |
625 | ||
626 | template <typename Component_> | |
627 | friend naming::gid_type server::create(naming::gid_type const& gid, | |
628 | util::unique_function_nonser<void(void*)> const& ctor); | |
629 | #endif | |
630 | ||
631 | naming::gid_type get_base_gid( | |
632 | naming::gid_type const& assign_gid = naming::invalid_gid) const | |
633 | { | |
634 | if (assign_gid) | |
635 | { | |
636 | HPX_THROW_EXCEPTION(bad_parameter, | |
637 | "managed_component::get_base_gid", | |
638 | "managed_components must be assigned new gids on creation"); | |
639 | return naming::invalid_gid; | |
640 | } | |
641 | return heap_type::get_gid(const_cast<managed_component*>(this)); | |
642 | } | |
643 | ||
644 | public: | |
645 | // reference counting | |
646 | template<typename C, typename D> | |
647 | friend void intrusive_ptr_add_ref(managed_component<C, D>* p); | |
648 | ||
649 | template<typename C, typename D> | |
650 | friend void intrusive_ptr_release(managed_component<C, D>* p); | |
651 | ||
652 | protected: | |
653 | Component* component_; | |
654 | }; | |
655 | ||
656 | /////////////////////////////////////////////////////////////////////////// | |
657 | template <typename Component, typename Wrapper, | |
658 | typename CtorPolicy, typename DtorPolicy> | |
659 | inline naming::id_type | |
660 | managed_component_base<Component, Wrapper, CtorPolicy, DtorPolicy>:: | |
661 | get_unmanaged_id() const | |
662 | { | |
663 | HPX_ASSERT(back_ptr_); | |
664 | return back_ptr_->get_unmanaged_id(); | |
665 | } | |
666 | ||
667 | template <typename Component, typename Wrapper, | |
668 | typename CtorPolicy, typename DtorPolicy> | |
669 | inline naming::id_type | |
670 | managed_component_base<Component, Wrapper, CtorPolicy, DtorPolicy>:: | |
671 | get_id() const | |
672 | { | |
673 | // all credits should have been taken already | |
674 | naming::gid_type gid = derived().get_base_gid(); | |
675 | ||
676 | // The underlying heap will always give us a full set of credits, but | |
677 | // those are valid for the first invocation of get_base_gid() only. | |
678 | // We have to get rid of those credits and properly replenish those. | |
679 | naming::detail::strip_credits_from_gid(gid); | |
680 | ||
681 | // any invocation causes the credits to be replenished | |
682 | naming::detail::replenish_credits(gid); | |
683 | return naming::id_type(gid, naming::id_type::managed); | |
684 | } | |
685 | ||
686 | template <typename Component, typename Wrapper, | |
687 | typename CtorPolicy, typename DtorPolicy> | |
688 | inline naming::gid_type | |
689 | managed_component_base<Component, Wrapper, CtorPolicy, DtorPolicy>:: | |
690 | get_base_gid() const | |
691 | { | |
692 | HPX_ASSERT(back_ptr_); | |
693 | return back_ptr_->get_base_gid(); | |
694 | } | |
695 | }} | |
696 | ||
697 | #endif | |
698 | ||
699 | ||
700 |
Copyright (c) 2006-2012 Rogue Wave Software, Inc. All Rights Reserved.
Patents pending.