]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/interprocess/include/boost/interprocess/detail/managed_memory_impl.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / interprocess / include / boost / interprocess / detail / managed_memory_impl.hpp
CommitLineData
7c673cae
FG
1//////////////////////////////////////////////////////////////////////////////
2//
3// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
4// Software License, Version 1.0. (See accompanying file
5// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6//
7// See http://www.boost.org/libs/interprocess for documentation.
8//
9//////////////////////////////////////////////////////////////////////////////
10
11#ifndef BOOST_INTERPROCESS_DETAIL_MANAGED_MEMORY_IMPL_HPP
12#define BOOST_INTERPROCESS_DETAIL_MANAGED_MEMORY_IMPL_HPP
13
14#ifndef BOOST_CONFIG_HPP
15# include <boost/config.hpp>
16#endif
17#
18#if defined(BOOST_HAS_PRAGMA_ONCE)
19# pragma once
20#endif
21
22#include <boost/interprocess/detail/config_begin.hpp>
23#include <boost/interprocess/detail/workaround.hpp>
24
25#include <boost/interprocess/interprocess_fwd.hpp>
26#include <boost/interprocess/detail/utilities.hpp>
27#include <boost/interprocess/detail/os_file_functions.hpp>
28#include <boost/interprocess/creation_tags.hpp>
29#include <boost/interprocess/exceptions.hpp>
30#include <boost/interprocess/segment_manager.hpp>
31#include <boost/interprocess/sync/scoped_lock.hpp>
32#include <boost/interprocess/detail/nothrow.hpp>
33#include <boost/interprocess/detail/simple_swap.hpp>
34//
35#include <boost/core/no_exceptions_support.hpp>
36//
37#include <boost/intrusive/detail/minimal_pair_header.hpp>
38#include <boost/assert.hpp>
39
40//!\file
41//!Describes a named shared memory allocation user class.
42//!
43
44namespace boost {
45namespace interprocess {
46namespace ipcdetail {
47
48template<class BasicManagedMemoryImpl>
49class create_open_func;
50
51template<
52 class CharType,
53 class MemoryAlgorithm,
54 template<class IndexConfig> class IndexType
55 >
56struct segment_manager_type
57{
58 typedef segment_manager<CharType, MemoryAlgorithm, IndexType> type;
59};
60
61//!This class is designed to be a base class to classes that manage
62//!creation of objects in a fixed size memory buffer. Apart
63//!from allocating raw memory, the user can construct named objects. To
64//!achieve this, this class uses the reserved space provided by the allocation
65//!algorithm to place a named_allocator_algo, who takes care of name mappings.
66//!The class can be customized with the char type used for object names
67//!and the memory allocation algorithm to be used.*/
68template < class CharType
69 , class MemoryAlgorithm
70 , template<class IndexConfig> class IndexType
71 , std::size_t Offset = 0
72 >
73class basic_managed_memory_impl
74{
75 //Non-copyable
76 basic_managed_memory_impl(const basic_managed_memory_impl &);
77 basic_managed_memory_impl &operator=(const basic_managed_memory_impl &);
78
79 template<class BasicManagedMemoryImpl>
80 friend class create_open_func;
81
82 public:
83 typedef typename segment_manager_type
84 <CharType, MemoryAlgorithm, IndexType>::type segment_manager;
85 typedef CharType char_type;
86 typedef MemoryAlgorithm memory_algorithm;
87 typedef typename MemoryAlgorithm::mutex_family mutex_family;
88 typedef CharType char_t;
89 typedef typename MemoryAlgorithm::size_type size_type;
90 typedef typename MemoryAlgorithm::difference_type difference_type;
91 typedef difference_type handle_t;
92 typedef typename segment_manager::
93 const_named_iterator const_named_iterator;
94 typedef typename segment_manager::
95 const_unique_iterator const_unique_iterator;
96
97 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
98
99 typedef typename
100 segment_manager::char_ptr_holder_t char_ptr_holder_t;
101 //Experimental. Don't use.
102
103 typedef typename segment_manager::multiallocation_chain multiallocation_chain;
104
105 #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
106
107 static const size_type PayloadPerAllocation = segment_manager::PayloadPerAllocation;
108
109 private:
110 typedef basic_managed_memory_impl
111 <CharType, MemoryAlgorithm, IndexType, Offset> self_t;
112 protected:
113 template<class ManagedMemory>
114 static bool grow(const char *filename, size_type extra_bytes)
115 {
116 typedef typename ManagedMemory::device_type device_type;
117 //Increase file size
118 try{
119 offset_t old_size;
120 {
121 device_type f(open_or_create, filename, read_write);
122 if(!f.get_size(old_size))
123 return false;
124 f.truncate(old_size + extra_bytes);
125 }
126 ManagedMemory managed_memory(open_only, filename);
127 //Grow always works
128 managed_memory.self_t::grow(extra_bytes);
129 }
130 catch(...){
131 return false;
132 }
133 return true;
134 }
135
136 template<class ManagedMemory>
137 static bool shrink_to_fit(const char *filename)
138 {
139 typedef typename ManagedMemory::device_type device_type;
140 size_type new_size;
141 try{
142 ManagedMemory managed_memory(open_only, filename);
143 managed_memory.get_size();
144 managed_memory.self_t::shrink_to_fit();
145 new_size = managed_memory.get_size();
146 }
147 catch(...){
148 return false;
149 }
150
151 //Decrease file size
152 {
153 device_type f(open_or_create, filename, read_write);
154 f.truncate(new_size);
155 }
156 return true;
157 }
158
159 //!Constructor. Allocates basic resources. Never throws.
160 basic_managed_memory_impl()
161 : mp_header(0){}
162
163 //!Destructor. Calls close. Never throws.
164 ~basic_managed_memory_impl()
165 { this->close_impl(); }
166
167 //!Places segment manager in the reserved space. This can throw.
168 bool create_impl (void *addr, size_type size)
169 {
170 if(mp_header) return false;
171
172 //Check if there is enough space
173 if(size < segment_manager::get_min_size())
174 return false;
175
176 //This function should not throw. The index construction can
177 //throw if constructor allocates memory. So we must catch it.
178 BOOST_TRY{
179 //Let's construct the allocator in memory
180 mp_header = ::new(addr, boost_container_new_t()) segment_manager(size);
181 }
182 BOOST_CATCH(...){
183 return false;
184 }
185 BOOST_CATCH_END
186 return true;
187 }
188
189 //!Connects to a segment manager in the reserved buffer. Never throws.
190 bool open_impl (void *addr, size_type)
191 {
192 if(mp_header) return false;
193 mp_header = static_cast<segment_manager*>(addr);
194 return true;
195 }
196
197 //!Frees resources. Never throws.
198 bool close_impl()
199 {
200 bool ret = mp_header != 0;
201 mp_header = 0;
202 return ret;
203 }
204
205 //!Frees resources and destroys common resources. Never throws.
206 bool destroy_impl()
207 {
208 if(mp_header == 0)
209 return false;
210 mp_header->~segment_manager();
211 this->close_impl();
212 return true;
213 }
214
215 //!
216 void grow(size_type extra_bytes)
217 { mp_header->grow(extra_bytes); }
218
219 void shrink_to_fit()
220 { mp_header->shrink_to_fit(); }
221
222 public:
223
224 //!Returns segment manager. Never throws.
225 segment_manager *get_segment_manager() const
226 { return mp_header; }
227
228 //!Returns the base address of the memory in this process. Never throws.
229 void * get_address () const
230 { return reinterpret_cast<char*>(mp_header) - Offset; }
231
232 //!Returns the size of memory segment. Never throws.
233 size_type get_size () const
234 { return mp_header->get_size() + Offset; }
235
236 //!Returns the number of free bytes of the memory
237 //!segment
238 size_type get_free_memory() const
239 { return mp_header->get_free_memory(); }
240
241 //!Returns the result of "all_memory_deallocated()" function
242 //!of the used memory algorithm
243 bool all_memory_deallocated()
244 { return mp_header->all_memory_deallocated(); }
245
246 //!Returns the result of "check_sanity()" function
247 //!of the used memory algorithm
248 bool check_sanity()
249 { return mp_header->check_sanity(); }
250
251 //!Writes to zero free memory (memory not yet allocated) of
252 //!the memory algorithm
253 void zero_free_memory()
254 { mp_header->zero_free_memory(); }
255
256 //!Transforms an absolute address into an offset from base address.
257 //!The address must belong to the memory segment. Never throws.
258 handle_t get_handle_from_address (const void *ptr) const
259 {
260 return (handle_t)(reinterpret_cast<const char*>(ptr) -
261 reinterpret_cast<const char*>(this->get_address()));
262 }
263
264 //!Returns true if the address belongs to the managed memory segment
265 bool belongs_to_segment (const void *ptr) const
266 {
267 return ptr >= this->get_address() &&
268 ptr < (reinterpret_cast<const char*>(this->get_address()) + this->get_size());
269 }
270
271 //!Transforms previously obtained offset into an absolute address in the
272 //!process space of the current process. Never throws.*/
273 void * get_address_from_handle (handle_t offset) const
274 { return reinterpret_cast<char*>(this->get_address()) + offset; }
275
276 //!Searches for nbytes of free memory in the segment, marks the
277 //!memory as used and return the pointer to the memory. If no
278 //!memory is available throws a boost::interprocess::bad_alloc exception
279 void* allocate (size_type nbytes)
280 { return mp_header->allocate(nbytes); }
281
282 //!Searches for nbytes of free memory in the segment, marks the
283 //!memory as used and return the pointer to the memory. If no memory
284 //!is available returns 0. Never throws.
285 void* allocate (size_type nbytes, const std::nothrow_t &tag)
286 { return mp_header->allocate(nbytes, tag); }
287
288 //!Allocates nbytes bytes aligned to "alignment" bytes. "alignment"
289 //!must be power of two. If no memory
290 //!is available returns 0. Never throws.
291 void * allocate_aligned (size_type nbytes, size_type alignment, const std::nothrow_t &tag)
292 { return mp_header->allocate_aligned(nbytes, alignment, tag); }
293
294 template<class T>
295 T * allocation_command (boost::interprocess::allocation_type command, size_type limit_size,
296 size_type &prefer_in_recvd_out_size, T *&reuse)
297 { return mp_header->allocation_command(command, limit_size, prefer_in_recvd_out_size, reuse); }
298
299 //!Allocates nbytes bytes aligned to "alignment" bytes. "alignment"
300 //!must be power of two. If no
301 //!memory is available throws a boost::interprocess::bad_alloc exception
302 void * allocate_aligned(size_type nbytes, size_type alignment)
303 { return mp_header->allocate_aligned(nbytes, alignment); }
304
305 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
306
307 //Experimental. Don't use.
308
309 //!Allocates n_elements of elem_bytes bytes.
310 //!Throws bad_alloc on failure. chain.size() is not increased on failure.
311 void allocate_many(size_type elem_bytes, size_type n_elements, multiallocation_chain &chain)
312 { mp_header->allocate_many(elem_bytes, n_elements, chain); }
313
314 //!Allocates n_elements, each one of element_lengths[i]*sizeof_element bytes.
315 //!Throws bad_alloc on failure. chain.size() is not increased on failure.
316 void allocate_many(const size_type *element_lengths, size_type n_elements, size_type sizeof_element, multiallocation_chain &chain)
317 { mp_header->allocate_many(element_lengths, n_elements, sizeof_element, chain); }
318
319 //!Allocates n_elements of elem_bytes bytes.
320 //!Non-throwing version. chain.size() is not increased on failure.
321 void allocate_many(const std::nothrow_t &tag, size_type elem_bytes, size_type n_elements, multiallocation_chain &chain)
322 { mp_header->allocate_many(tag, elem_bytes, n_elements, chain); }
323
324 //!Allocates n_elements, each one of
325 //!element_lengths[i]*sizeof_element bytes.
326 //!Non-throwing version. chain.size() is not increased on failure.
327 void allocate_many(const std::nothrow_t &tag, const size_type *elem_sizes, size_type n_elements, size_type sizeof_element, multiallocation_chain &chain)
328 { mp_header->allocate_many(tag, elem_sizes, n_elements, sizeof_element, chain); }
329
330 //!Deallocates all elements contained in chain.
331 //!Never throws.
332 void deallocate_many(multiallocation_chain &chain)
333 { mp_header->deallocate_many(chain); }
334
335 #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
336
337 //!Marks previously allocated memory as free. Never throws.
338 void deallocate (void *addr)
339 { if (mp_header) mp_header->deallocate(addr); }
340
341 //!Tries to find a previous named allocation address. Returns a memory
342 //!buffer and the object count. If not found returned pointer is 0.
343 //!Never throws.
344 template <class T>
345 std::pair<T*, size_type> find (char_ptr_holder_t name)
346 { return mp_header->template find<T>(name); }
347
348 //!Creates a named object or array in memory
349 //!
350 //!Allocates and constructs a T object or an array of T in memory,
351 //!associates this with the given name and returns a pointer to the
352 //!created object. If an array is being constructed all objects are
353 //!created using the same parameters given to this function.
354 //!
355 //!-> If the name was previously used, returns 0.
356 //!
357 //!-> Throws boost::interprocess::bad_alloc if there is no available memory
358 //!
359 //!-> If T's constructor throws, the function throws that exception.
360 //!
361 //!Memory is freed automatically if T's constructor throws and if an
362 //!array was being constructed, destructors of created objects are called
363 //!before freeing the memory.
364 template <class T>
365 typename segment_manager::template construct_proxy<T>::type
366 construct(char_ptr_holder_t name)
367 { return mp_header->template construct<T>(name); }
368
369 //!Finds or creates a named object or array in memory
370 //!
371 //!Tries to find an object with the given name in memory. If
372 //!found, returns the pointer to this pointer. If the object is not found,
373 //!allocates and constructs a T object or an array of T in memory,
374 //!associates this with the given name and returns a pointer to the
375 //!created object. If an array is being constructed all objects are
376 //!created using the same parameters given to this function.
377 //!
378 //!-> Throws boost::interprocess::bad_alloc if there is no available memory
379 //!
380 //!-> If T's constructor throws, the function throws that exception.
381 //!
382 //!Memory is freed automatically if T's constructor throws and if an
383 //!array was being constructed, destructors of created objects are called
384 //!before freeing the memory.
385 template <class T>
386 typename segment_manager::template construct_proxy<T>::type
387 find_or_construct(char_ptr_holder_t name)
388 { return mp_header->template find_or_construct<T>(name); }
389
390 //!Creates a named object or array in memory
391 //!
392 //!Allocates and constructs a T object or an array of T in memory,
393 //!associates this with the given name and returns a pointer to the
394 //!created object. If an array is being constructed all objects are
395 //!created using the same parameters given to this function.
396 //!
397 //!-> If the name was previously used, returns 0.
398 //!
399 //!-> Returns 0 if there is no available memory
400 //!
401 //!-> If T's constructor throws, the function throws that exception.
402 //!
403 //!Memory is freed automatically if T's constructor throws and if an
404 //!array was being constructed, destructors of created objects are called
405 //!before freeing the memory.
406 template <class T>
407 typename segment_manager::template construct_proxy<T>::type
408 construct(char_ptr_holder_t name, const std::nothrow_t &tag)
409 { return mp_header->template construct<T>(name, tag); }
410
411 //!Finds or creates a named object or array in memory
412 //!
413 //!Tries to find an object with the given name in memory. If
414 //!found, returns the pointer to this pointer. If the object is not found,
415 //!allocates and constructs a T object or an array of T in memory,
416 //!associates this with the given name and returns a pointer to the
417 //!created object. If an array is being constructed all objects are
418 //!created using the same parameters given to this function.
419 //!
420 //!-> Returns 0 if there is no available memory
421 //!
422 //!-> If T's constructor throws, the function throws that exception.
423 //!
424 //!Memory is freed automatically if T's constructor throws and if an
425 //!array was being constructed, destructors of created objects are called
426 //!before freeing the memory.
427 template <class T>
428 typename segment_manager::template construct_proxy<T>::type
429 find_or_construct(char_ptr_holder_t name, const std::nothrow_t &tag)
430 { return mp_header->template find_or_construct<T>(name, tag); }
431
432 //!Creates a named array from iterators in memory
433 //!
434 //!Allocates and constructs an array of T in memory,
435 //!associates this with the given name and returns a pointer to the
436 //!created object. Each element in the array is created using the
437 //!objects returned when dereferencing iterators as parameters
438 //!and incrementing all iterators for each element.
439 //!
440 //!-> If the name was previously used, returns 0.
441 //!
442 //!-> Throws boost::interprocess::bad_alloc if there is no available memory
443 //!
444 //!-> If T's constructor throws, the function throws that exception.
445 //!
446 //!Memory is freed automatically if T's constructor throws and
447 //!destructors of created objects are called before freeing the memory.
448 template <class T>
449 typename segment_manager::template construct_iter_proxy<T>::type
450 construct_it(char_ptr_holder_t name)
451 { return mp_header->template construct_it<T>(name); }
452
453 //!Finds or creates a named array from iterators in memory
454 //!
455 //!Tries to find an object with the given name in memory. If
456 //!found, returns the pointer to this pointer. If the object is not found,
457 //!allocates and constructs an array of T in memory,
458 //!associates this with the given name and returns a pointer to the
459 //!created object. Each element in the array is created using the
460 //!objects returned when dereferencing iterators as parameters
461 //!and incrementing all iterators for each element.
462 //!
463 //!-> If the name was previously used, returns 0.
464 //!
465 //!-> Throws boost::interprocess::bad_alloc if there is no available memory
466 //!
467 //!-> If T's constructor throws, the function throws that exception.
468 //!
469 //!Memory is freed automatically if T's constructor throws and
470 //!destructors of created objects are called before freeing the memory.
471 template <class T>
472 typename segment_manager::template construct_iter_proxy<T>::type
473 find_or_construct_it(char_ptr_holder_t name)
474 { return mp_header->template find_or_construct_it<T>(name); }
475
476 //!Creates a named array from iterators in memory
477 //!
478 //!Allocates and constructs an array of T in memory,
479 //!associates this with the given name and returns a pointer to the
480 //!created object. Each element in the array is created using the
481 //!objects returned when dereferencing iterators as parameters
482 //!and incrementing all iterators for each element.
483 //!
484 //!-> If the name was previously used, returns 0.
485 //!
486 //!-> If there is no available memory, returns 0.
487 //!
488 //!-> If T's constructor throws, the function throws that exception.
489 //!
490 //!Memory is freed automatically if T's constructor throws and
491 //!destructors of created objects are called before freeing the memory.*/
492 template <class T>
493 typename segment_manager::template construct_iter_proxy<T>::type
494 construct_it(char_ptr_holder_t name, const std::nothrow_t &tag)
495 { return mp_header->template construct_it<T>(name, tag); }
496
497 //!Finds or creates a named array from iterators in memory
498 //!
499 //!Tries to find an object with the given name in memory. If
500 //!found, returns the pointer to this pointer. If the object is not found,
501 //!allocates and constructs an array of T in memory,
502 //!associates this with the given name and returns a pointer to the
503 //!created object. Each element in the array is created using the
504 //!objects returned when dereferencing iterators as parameters
505 //!and incrementing all iterators for each element.
506 //!
507 //!-> If the name was previously used, returns 0.
508 //!
509 //!-> If there is no available memory, returns 0.
510 //!
511 //!-> If T's constructor throws, the function throws that exception.
512 //!
513 //!Memory is freed automatically if T's constructor throws and
514 //!destructors of created objects are called before freeing the memory.*/
515 template <class T>
516 typename segment_manager::template construct_iter_proxy<T>::type
517 find_or_construct_it(char_ptr_holder_t name, const std::nothrow_t &tag)
518 { return mp_header->template find_or_construct_it<T>(name, tag); }
519
520 //!Calls a functor and guarantees that no new construction, search or
521 //!destruction will be executed by any process while executing the object
522 //!function call. If the functor throws, this function throws.
523 template <class Func>
524 void atomic_func(Func &f)
525 { mp_header->atomic_func(f); }
526
527 //!Tries to call a functor guaranteeing that no new construction, search or
528 //!destruction will be executed by any process while executing the object
529 //!function call. If the atomic function can't be immediatelly executed
530 //!because the internal mutex is already locked, returns false.
531 //!If the functor throws, this function throws.
532 template <class Func>
533 bool try_atomic_func(Func &f)
534 { return mp_header->try_atomic_func(f); }
535
536 //!Destroys a named memory object or array.
537 //!
538 //!Finds the object with the given name, calls its destructors,
539 //!frees used memory and returns true.
540 //!
541 //!-> If the object is not found, it returns false.
542 //!
543 //!Exception Handling:
544 //!
545 //!When deleting a dynamically object or array, the Standard
546 //!does not guarantee that dynamically allocated memory, will be released.
547 //!Also, when deleting arrays, the Standard doesn't require calling
548 //!destructors for the rest of the objects if for one of them the destructor
549 //!terminated with an exception.
550 //!
551 //!Destroying an object:
552 //!
553 //!If the destructor throws, the memory will be freed and that exception
554 //!will be thrown.
555 //!
556 //!Destroying an array:
557 //!
558 //!When destroying an array, if a destructor throws, the rest of
559 //!destructors are called. If any of these throws, the exceptions are
560 //!ignored. The name association will be erased, memory will be freed and
561 //!the first exception will be thrown. This guarantees the unlocking of
562 //!mutexes and other resources.
563 //!
564 //!For all theses reasons, classes with throwing destructors are not
565 //!recommended.
566 template <class T>
567 bool destroy(const CharType *name)
568 { return mp_header->template destroy<T>(name); }
569
570 //!Destroys the unique instance of type T
571 //!
572 //!Calls the destructor, frees used memory and returns true.
573 //!
574 //!Exception Handling:
575 //!
576 //!When deleting a dynamically object, the Standard does not
577 //!guarantee that dynamically allocated memory will be released.
578 //!
579 //!Destroying an object:
580 //!
581 //!If the destructor throws, the memory will be freed and that exception
582 //!will be thrown.
583 //!
584 //!For all theses reasons, classes with throwing destructors are not
585 //!recommended for memory.
586 template <class T>
587 bool destroy(const unique_instance_t *const )
588 { return mp_header->template destroy<T>(unique_instance); }
589
590 //!Destroys the object (named, unique, or anonymous)
591 //!
592 //!Calls the destructor, frees used memory and returns true.
593 //!
594 //!Exception Handling:
595 //!
596 //!When deleting a dynamically object, the Standard does not
597 //!guarantee that dynamically allocated memory will be released.
598 //!
599 //!Destroying an object:
600 //!
601 //!If the destructor throws, the memory will be freed and that exception
602 //!will be thrown.
603 //!
604 //!For all theses reasons, classes with throwing destructors are not
605 //!recommended for memory.
606 template <class T>
607 void destroy_ptr(const T *ptr)
608 { mp_header->template destroy_ptr<T>(ptr); }
609
610 //!Returns the name of an object created with construct/find_or_construct
611 //!functions. If ptr points to an unique instance typeid(T).name() is returned.
612 template<class T>
613 static const char_type *get_instance_name(const T *ptr)
614 { return segment_manager::get_instance_name(ptr); }
615
616 //!Returns is the type an object created with construct/find_or_construct
617 //!functions. Does not throw.
618 template<class T>
619 static instance_type get_instance_type(const T *ptr)
620 { return segment_manager::get_instance_type(ptr); }
621
622 //!Returns the length of an object created with construct/find_or_construct
623 //!functions (1 if is a single element, >=1 if it's an array). Does not throw.
624 template<class T>
625 static size_type get_instance_length(const T *ptr)
626 { return segment_manager::get_instance_length(ptr); }
627
628 //!Preallocates needed index resources to optimize the
629 //!creation of "num" named objects in the memory segment.
630 //!Can throw boost::interprocess::bad_alloc if there is no enough memory.
631 void reserve_named_objects(size_type num)
632 { mp_header->reserve_named_objects(num); }
633
634 //!Preallocates needed index resources to optimize the
635 //!creation of "num" unique objects in the memory segment.
636 //!Can throw boost::interprocess::bad_alloc if there is no enough memory.
637 void reserve_unique_objects(size_type num)
638 { mp_header->reserve_unique_objects(num); }
639
640 //!Calls shrink_to_fit in both named and unique object indexes
641 //to try to free unused memory from those indexes.
642 void shrink_to_fit_indexes()
643 { mp_header->shrink_to_fit_indexes(); }
644
645 //!Returns the number of named objects stored
646 //!in the managed segment.
647 size_type get_num_named_objects()
648 { return mp_header->get_num_named_objects(); }
649
650 //!Returns the number of unique objects stored
651 //!in the managed segment.
652 size_type get_num_unique_objects()
653 { return mp_header->get_num_unique_objects(); }
654
655 //!Returns a constant iterator to the index storing the
656 //!named allocations. NOT thread-safe. Never throws.
657 const_named_iterator named_begin() const
658 { return mp_header->named_begin(); }
659
660 //!Returns a constant iterator to the end of the index
661 //!storing the named allocations. NOT thread-safe. Never throws.
662 const_named_iterator named_end() const
663 { return mp_header->named_end(); }
664
665 //!Returns a constant iterator to the index storing the
666 //!unique allocations. NOT thread-safe. Never throws.
667 const_unique_iterator unique_begin() const
668 { return mp_header->unique_begin(); }
669
670 //!Returns a constant iterator to the end of the index
671 //!storing the unique allocations. NOT thread-safe. Never throws.
672 const_unique_iterator unique_end() const
673 { return mp_header->unique_end(); }
674
675 //!This is the default allocator to allocate types T
676 //!from this managed segment
677 template<class T>
678 struct allocator
679 {
680 typedef typename segment_manager::template allocator<T>::type type;
681 };
682
683 //!Returns an instance of the default allocator for type T
684 //!initialized that allocates memory from this segment manager.
685 template<class T>
686 typename allocator<T>::type
687 get_allocator()
688 { return mp_header->template get_allocator<T>(); }
689
690 //!This is the default deleter to delete types T
691 //!from this managed segment.
692 template<class T>
693 struct deleter
694 {
695 typedef typename segment_manager::template deleter<T>::type type;
696 };
697
698 //!Returns an instance of the default allocator for type T
699 //!initialized that allocates memory from this segment manager.
700 template<class T>
701 typename deleter<T>::type
702 get_deleter()
703 { return mp_header->template get_deleter<T>(); }
704
705 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
706 //!Tries to find a previous named allocation address. Returns a memory
707 //!buffer and the object count. If not found returned pointer is 0.
708 //!Never throws.
709 template <class T>
710 std::pair<T*, size_type> find_no_lock (char_ptr_holder_t name)
711 { return mp_header->template find_no_lock<T>(name); }
712 #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
713
714 protected:
715 //!Swaps the segment manager's managed by this managed memory segment.
716 //!NOT thread-safe. Never throws.
717 void swap(basic_managed_memory_impl &other)
718 { (simple_swap)(mp_header, other.mp_header); }
719
720 private:
721 segment_manager *mp_header;
722};
723
724template<class BasicManagedMemoryImpl>
725class create_open_func
726{
727 typedef typename BasicManagedMemoryImpl::size_type size_type;
728
729 public:
730
731 create_open_func(BasicManagedMemoryImpl * const frontend, create_enum_t type)
732 : m_frontend(frontend), m_type(type){}
733
734 bool operator()(void *addr, std::size_t size, bool created) const
735 {
736 if( ((m_type == DoOpen) && created) ||
737 ((m_type == DoCreate) && !created) ||
738 //Check for overflow
739 size_type(-1) < size ){
740 return false;
741 }
742 else if(created){
743 return m_frontend->create_impl(addr, static_cast<size_type>(size));
744 }
745 else{
746 return m_frontend->open_impl (addr, static_cast<size_type>(size));
747 }
748 }
749
750 static std::size_t get_min_size()
751 {
752 const size_type sz = BasicManagedMemoryImpl::segment_manager::get_min_size();
753 if(sz > std::size_t(-1)){
754 //The minimum size is not representable by std::size_t
755 BOOST_ASSERT(false);
756 return std::size_t(-1);
757 }
758 else{
759 return static_cast<std::size_t>(sz);
760 }
761 }
762
763 private:
764 BasicManagedMemoryImpl *m_frontend;
765 create_enum_t m_type;
766};
767
768} //namespace ipcdetail {
769} //namespace interprocess {
770} //namespace boost {
771
772#include <boost/interprocess/detail/config_end.hpp>
773
774#endif //BOOST_INTERPROCESS_DETAIL_MANAGED_MEMORY_IMPL_HPP
775