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