summaryrefslogtreecommitdiff
path: root/boost/interprocess/detail/managed_memory_impl.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/interprocess/detail/managed_memory_impl.hpp')
-rw-r--r--boost/interprocess/detail/managed_memory_impl.hpp750
1 files changed, 750 insertions, 0 deletions
diff --git a/boost/interprocess/detail/managed_memory_impl.hpp b/boost/interprocess/detail/managed_memory_impl.hpp
new file mode 100644
index 0000000000..31c3804439
--- /dev/null
+++ b/boost/interprocess/detail/managed_memory_impl.hpp
@@ -0,0 +1,750 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/interprocess for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTERPROCESS_DETAIL_MANAGED_MEMORY_IMPL_HPP
+#define BOOST_INTERPROCESS_DETAIL_MANAGED_MEMORY_IMPL_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/detail/workaround.hpp>
+
+#include <boost/interprocess/interprocess_fwd.hpp>
+#include <boost/interprocess/detail/utilities.hpp>
+#include <boost/interprocess/detail/os_file_functions.hpp>
+#include <boost/interprocess/creation_tags.hpp>
+#include <boost/interprocess/exceptions.hpp>
+#include <boost/interprocess/segment_manager.hpp>
+#include <boost/interprocess/sync/scoped_lock.hpp>
+//
+#include <boost/detail/no_exceptions_support.hpp>
+//
+#include <utility>
+#include <fstream>
+#include <new>
+#include <boost/assert.hpp>
+
+//!\file
+//!Describes a named shared memory allocation user class.
+//!
+
+namespace boost {
+namespace interprocess {
+namespace ipcdetail {
+
+template<class BasicManagedMemoryImpl>
+class create_open_func;
+
+template<
+ class CharType,
+ class MemoryAlgorithm,
+ template<class IndexConfig> class IndexType
+ >
+struct segment_manager_type
+{
+ typedef segment_manager<CharType, MemoryAlgorithm, IndexType> type;
+};
+
+//!This class is designed to be a base class to classes that manage
+//!creation of objects in a fixed size memory buffer. Apart
+//!from allocating raw memory, the user can construct named objects. To
+//!achieve this, this class uses the reserved space provided by the allocation
+//!algorithm to place a named_allocator_algo, who takes care of name mappings.
+//!The class can be customized with the char type used for object names
+//!and the memory allocation algorithm to be used.*/
+template < class CharType
+ , class MemoryAlgorithm
+ , template<class IndexConfig> class IndexType
+ , std::size_t Offset = 0
+ >
+class basic_managed_memory_impl
+{
+ //Non-copyable
+ basic_managed_memory_impl(const basic_managed_memory_impl &);
+ basic_managed_memory_impl &operator=(const basic_managed_memory_impl &);
+
+ template<class BasicManagedMemoryImpl>
+ friend class create_open_func;
+
+ public:
+ typedef typename segment_manager_type
+ <CharType, MemoryAlgorithm, IndexType>::type segment_manager;
+ typedef CharType char_type;
+ typedef MemoryAlgorithm memory_algorithm;
+ typedef typename MemoryAlgorithm::mutex_family mutex_family;
+ typedef CharType char_t;
+ typedef typename MemoryAlgorithm::size_type size_type;
+ typedef typename MemoryAlgorithm::difference_type difference_type;
+ typedef difference_type handle_t;
+ typedef typename segment_manager::
+ const_named_iterator const_named_iterator;
+ typedef typename segment_manager::
+ const_unique_iterator const_unique_iterator;
+
+ /// @cond
+
+ typedef typename
+ segment_manager::char_ptr_holder_t char_ptr_holder_t;
+ //Experimental. Don't use.
+
+ typedef typename segment_manager::multiallocation_chain multiallocation_chain;
+
+ /// @endcond
+
+ static const size_type PayloadPerAllocation = segment_manager::PayloadPerAllocation;
+
+ private:
+ typedef basic_managed_memory_impl
+ <CharType, MemoryAlgorithm, IndexType, Offset> self_t;
+ protected:
+ template<class ManagedMemory>
+ static bool grow(const char *filename, size_type extra_bytes)
+ {
+ typedef typename ManagedMemory::device_type device_type;
+ //Increase file size
+ try{
+ offset_t old_size;
+ {
+ device_type f(open_or_create, filename, read_write);
+ if(!f.get_size(old_size))
+ return false;
+ f.truncate(old_size + extra_bytes);
+ }
+ ManagedMemory managed_memory(open_only, filename);
+ //Grow always works
+ managed_memory.self_t::grow(extra_bytes);
+ }
+ catch(...){
+ return false;
+ }
+ return true;
+ }
+
+ template<class ManagedMemory>
+ static bool shrink_to_fit(const char *filename)
+ {
+ typedef typename ManagedMemory::device_type device_type;
+ size_type new_size;
+ try{
+ ManagedMemory managed_memory(open_only, filename);
+ managed_memory.get_size();
+ managed_memory.self_t::shrink_to_fit();
+ new_size = managed_memory.get_size();
+ }
+ catch(...){
+ return false;
+ }
+
+ //Decrease file size
+ {
+ device_type f(open_or_create, filename, read_write);
+ f.truncate(new_size);
+ }
+ return true;
+ }
+
+ //!Constructor. Allocates basic resources. Never throws.
+ basic_managed_memory_impl()
+ : mp_header(0){}
+
+ //!Destructor. Calls close. Never throws.
+ ~basic_managed_memory_impl()
+ { this->close_impl(); }
+
+ //!Places segment manager in the reserved space. This can throw.
+ bool create_impl (void *addr, size_type size)
+ {
+ if(mp_header) return false;
+
+ //Check if there is enough space
+ if(size < segment_manager::get_min_size())
+ return false;
+
+ //This function should not throw. The index construction can
+ //throw if constructor allocates memory. So we must catch it.
+ BOOST_TRY{
+ //Let's construct the allocator in memory
+ mp_header = new(addr) segment_manager(size);
+ }
+ BOOST_CATCH(...){
+ return false;
+ }
+ BOOST_CATCH_END
+ return true;
+ }
+
+ //!Connects to a segment manager in the reserved buffer. Never throws.
+ bool open_impl (void *addr, size_type)
+ {
+ if(mp_header) return false;
+ mp_header = static_cast<segment_manager*>(addr);
+ return true;
+ }
+
+ //!Frees resources. Never throws.
+ bool close_impl()
+ {
+ bool ret = mp_header != 0;
+ mp_header = 0;
+ return ret;
+ }
+
+ //!Frees resources and destroys common resources. Never throws.
+ bool destroy_impl()
+ {
+ if(mp_header == 0)
+ return false;
+ mp_header->~segment_manager();
+ this->close_impl();
+ return true;
+ }
+
+ //!
+ void grow(size_type extra_bytes)
+ { mp_header->grow(extra_bytes); }
+
+ void shrink_to_fit()
+ { mp_header->shrink_to_fit(); }
+
+ public:
+
+ //!Returns segment manager. Never throws.
+ segment_manager *get_segment_manager() const
+ { return mp_header; }
+
+ //!Returns the base address of the memory in this process. Never throws.
+ void * get_address () const
+ { return reinterpret_cast<char*>(mp_header) - Offset; }
+
+ //!Returns the size of memory segment. Never throws.
+ size_type get_size () const
+ { return mp_header->get_size() + Offset; }
+
+ //!Returns the number of free bytes of the memory
+ //!segment
+ size_type get_free_memory() const
+ { return mp_header->get_free_memory(); }
+
+ //!Returns the result of "all_memory_deallocated()" function
+ //!of the used memory algorithm
+ bool all_memory_deallocated()
+ { return mp_header->all_memory_deallocated(); }
+
+ //!Returns the result of "check_sanity()" function
+ //!of the used memory algorithm
+ bool check_sanity()
+ { return mp_header->check_sanity(); }
+
+ //!Writes to zero free memory (memory not yet allocated) of
+ //!the memory algorithm
+ void zero_free_memory()
+ { mp_header->zero_free_memory(); }
+
+ //!Transforms an absolute address into an offset from base address.
+ //!The address must belong to the memory segment. Never throws.
+ handle_t get_handle_from_address (const void *ptr) const
+ {
+ return (handle_t)(reinterpret_cast<const char*>(ptr) -
+ reinterpret_cast<const char*>(this->get_address()));
+ }
+
+ //!Returns true if the address belongs to the managed memory segment
+ bool belongs_to_segment (const void *ptr) const
+ {
+ return ptr >= this->get_address() &&
+ ptr < (reinterpret_cast<const char*>(this->get_address()) + this->get_size());
+ }
+
+ //!Transforms previously obtained offset into an absolute address in the
+ //!process space of the current process. Never throws.*/
+ void * get_address_from_handle (handle_t offset) const
+ { return reinterpret_cast<char*>(this->get_address()) + offset; }
+
+ //!Searches for nbytes of free memory in the segment, marks the
+ //!memory as used and return the pointer to the memory. If no
+ //!memory is available throws a boost::interprocess::bad_alloc exception
+ void* allocate (size_type nbytes)
+ { return mp_header->allocate(nbytes); }
+
+ //!Searches for nbytes of free memory in the segment, marks the
+ //!memory as used and return the pointer to the memory. If no memory
+ //!is available returns 0. Never throws.
+ void* allocate (size_type nbytes, std::nothrow_t nothrow)
+ { return mp_header->allocate(nbytes, nothrow); }
+
+ //!Allocates nbytes bytes aligned to "alignment" bytes. "alignment"
+ //!must be power of two. If no memory
+ //!is available returns 0. Never throws.
+ void * allocate_aligned (size_type nbytes, size_type alignment, std::nothrow_t nothrow)
+ { return mp_header->allocate_aligned(nbytes, alignment, nothrow); }
+
+ template<class T>
+ std::pair<T *, bool>
+ allocation_command (boost::interprocess::allocation_type command, size_type limit_size,
+ size_type preferred_size,size_type &received_size,
+ T *reuse_ptr = 0)
+ {
+ return mp_header->allocation_command
+ (command, limit_size, preferred_size, received_size, reuse_ptr);
+ }
+
+ //!Allocates nbytes bytes aligned to "alignment" bytes. "alignment"
+ //!must be power of two. If no
+ //!memory is available throws a boost::interprocess::bad_alloc exception
+ void * allocate_aligned(size_type nbytes, size_type alignment)
+ { return mp_header->allocate_aligned(nbytes, alignment); }
+
+ /// @cond
+
+ //Experimental. Don't use.
+
+ //!Allocates n_elements of elem_size bytes.
+ multiallocation_chain allocate_many(size_type elem_bytes, size_type num_elements)
+ { return mp_header->allocate_many(elem_bytes, num_elements); }
+
+ //!Allocates n_elements, each one of elem_sizes[i] bytes.
+ multiallocation_chain allocate_many(const size_type *elem_sizes, size_type n_elements)
+ { return mp_header->allocate_many(elem_sizes, n_elements); }
+
+ //!Allocates n_elements of elem_size bytes.
+ multiallocation_chain allocate_many(size_type elem_bytes, size_type num_elements, std::nothrow_t nothrow)
+ { return mp_header->allocate_many(elem_bytes, num_elements, nothrow); }
+
+ //!Allocates n_elements, each one of elem_sizes[i] bytes.
+ multiallocation_chain allocate_many(const size_type *elem_sizes, size_type n_elements, std::nothrow_t nothrow)
+ { return mp_header->allocate_many(elem_sizes, n_elements, nothrow); }
+
+ //!Allocates n_elements, each one of elem_sizes[i] bytes.
+ void deallocate_many(multiallocation_chain chain)
+ { return mp_header->deallocate_many(boost::move(chain)); }
+
+ /// @endcond
+
+ //!Marks previously allocated memory as free. Never throws.
+ void deallocate (void *addr)
+ { if (mp_header) mp_header->deallocate(addr); }
+
+ //!Tries to find a previous named allocation address. Returns a memory
+ //!buffer and the object count. If not found returned pointer is 0.
+ //!Never throws.
+ template <class T>
+ std::pair<T*, size_type> find (char_ptr_holder_t name)
+ { return mp_header->template find<T>(name); }
+
+ //!Creates a named object or array in memory
+ //!
+ //!Allocates and constructs a T object or an array of T in memory,
+ //!associates this with the given name and returns a pointer to the
+ //!created object. If an array is being constructed all objects are
+ //!created using the same parameters given to this function.
+ //!
+ //!-> If the name was previously used, returns 0.
+ //!
+ //!-> Throws boost::interprocess::bad_alloc if there is no available memory
+ //!
+ //!-> If T's constructor throws, the function throws that exception.
+ //!
+ //!Memory is freed automatically if T's constructor throws and if an
+ //!array was being constructed, destructors of created objects are called
+ //!before freeing the memory.
+ template <class T>
+ typename segment_manager::template construct_proxy<T>::type
+ construct(char_ptr_holder_t name)
+ { return mp_header->template construct<T>(name); }
+
+ //!Finds or creates a named object or array in memory
+ //!
+ //!Tries to find an object with the given name in memory. If
+ //!found, returns the pointer to this pointer. If the object is not found,
+ //!allocates and constructs a T object or an array of T in memory,
+ //!associates this with the given name and returns a pointer to the
+ //!created object. If an array is being constructed all objects are
+ //!created using the same parameters given to this function.
+ //!
+ //!-> Throws boost::interprocess::bad_alloc if there is no available memory
+ //!
+ //!-> If T's constructor throws, the function throws that exception.
+ //!
+ //!Memory is freed automatically if T's constructor throws and if an
+ //!array was being constructed, destructors of created objects are called
+ //!before freeing the memory.
+ template <class T>
+ typename segment_manager::template construct_proxy<T>::type
+ find_or_construct(char_ptr_holder_t name)
+ { return mp_header->template find_or_construct<T>(name); }
+
+ //!Creates a named object or array in memory
+ //!
+ //!Allocates and constructs a T object or an array of T in memory,
+ //!associates this with the given name and returns a pointer to the
+ //!created object. If an array is being constructed all objects are
+ //!created using the same parameters given to this function.
+ //!
+ //!-> If the name was previously used, returns 0.
+ //!
+ //!-> Returns 0 if there is no available memory
+ //!
+ //!-> If T's constructor throws, the function throws that exception.
+ //!
+ //!Memory is freed automatically if T's constructor throws and if an
+ //!array was being constructed, destructors of created objects are called
+ //!before freeing the memory.
+ template <class T>
+ typename segment_manager::template construct_proxy<T>::type
+ construct(char_ptr_holder_t name, std::nothrow_t nothrow)
+ { return mp_header->template construct<T>(name, nothrow); }
+
+ //!Finds or creates a named object or array in memory
+ //!
+ //!Tries to find an object with the given name in memory. If
+ //!found, returns the pointer to this pointer. If the object is not found,
+ //!allocates and constructs a T object or an array of T in memory,
+ //!associates this with the given name and returns a pointer to the
+ //!created object. If an array is being constructed all objects are
+ //!created using the same parameters given to this function.
+ //!
+ //!-> Returns 0 if there is no available memory
+ //!
+ //!-> If T's constructor throws, the function throws that exception.
+ //!
+ //!Memory is freed automatically if T's constructor throws and if an
+ //!array was being constructed, destructors of created objects are called
+ //!before freeing the memory.
+ template <class T>
+ typename segment_manager::template construct_proxy<T>::type
+ find_or_construct(char_ptr_holder_t name, std::nothrow_t nothrow)
+ { return mp_header->template find_or_construct<T>(name, nothrow); }
+
+ //!Creates a named array from iterators in memory
+ //!
+ //!Allocates and constructs an array of T in memory,
+ //!associates this with the given name and returns a pointer to the
+ //!created object. Each element in the array is created using the
+ //!objects returned when dereferencing iterators as parameters
+ //!and incrementing all iterators for each element.
+ //!
+ //!-> If the name was previously used, returns 0.
+ //!
+ //!-> Throws boost::interprocess::bad_alloc if there is no available memory
+ //!
+ //!-> If T's constructor throws, the function throws that exception.
+ //!
+ //!Memory is freed automatically if T's constructor throws and
+ //!destructors of created objects are called before freeing the memory.
+ template <class T>
+ typename segment_manager::template construct_iter_proxy<T>::type
+ construct_it(char_ptr_holder_t name)
+ { return mp_header->template construct_it<T>(name); }
+
+ //!Finds or creates a named array from iterators in memory
+ //!
+ //!Tries to find an object with the given name in memory. If
+ //!found, returns the pointer to this pointer. If the object is not found,
+ //!allocates and constructs an array of T in memory,
+ //!associates this with the given name and returns a pointer to the
+ //!created object. Each element in the array is created using the
+ //!objects returned when dereferencing iterators as parameters
+ //!and incrementing all iterators for each element.
+ //!
+ //!-> If the name was previously used, returns 0.
+ //!
+ //!-> Throws boost::interprocess::bad_alloc if there is no available memory
+ //!
+ //!-> If T's constructor throws, the function throws that exception.
+ //!
+ //!Memory is freed automatically if T's constructor throws and
+ //!destructors of created objects are called before freeing the memory.
+ template <class T>
+ typename segment_manager::template construct_iter_proxy<T>::type
+ find_or_construct_it(char_ptr_holder_t name)
+ { return mp_header->template find_or_construct_it<T>(name); }
+
+ //!Creates a named array from iterators in memory
+ //!
+ //!Allocates and constructs an array of T in memory,
+ //!associates this with the given name and returns a pointer to the
+ //!created object. Each element in the array is created using the
+ //!objects returned when dereferencing iterators as parameters
+ //!and incrementing all iterators for each element.
+ //!
+ //!-> If the name was previously used, returns 0.
+ //!
+ //!-> If there is no available memory, returns 0.
+ //!
+ //!-> If T's constructor throws, the function throws that exception.
+ //!
+ //!Memory is freed automatically if T's constructor throws and
+ //!destructors of created objects are called before freeing the memory.*/
+ template <class T>
+ typename segment_manager::template construct_iter_proxy<T>::type
+ construct_it(char_ptr_holder_t name, std::nothrow_t nothrow)
+ { return mp_header->template construct_it<T>(name, nothrow); }
+
+ //!Finds or creates a named array from iterators in memory
+ //!
+ //!Tries to find an object with the given name in memory. If
+ //!found, returns the pointer to this pointer. If the object is not found,
+ //!allocates and constructs an array of T in memory,
+ //!associates this with the given name and returns a pointer to the
+ //!created object. Each element in the array is created using the
+ //!objects returned when dereferencing iterators as parameters
+ //!and incrementing all iterators for each element.
+ //!
+ //!-> If the name was previously used, returns 0.
+ //!
+ //!-> If there is no available memory, returns 0.
+ //!
+ //!-> If T's constructor throws, the function throws that exception.
+ //!
+ //!Memory is freed automatically if T's constructor throws and
+ //!destructors of created objects are called before freeing the memory.*/
+ template <class T>
+ typename segment_manager::template construct_iter_proxy<T>::type
+ find_or_construct_it(char_ptr_holder_t name, std::nothrow_t nothrow)
+ { return mp_header->template find_or_construct_it<T>(name, nothrow); }
+
+ //!Calls a functor and guarantees that no new construction, search or
+ //!destruction will be executed by any process while executing the object
+ //!function call. If the functor throws, this function throws.
+ template <class Func>
+ void atomic_func(Func &f)
+ { mp_header->atomic_func(f); }
+
+ //!Tries to call a functor guaranteeing that no new construction, search or
+ //!destruction will be executed by any process while executing the object
+ //!function call. If the atomic function can't be immediatelly executed
+ //!because the internal mutex is already locked, returns false.
+ //!If the functor throws, this function throws.
+ template <class Func>
+ bool try_atomic_func(Func &f)
+ { return mp_header->try_atomic_func(f); }
+
+ //!Destroys a named memory object or array.
+ //!
+ //!Finds the object with the given name, calls its destructors,
+ //!frees used memory and returns true.
+ //!
+ //!-> If the object is not found, it returns false.
+ //!
+ //!Exception Handling:
+ //!
+ //!When deleting a dynamically object or array, the Standard
+ //!does not guarantee that dynamically allocated memory, will be released.
+ //!Also, when deleting arrays, the Standard doesn't require calling
+ //!destructors for the rest of the objects if for one of them the destructor
+ //!terminated with an exception.
+ //!
+ //!Destroying an object:
+ //!
+ //!If the destructor throws, the memory will be freed and that exception
+ //!will be thrown.
+ //!
+ //!Destroying an array:
+ //!
+ //!When destroying an array, if a destructor throws, the rest of
+ //!destructors are called. If any of these throws, the exceptions are
+ //!ignored. The name association will be erased, memory will be freed and
+ //!the first exception will be thrown. This guarantees the unlocking of
+ //!mutexes and other resources.
+ //!
+ //!For all theses reasons, classes with throwing destructors are not
+ //!recommended.
+ template <class T>
+ bool destroy(const CharType *name)
+ { return mp_header->template destroy<T>(name); }
+
+ //!Destroys the unique instance of type T
+ //!
+ //!Calls the destructor, frees used memory and returns true.
+ //!
+ //!Exception Handling:
+ //!
+ //!When deleting a dynamically object, the Standard does not
+ //!guarantee that dynamically allocated memory will be released.
+ //!
+ //!Destroying an object:
+ //!
+ //!If the destructor throws, the memory will be freed and that exception
+ //!will be thrown.
+ //!
+ //!For all theses reasons, classes with throwing destructors are not
+ //!recommended for memory.
+ template <class T>
+ bool destroy(const unique_instance_t *const )
+ { return mp_header->template destroy<T>(unique_instance); }
+
+ //!Destroys the object (named, unique, or anonymous)
+ //!
+ //!Calls the destructor, frees used memory and returns true.
+ //!
+ //!Exception Handling:
+ //!
+ //!When deleting a dynamically object, the Standard does not
+ //!guarantee that dynamically allocated memory will be released.
+ //!
+ //!Destroying an object:
+ //!
+ //!If the destructor throws, the memory will be freed and that exception
+ //!will be thrown.
+ //!
+ //!For all theses reasons, classes with throwing destructors are not
+ //!recommended for memory.
+ template <class T>
+ void destroy_ptr(const T *ptr)
+ { mp_header->template destroy_ptr<T>(ptr); }
+
+ //!Returns the name of an object created with construct/find_or_construct
+ //!functions. Does not throw
+ template<class T>
+ static const char_type *get_instance_name(const T *ptr)
+ { return segment_manager::get_instance_name(ptr); }
+
+ //!Returns is the type an object created with construct/find_or_construct
+ //!functions. Does not throw.
+ template<class T>
+ static instance_type get_instance_type(const T *ptr)
+ { return segment_manager::get_instance_type(ptr); }
+
+ //!Returns the length of an object created with construct/find_or_construct
+ //!functions (1 if is a single element, >=1 if it's an array). Does not throw.
+ template<class T>
+ static size_type get_instance_length(const T *ptr)
+ { return segment_manager::get_instance_length(ptr); }
+
+ //!Preallocates needed index resources to optimize the
+ //!creation of "num" named objects in the memory segment.
+ //!Can throw boost::interprocess::bad_alloc if there is no enough memory.
+ void reserve_named_objects(size_type num)
+ { mp_header->reserve_named_objects(num); }
+
+ //!Preallocates needed index resources to optimize the
+ //!creation of "num" unique objects in the memory segment.
+ //!Can throw boost::interprocess::bad_alloc if there is no enough memory.
+ void reserve_unique_objects(size_type num)
+ { mp_header->reserve_unique_objects(num); }
+
+ //!Calls shrink_to_fit in both named and unique object indexes
+ //to try to free unused memory from those indexes.
+ void shrink_to_fit_indexes()
+ { mp_header->shrink_to_fit_indexes(); }
+
+ //!Returns the number of named objects stored
+ //!in the managed segment.
+ size_type get_num_named_objects()
+ { return mp_header->get_num_named_objects(); }
+
+ //!Returns the number of unique objects stored
+ //!in the managed segment.
+ size_type get_num_unique_objects()
+ { return mp_header->get_num_unique_objects(); }
+
+ //!Returns a constant iterator to the index storing the
+ //!named allocations. NOT thread-safe. Never throws.
+ const_named_iterator named_begin() const
+ { return mp_header->named_begin(); }
+
+ //!Returns a constant iterator to the end of the index
+ //!storing the named allocations. NOT thread-safe. Never throws.
+ const_named_iterator named_end() const
+ { return mp_header->named_end(); }
+
+ //!Returns a constant iterator to the index storing the
+ //!unique allocations. NOT thread-safe. Never throws.
+ const_unique_iterator unique_begin() const
+ { return mp_header->unique_begin(); }
+
+ //!Returns a constant iterator to the end of the index
+ //!storing the unique allocations. NOT thread-safe. Never throws.
+ const_unique_iterator unique_end() const
+ { return mp_header->unique_end(); }
+
+ //!This is the default allocator to allocate types T
+ //!from this managed segment
+ template<class T>
+ struct allocator
+ {
+ typedef typename segment_manager::template allocator<T>::type type;
+ };
+
+ //!Returns an instance of the default allocator for type T
+ //!initialized that allocates memory from this segment manager.
+ template<class T>
+ typename allocator<T>::type
+ get_allocator()
+ { return mp_header->template get_allocator<T>(); }
+
+ //!This is the default deleter to delete types T
+ //!from this managed segment.
+ template<class T>
+ struct deleter
+ {
+ typedef typename segment_manager::template deleter<T>::type type;
+ };
+
+ //!Returns an instance of the default allocator for type T
+ //!initialized that allocates memory from this segment manager.
+ template<class T>
+ typename deleter<T>::type
+ get_deleter()
+ { return mp_header->template get_deleter<T>(); }
+
+ /// @cond
+ //!Tries to find a previous named allocation address. Returns a memory
+ //!buffer and the object count. If not found returned pointer is 0.
+ //!Never throws.
+ template <class T>
+ std::pair<T*, size_type> find_no_lock (char_ptr_holder_t name)
+ { return mp_header->template find_no_lock<T>(name); }
+ /// @endcond
+
+ protected:
+ //!Swaps the segment manager's managed by this managed memory segment.
+ //!NOT thread-safe. Never throws.
+ void swap(basic_managed_memory_impl &other)
+ { std::swap(mp_header, other.mp_header); }
+
+ private:
+ segment_manager *mp_header;
+};
+
+template<class BasicManagedMemoryImpl>
+class create_open_func
+{
+ public:
+ create_open_func(BasicManagedMemoryImpl * const frontend, create_enum_t type)
+ : m_frontend(frontend), m_type(type){}
+
+ bool operator()(void *addr, typename BasicManagedMemoryImpl::size_type size, bool created) const
+ {
+ if(((m_type == DoOpen) && created) ||
+ ((m_type == DoCreate) && !created))
+ return false;
+
+ if(created)
+ return m_frontend->create_impl(addr, size);
+ else
+ return m_frontend->open_impl (addr, size);
+ }
+
+ private:
+ BasicManagedMemoryImpl *m_frontend;
+ create_enum_t m_type;
+};
+
+} //namespace ipcdetail {
+} //namespace interprocess {
+} //namespace boost {
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif //BOOST_INTERPROCESS_DETAIL_MANAGED_MEMORY_IMPL_HPP
+