123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775 |
- #ifndef BOOST_INTERPROCESS_DETAIL_MANAGED_MEMORY_IMPL_HPP
- #define BOOST_INTERPROCESS_DETAIL_MANAGED_MEMORY_IMPL_HPP
- #ifndef BOOST_CONFIG_HPP
- # include <boost/config.hpp>
- #endif
- #
- #if defined(BOOST_HAS_PRAGMA_ONCE)
- # 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/interprocess/detail/nothrow.hpp>
- #include <boost/interprocess/detail/simple_swap.hpp>
- #include <boost/core/no_exceptions_support.hpp>
- #include <boost/intrusive/detail/minimal_pair_header.hpp>
- #include <boost/assert.hpp>
- 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;
- };
- template < class CharType
- , class MemoryAlgorithm
- , template<class IndexConfig> class IndexType
- , std::size_t Offset = 0
- >
- class basic_managed_memory_impl
- {
-
- 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;
- #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- typedef typename
- segment_manager::char_ptr_holder_t char_ptr_holder_t;
-
- typedef typename segment_manager::multiallocation_chain multiallocation_chain;
- #endif
- static const size_type PayloadPerAllocation = segment_manager::PayloadPerAllocation;
- private:
- typedef basic_managed_memory_impl
- <CharType, MemoryAlgorithm, IndexType, Offset> self_t;
- protected:
- template<class ManagedMemory, class CharT>
- static bool grow(const CharT *filename, size_type extra_bytes)
- {
- typedef typename ManagedMemory::device_type device_type;
-
- BOOST_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 + static_cast<offset_t>(extra_bytes));
- }
- ManagedMemory managed_memory(open_only, filename);
-
- managed_memory.self_t::grow(extra_bytes);
- }
- BOOST_CATCH(...){
- return false;
- } BOOST_CATCH_END
- return true;
- }
- template<class ManagedMemory, class CharT>
- static bool shrink_to_fit(const CharT *filename)
- {
- typedef typename ManagedMemory::device_type device_type;
- size_type new_size;
- BOOST_TRY{
- ManagedMemory managed_memory(open_only, filename);
- managed_memory.get_size();
- managed_memory.self_t::shrink_to_fit();
- new_size = managed_memory.get_size();
- }
- BOOST_CATCH(...){
- return false;
- } BOOST_CATCH_END
-
- {
- device_type f(open_or_create, filename, read_write);
- f.truncate(static_cast<offset_t>(new_size));
- }
- return true;
- }
-
- basic_managed_memory_impl()
- : mp_header(0){}
-
- ~basic_managed_memory_impl()
- { this->close_impl(); }
-
- bool create_impl (void *addr, size_type size)
- {
- if(mp_header) return false;
-
- if(size < segment_manager::get_min_size())
- return false;
-
-
- BOOST_TRY{
-
- BOOST_ASSERT((0 == (std::size_t)addr % boost::move_detail::alignment_of<segment_manager>::value));
- mp_header = ::new(addr, boost_container_new_t()) segment_manager(size);
- }
- BOOST_CATCH(...){
- return false;
- } BOOST_CATCH_END
- return true;
- }
-
- bool open_impl (void *addr, size_type)
- {
- if(mp_header) return false;
- mp_header = static_cast<segment_manager*>(addr);
- return true;
- }
-
- bool close_impl()
- {
- bool ret = mp_header != 0;
- mp_header = 0;
- return ret;
- }
-
- 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:
-
- segment_manager *get_segment_manager() const
- { return mp_header; }
-
- void * get_address () const
- { return reinterpret_cast<char*>(mp_header) - Offset; }
-
- size_type get_size () const
- { return mp_header->get_size() + Offset; }
-
-
- size_type get_free_memory() const
- { return mp_header->get_free_memory(); }
-
-
- bool all_memory_deallocated()
- { return mp_header->all_memory_deallocated(); }
-
-
- bool check_sanity()
- { return mp_header->check_sanity(); }
-
-
- void zero_free_memory()
- { mp_header->zero_free_memory(); }
-
-
- 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()));
- }
-
- bool belongs_to_segment (const void *ptr) const
- {
- return ptr >= this->get_address() &&
- ptr < (reinterpret_cast<const char*>(this->get_address()) + this->get_size());
- }
-
-
- void * get_address_from_handle (handle_t offset) const
- { return reinterpret_cast<char*>(this->get_address()) + offset; }
-
-
-
- void* allocate (size_type nbytes)
- { return mp_header->allocate(nbytes); }
-
-
-
- void* allocate (size_type nbytes, const std::nothrow_t &tag)
- { return mp_header->allocate(nbytes, tag); }
-
-
-
- void * allocate_aligned (size_type nbytes, size_type alignment, const std::nothrow_t &tag)
- { return mp_header->allocate_aligned(nbytes, alignment, tag); }
- template<class T>
- T * allocation_command (boost::interprocess::allocation_type command, size_type limit_size,
- size_type &prefer_in_recvd_out_size, T *&reuse)
- { return mp_header->allocation_command(command, limit_size, prefer_in_recvd_out_size, reuse); }
-
-
-
- void * allocate_aligned(size_type nbytes, size_type alignment)
- { return mp_header->allocate_aligned(nbytes, alignment); }
- #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
-
-
-
- void allocate_many(size_type elem_bytes, size_type n_elements, multiallocation_chain &chain)
- { mp_header->allocate_many(elem_bytes, n_elements, chain); }
-
-
- void allocate_many(const size_type *element_lengths, size_type n_elements, size_type sizeof_element, multiallocation_chain &chain)
- { mp_header->allocate_many(element_lengths, n_elements, sizeof_element, chain); }
-
-
- void allocate_many(const std::nothrow_t &tag, size_type elem_bytes, size_type n_elements, multiallocation_chain &chain)
- { mp_header->allocate_many(tag, elem_bytes, n_elements, chain); }
-
-
-
- void allocate_many(const std::nothrow_t &tag, const size_type *elem_sizes, size_type n_elements, size_type sizeof_element, multiallocation_chain &chain)
- { mp_header->allocate_many(tag, elem_sizes, n_elements, sizeof_element, chain); }
-
-
- void deallocate_many(multiallocation_chain &chain)
- { mp_header->deallocate_many(chain); }
- #endif
-
- void deallocate (void *addr)
- { if (mp_header) mp_header->deallocate(addr); }
-
-
-
- template <class T>
- std::pair<T*, size_type> find (char_ptr_holder_t name)
- { return mp_header->template find<T>(name); }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- template <class T>
- typename segment_manager::template construct_proxy<T>::type
- construct(char_ptr_holder_t name)
- { return mp_header->template construct<T>(name); }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 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); }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- template <class T>
- typename segment_manager::template construct_proxy<T>::type
- construct(char_ptr_holder_t name, const std::nothrow_t &tag)
- { return mp_header->template construct<T>(name, tag); }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- template <class T>
- typename segment_manager::template construct_proxy<T>::type
- find_or_construct(char_ptr_holder_t name, const std::nothrow_t &tag)
- { return mp_header->template find_or_construct<T>(name, tag); }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 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); }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 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); }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- template <class T>
- typename segment_manager::template construct_iter_proxy<T>::type
- construct_it(char_ptr_holder_t name, const std::nothrow_t &tag)
- { return mp_header->template construct_it<T>(name, tag); }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- template <class T>
- typename segment_manager::template construct_iter_proxy<T>::type
- find_or_construct_it(char_ptr_holder_t name, const std::nothrow_t &tag)
- { return mp_header->template find_or_construct_it<T>(name, tag); }
-
-
-
- template <class Func>
- void atomic_func(Func &f)
- { mp_header->atomic_func(f); }
-
-
-
-
-
- template <class Func>
- bool try_atomic_func(Func &f)
- { return mp_header->try_atomic_func(f); }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- template <class T>
- bool destroy(const CharType *name)
- { return mp_header->template destroy<T>(name); }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- template <class T>
- bool destroy(const unique_instance_t *const )
- { return mp_header->template destroy<T>(unique_instance); }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- template <class T>
- void destroy_ptr(const T *ptr)
- { mp_header->template destroy_ptr<T>(ptr); }
-
-
- template<class T>
- static const char_type *get_instance_name(const T *ptr)
- { return segment_manager::get_instance_name(ptr); }
-
-
- template<class T>
- static instance_type get_instance_type(const T *ptr)
- { return segment_manager::get_instance_type(ptr); }
-
-
- template<class T>
- static size_type get_instance_length(const T *ptr)
- { return segment_manager::get_instance_length(ptr); }
-
-
-
- void reserve_named_objects(size_type num)
- { mp_header->reserve_named_objects(num); }
-
-
-
- void reserve_unique_objects(size_type num)
- { mp_header->reserve_unique_objects(num); }
-
-
- void shrink_to_fit_indexes()
- { mp_header->shrink_to_fit_indexes(); }
-
-
- size_type get_num_named_objects()
- { return mp_header->get_num_named_objects(); }
-
-
- size_type get_num_unique_objects()
- { return mp_header->get_num_unique_objects(); }
-
-
- const_named_iterator named_begin() const
- { return mp_header->named_begin(); }
-
-
- const_named_iterator named_end() const
- { return mp_header->named_end(); }
-
-
- const_unique_iterator unique_begin() const
- { return mp_header->unique_begin(); }
-
-
- const_unique_iterator unique_end() const
- { return mp_header->unique_end(); }
-
-
- template<class T>
- struct allocator
- {
- typedef typename segment_manager::template allocator<T>::type type;
- };
-
-
- template<class T>
- typename allocator<T>::type
- get_allocator()
- { return mp_header->template get_allocator<T>(); }
-
-
- template<class T>
- struct deleter
- {
- typedef typename segment_manager::template deleter<T>::type type;
- };
-
-
- template<class T>
- typename deleter<T>::type
- get_deleter()
- { return mp_header->template get_deleter<T>(); }
- #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
-
-
-
- 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); }
- #endif
- protected:
-
-
- void swap(basic_managed_memory_impl &other)
- { (simple_swap)(mp_header, other.mp_header); }
- private:
- segment_manager *mp_header;
- };
- template<class BasicManagedMemoryImpl>
- class create_open_func
- {
- typedef typename BasicManagedMemoryImpl::size_type size_type;
- public:
- create_open_func(BasicManagedMemoryImpl * const frontend, create_enum_t type)
- : m_frontend(frontend), m_type(type){}
- bool operator()(void *addr, std::size_t size, bool created) const
- {
- if( ((m_type == DoOpen) && created) ||
- ((m_type == DoCreate) && !created) ||
-
- size_type(-1) < size ){
- return false;
- }
- else if(created){
- return m_frontend->create_impl(addr, static_cast<size_type>(size));
- }
- else{
- return m_frontend->open_impl (addr, static_cast<size_type>(size));
- }
- }
- static std::size_t get_min_size()
- {
- const size_type sz = BasicManagedMemoryImpl::segment_manager::get_min_size();
- if(sz > std::size_t(-1)){
-
- BOOST_ASSERT(false);
- return std::size_t(-1);
- }
- else{
- return static_cast<std::size_t>(sz);
- }
- }
- private:
- BasicManagedMemoryImpl *m_frontend;
- create_enum_t m_type;
- };
- }
- }
- }
- #include <boost/interprocess/detail/config_end.hpp>
- #endif
|