1 //////////////////////////////////////////////////////////////////////////////
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)
7 // See http://www.boost.org/libs/interprocess for documentation.
9 //////////////////////////////////////////////////////////////////////////////
11 #ifndef BOOST_INTERPROCESS_DETAIL_MANAGED_MEMORY_IMPL_HPP
12 #define BOOST_INTERPROCESS_DETAIL_MANAGED_MEMORY_IMPL_HPP
14 #ifndef BOOST_CONFIG_HPP
15 # include <boost/config.hpp>
18 #if defined(BOOST_HAS_PRAGMA_ONCE)
22 #include <boost/interprocess/detail/config_begin.hpp>
23 #include <boost/interprocess/detail/workaround.hpp>
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>
35 #include <boost/core/no_exceptions_support.hpp>
37 #include <boost/intrusive/detail/minimal_pair_header.hpp>
38 #include <boost/assert.hpp>
41 //!Describes a named shared memory allocation user class.
45 namespace interprocess {
48 template<class BasicManagedMemoryImpl>
49 class create_open_func;
53 class MemoryAlgorithm,
54 template<class IndexConfig> class IndexType
56 struct segment_manager_type
58 typedef segment_manager<CharType, MemoryAlgorithm, IndexType> type;
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.*/
68 template < class CharType
69 , class MemoryAlgorithm
70 , template<class IndexConfig> class IndexType
71 , std::size_t Offset = 0
73 class basic_managed_memory_impl
76 basic_managed_memory_impl(const basic_managed_memory_impl &);
77 basic_managed_memory_impl &operator=(const basic_managed_memory_impl &);
79 template<class BasicManagedMemoryImpl>
80 friend class create_open_func;
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;
97 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
100 segment_manager::char_ptr_holder_t char_ptr_holder_t;
101 //Experimental. Don't use.
103 typedef typename segment_manager::multiallocation_chain multiallocation_chain;
105 #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
107 static const size_type PayloadPerAllocation = segment_manager::PayloadPerAllocation;
110 typedef basic_managed_memory_impl
111 <CharType, MemoryAlgorithm, IndexType, Offset> self_t;
113 template<class ManagedMemory, class CharT>
114 static bool grow(const CharT *filename, size_type extra_bytes)
116 typedef typename ManagedMemory::device_type device_type;
121 device_type f(open_or_create, filename, read_write);
122 if(!f.get_size(old_size))
124 f.truncate(old_size + static_cast<offset_t>(extra_bytes));
126 ManagedMemory managed_memory(open_only, filename);
128 managed_memory.self_t::grow(extra_bytes);
136 template<class ManagedMemory, class CharT>
137 static bool shrink_to_fit(const CharT *filename)
139 typedef typename ManagedMemory::device_type device_type;
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();
153 device_type f(open_or_create, filename, read_write);
154 f.truncate(static_cast<offset_t>(new_size));
159 //!Constructor. Allocates basic resources. Never throws.
160 basic_managed_memory_impl()
163 //!Destructor. Calls close. Never throws.
164 ~basic_managed_memory_impl()
165 { this->close_impl(); }
167 //!Places segment manager in the reserved space. This can throw.
168 bool create_impl (void *addr, size_type size)
170 if(mp_header) return false;
172 //Check if there is enough space
173 if(size < segment_manager::get_min_size())
176 //This function should not throw. The index construction can
177 //throw if constructor allocates memory. So we must catch it.
179 //Let's construct the allocator in memory
180 BOOST_ASSERT((0 == (std::size_t)addr % boost::move_detail::alignment_of<segment_manager>::value));
181 mp_header = ::new(addr, boost_container_new_t()) segment_manager(size);
189 //!Connects to a segment manager in the reserved buffer. Never throws.
190 bool open_impl (void *addr, size_type)
192 if(mp_header) return false;
193 mp_header = static_cast<segment_manager*>(addr);
197 //!Frees resources. Never throws.
200 bool ret = mp_header != 0;
205 //!Frees resources and destroys common resources. Never throws.
210 mp_header->~segment_manager();
216 void grow(size_type extra_bytes)
217 { mp_header->grow(extra_bytes); }
220 { mp_header->shrink_to_fit(); }
224 //!Returns segment manager. Never throws.
225 segment_manager *get_segment_manager() const
226 { return mp_header; }
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; }
232 //!Returns the size of memory segment. Never throws.
233 size_type get_size () const
234 { return mp_header->get_size() + Offset; }
236 //!Returns the number of free bytes of the memory
238 size_type get_free_memory() const
239 { return mp_header->get_free_memory(); }
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(); }
246 //!Returns the result of "check_sanity()" function
247 //!of the used memory algorithm
249 { return mp_header->check_sanity(); }
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(); }
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
260 return (handle_t)(reinterpret_cast<const char*>(ptr) -
261 reinterpret_cast<const char*>(this->get_address()));
264 //!Returns true if the address belongs to the managed memory segment
265 bool belongs_to_segment (const void *ptr) const
267 return ptr >= this->get_address() &&
268 ptr < (reinterpret_cast<const char*>(this->get_address()) + this->get_size());
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; }
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); }
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); }
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); }
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); }
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); }
305 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
307 //Experimental. Don't use.
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); }
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); }
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); }
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); }
330 //!Deallocates all elements contained in chain.
332 void deallocate_many(multiallocation_chain &chain)
333 { mp_header->deallocate_many(chain); }
335 #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
337 //!Marks previously allocated memory as free. Never throws.
338 void deallocate (void *addr)
339 { if (mp_header) mp_header->deallocate(addr); }
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.
345 std::pair<T*, size_type> find (char_ptr_holder_t name)
346 { return mp_header->template find<T>(name); }
348 //!Creates a named object or array in memory
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.
355 //!-> If the name was previously used, returns 0.
357 //!-> Throws boost::interprocess::bad_alloc if there is no available memory
359 //!-> If T's constructor throws, the function throws that exception.
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.
365 typename segment_manager::template construct_proxy<T>::type
366 construct(char_ptr_holder_t name)
367 { return mp_header->template construct<T>(name); }
369 //!Finds or creates a named object or array in memory
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.
378 //!-> Throws boost::interprocess::bad_alloc if there is no available memory
380 //!-> If T's constructor throws, the function throws that exception.
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.
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); }
390 //!Creates a named object or array in memory
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.
397 //!-> If the name was previously used, returns 0.
399 //!-> Returns 0 if there is no available memory
401 //!-> If T's constructor throws, the function throws that exception.
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.
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); }
411 //!Finds or creates a named object or array in memory
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.
420 //!-> Returns 0 if there is no available memory
422 //!-> If T's constructor throws, the function throws that exception.
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.
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); }
432 //!Creates a named array from iterators in memory
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.
440 //!-> If the name was previously used, returns 0.
442 //!-> Throws boost::interprocess::bad_alloc if there is no available memory
444 //!-> If T's constructor throws, the function throws that exception.
446 //!Memory is freed automatically if T's constructor throws and
447 //!destructors of created objects are called before freeing the memory.
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); }
453 //!Finds or creates a named array from iterators in memory
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.
463 //!-> If the name was previously used, returns 0.
465 //!-> Throws boost::interprocess::bad_alloc if there is no available memory
467 //!-> If T's constructor throws, the function throws that exception.
469 //!Memory is freed automatically if T's constructor throws and
470 //!destructors of created objects are called before freeing the memory.
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); }
476 //!Creates a named array from iterators in memory
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.
484 //!-> If the name was previously used, returns 0.
486 //!-> If there is no available memory, returns 0.
488 //!-> If T's constructor throws, the function throws that exception.
490 //!Memory is freed automatically if T's constructor throws and
491 //!destructors of created objects are called before freeing the memory.*/
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); }
497 //!Finds or creates a named array from iterators in memory
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.
507 //!-> If the name was previously used, returns 0.
509 //!-> If there is no available memory, returns 0.
511 //!-> If T's constructor throws, the function throws that exception.
513 //!Memory is freed automatically if T's constructor throws and
514 //!destructors of created objects are called before freeing the memory.*/
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); }
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); }
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); }
536 //!Destroys a named memory object or array.
538 //!Finds the object with the given name, calls its destructors,
539 //!frees used memory and returns true.
541 //!-> If the object is not found, it returns false.
543 //!Exception Handling:
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.
551 //!Destroying an object:
553 //!If the destructor throws, the memory will be freed and that exception
556 //!Destroying an array:
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.
564 //!For all theses reasons, classes with throwing destructors are not
567 bool destroy(const CharType *name)
568 { return mp_header->template destroy<T>(name); }
570 //!Destroys the unique instance of type T
572 //!Calls the destructor, frees used memory and returns true.
574 //!Exception Handling:
576 //!When deleting a dynamically object, the Standard does not
577 //!guarantee that dynamically allocated memory will be released.
579 //!Destroying an object:
581 //!If the destructor throws, the memory will be freed and that exception
584 //!For all theses reasons, classes with throwing destructors are not
585 //!recommended for memory.
587 bool destroy(const unique_instance_t *const )
588 { return mp_header->template destroy<T>(unique_instance); }
590 //!Destroys the object (named, unique, or anonymous)
592 //!Calls the destructor, frees used memory and returns true.
594 //!Exception Handling:
596 //!When deleting a dynamically object, the Standard does not
597 //!guarantee that dynamically allocated memory will be released.
599 //!Destroying an object:
601 //!If the destructor throws, the memory will be freed and that exception
604 //!For all theses reasons, classes with throwing destructors are not
605 //!recommended for memory.
607 void destroy_ptr(const T *ptr)
608 { mp_header->template destroy_ptr<T>(ptr); }
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.
613 static const char_type *get_instance_name(const T *ptr)
614 { return segment_manager::get_instance_name(ptr); }
616 //!Returns is the type an object created with construct/find_or_construct
617 //!functions. Does not throw.
619 static instance_type get_instance_type(const T *ptr)
620 { return segment_manager::get_instance_type(ptr); }
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.
625 static size_type get_instance_length(const T *ptr)
626 { return segment_manager::get_instance_length(ptr); }
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); }
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); }
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(); }
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(); }
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(); }
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(); }
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(); }
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(); }
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(); }
675 //!This is the default allocator to allocate types T
676 //!from this managed segment
680 typedef typename segment_manager::template allocator<T>::type type;
683 //!Returns an instance of the default allocator for type T
684 //!initialized that allocates memory from this segment manager.
686 typename allocator<T>::type
688 { return mp_header->template get_allocator<T>(); }
690 //!This is the default deleter to delete types T
691 //!from this managed segment.
695 typedef typename segment_manager::template deleter<T>::type type;
698 //!Returns an instance of the default allocator for type T
699 //!initialized that allocates memory from this segment manager.
701 typename deleter<T>::type
703 { return mp_header->template get_deleter<T>(); }
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.
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
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); }
721 segment_manager *mp_header;
724 template<class BasicManagedMemoryImpl>
725 class create_open_func
727 typedef typename BasicManagedMemoryImpl::size_type size_type;
731 create_open_func(BasicManagedMemoryImpl * const frontend, create_enum_t type)
732 : m_frontend(frontend), m_type(type){}
734 bool operator()(void *addr, std::size_t size, bool created) const
736 if( ((m_type == DoOpen) && created) ||
737 ((m_type == DoCreate) && !created) ||
739 size_type(-1) < size ){
743 return m_frontend->create_impl(addr, static_cast<size_type>(size));
746 return m_frontend->open_impl (addr, static_cast<size_type>(size));
750 static std::size_t get_min_size()
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
756 return std::size_t(-1);
759 return static_cast<std::size_t>(sz);
764 BasicManagedMemoryImpl *m_frontend;
765 create_enum_t m_type;
768 } //namespace ipcdetail {
769 } //namespace interprocess {
770 } //namespace boost {
772 #include <boost/interprocess/detail/config_end.hpp>
774 #endif //BOOST_INTERPROCESS_DETAIL_MANAGED_MEMORY_IMPL_HPP