Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-06-30 08:17:11

0001 //////////////////////////////////////////////////////////////////////////////
0002 //
0003 // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
0004 // Software License, Version 1.0. (See accompanying file
0005 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 //
0007 // See http://www.boost.org/libs/interprocess for documentation.
0008 //
0009 //////////////////////////////////////////////////////////////////////////////
0010 
0011 #ifndef BOOST_INTERPROCESS_SEGMENT_MANAGER_BASE_HPP
0012 #define BOOST_INTERPROCESS_SEGMENT_MANAGER_BASE_HPP
0013 
0014 #ifndef BOOST_CONFIG_HPP
0015 #  include <boost/config.hpp>
0016 #endif
0017 #
0018 #if defined(BOOST_HAS_PRAGMA_ONCE)
0019 #  pragma once
0020 #endif
0021 
0022 #include <boost/interprocess/detail/config_begin.hpp>
0023 #include <boost/interprocess/detail/workaround.hpp>
0024 
0025 // interprocess
0026 #include <boost/interprocess/exceptions.hpp>
0027 // interprocess/detail
0028 #include <boost/interprocess/detail/type_traits.hpp>
0029 #include <boost/interprocess/detail/utilities.hpp>
0030 #include <boost/interprocess/detail/in_place_interface.hpp>
0031 // container/detail
0032 #include <boost/container/detail/type_traits.hpp> //alignment_of
0033 #include <boost/container/detail/minimal_char_traits_header.hpp>
0034 // intrusive
0035 #include <boost/intrusive/pointer_traits.hpp>
0036 // move/detail
0037 #include <boost/move/detail/type_traits.hpp> //make_unsigned
0038 #include <boost/move/detail/force_ptr.hpp>
0039 // other boost
0040 #include <boost/assert.hpp>   //BOOST_ASSERT
0041 #include <boost/core/no_exceptions_support.hpp>
0042 // std
0043 #include <cstddef>   //std::size_t
0044 
0045 //!\file
0046 //!Describes the object placed in a memory segment that provides
0047 //!named object allocation capabilities.
0048 
0049 namespace boost{
0050 namespace interprocess{
0051 
0052 template<class MemoryManager>
0053 class segment_manager_base;
0054 
0055 //!An integer that describes the type of the
0056 //!instance constructed in memory
0057 enum instance_type {   anonymous_type, named_type, unique_type, max_allocation_type };
0058 
0059 namespace ipcdetail{
0060 
0061 template<class MemoryAlgorithm>
0062 class mem_algo_deallocator
0063 {
0064    void *            m_ptr;
0065    MemoryAlgorithm & m_algo;
0066 
0067    public:
0068    mem_algo_deallocator(void *ptr, MemoryAlgorithm &algo)
0069       :  m_ptr(ptr), m_algo(algo)
0070    {}
0071 
0072    void release()
0073    {  m_ptr = 0;  }
0074 
0075    ~mem_algo_deallocator()
0076    {  if(m_ptr) m_algo.deallocate(m_ptr);  }
0077 };
0078 
0079 template<class size_type>
0080 struct block_header
0081 {
0082    size_type      m_value_bytes;
0083    unsigned short m_num_char;
0084    unsigned char  m_value_alignment;
0085    unsigned char  m_alloc_type_sizeof_char;
0086 
0087    block_header(size_type val_bytes
0088                ,size_type val_alignment
0089                ,unsigned char al_type
0090                ,std::size_t szof_char
0091                ,std::size_t num_char
0092                )
0093       :  m_value_bytes(val_bytes)
0094       ,  m_num_char((unsigned short)num_char)
0095       ,  m_value_alignment((unsigned char)val_alignment)
0096       ,  m_alloc_type_sizeof_char( (unsigned char)((al_type << 5u) | ((unsigned char)szof_char & 0x1F)) )
0097    {};
0098 
0099    template<class T>
0100    block_header &operator= (const T& )
0101    {  return *this;  }
0102 
0103    size_type total_size() const
0104    {
0105       if(alloc_type() != anonymous_type){
0106          return name_offset() + (m_num_char+1u)*sizeof_char();
0107       }
0108       else{
0109          return this->value_offset() + m_value_bytes;
0110       }
0111    }
0112 
0113    size_type value_bytes() const
0114    {  return m_value_bytes;   }
0115 
0116    template<class Header>
0117    size_type total_size_with_header() const
0118    {
0119       return get_rounded_size
0120                ( size_type(sizeof(Header))
0121             , size_type(::boost::container::dtl::alignment_of<block_header<size_type> >::value))
0122            + total_size();
0123    }
0124 
0125    unsigned char alloc_type() const
0126    {  return (m_alloc_type_sizeof_char >> 5u)&(unsigned char)0x7;  }
0127 
0128    unsigned char sizeof_char() const
0129    {  return m_alloc_type_sizeof_char & (unsigned char)0x1F;  }
0130 
0131    template<class CharType>
0132    CharType *name() const
0133    {
0134       return const_cast<CharType*>(move_detail::force_ptr<const CharType*>
0135          (reinterpret_cast<const char*>(this) + name_offset()));
0136    }
0137 
0138    unsigned short name_length() const
0139    {  return m_num_char;   }
0140 
0141    size_type name_offset() const
0142    {
0143       return this->value_offset() + get_rounded_size(size_type(m_value_bytes), size_type(sizeof_char()));
0144    }
0145 
0146    void *value() const
0147    {
0148       return const_cast<char*>((reinterpret_cast<const char*>(this) + this->value_offset()));
0149    }
0150 
0151    size_type value_offset() const
0152    {
0153       return get_rounded_size(size_type(sizeof(block_header<size_type>)), size_type(m_value_alignment));
0154    }
0155 
0156    template<class CharType>
0157    bool less_comp(const block_header<size_type> &b) const
0158    {
0159       return m_num_char < b.m_num_char ||
0160              (m_num_char < b.m_num_char &&
0161               std::char_traits<CharType>::compare(name<CharType>(), b.name<CharType>(), m_num_char) < 0);
0162    }
0163 
0164    template<class CharType>
0165    bool equal_comp(const block_header<size_type> &b) const
0166    {
0167       return m_num_char == b.m_num_char &&
0168              std::char_traits<CharType>::compare(name<CharType>(), b.name<CharType>(), m_num_char) == 0;
0169    }
0170 
0171    template<class T>
0172    static block_header<size_type> *block_header_from_value(T *value)
0173    {  return block_header_from_value(value, sizeof(T), ::boost::container::dtl::alignment_of<T>::value);  }
0174 
0175    static block_header<size_type> *block_header_from_value(const void *value, std::size_t sz, std::size_t algn)
0176    {
0177       block_header * hdr =
0178          const_cast<block_header*>
0179             (move_detail::force_ptr<const block_header*>(reinterpret_cast<const char*>(value) -
0180                get_rounded_size(sizeof(block_header), algn)));
0181       (void)sz;
0182       //Some sanity checks
0183       BOOST_ASSERT(hdr->m_value_alignment == algn);
0184       BOOST_ASSERT(hdr->m_value_bytes % sz == 0);
0185       return hdr;
0186    }
0187 
0188    template<class Header>
0189    static block_header<size_type> *from_first_header(Header *header)
0190    {
0191       block_header<size_type> * hdr =
0192          move_detail::force_ptr<block_header<size_type>*>(reinterpret_cast<char*>(header) +
0193        get_rounded_size( size_type(sizeof(Header))
0194                        , size_type(::boost::container::dtl::alignment_of<block_header<size_type> >::value)));
0195       //Some sanity checks
0196       return hdr;
0197    }
0198 
0199    template<class Header>
0200    static Header *to_first_header(block_header<size_type> *bheader)
0201    {
0202       Header * hdr =
0203          move_detail::force_ptr<Header*>(reinterpret_cast<char*>(bheader) -
0204        get_rounded_size( size_type(sizeof(Header))
0205                        , size_type(::boost::container::dtl::alignment_of<block_header<size_type> >::value)));
0206       //Some sanity checks
0207       return hdr;
0208    }
0209 };
0210 
0211 template<class CharT>
0212 struct intrusive_compare_key
0213 {
0214    typedef CharT char_type;
0215 
0216    intrusive_compare_key(const CharT *str, std::size_t len)
0217       :  mp_str(str), m_len(len)
0218    {}
0219 
0220    const CharT *  mp_str;
0221    std::size_t    m_len;
0222 };
0223 
0224 //!This struct indicates an anonymous object creation
0225 //!allocation
0226 template<instance_type type>
0227 class instance_t
0228 {
0229    instance_t(){}
0230 };
0231 
0232 template<class T>
0233 struct char_if_void
0234 {
0235    typedef T type;
0236 };
0237 
0238 template<>
0239 struct char_if_void<void>
0240 {
0241    typedef char type;
0242 };
0243 
0244 typedef instance_t<anonymous_type>  anonymous_instance_t;
0245 typedef instance_t<unique_type>     unique_instance_t;
0246 
0247 
0248 template<class Hook, class CharType, class SizeType>
0249 struct intrusive_value_type_impl
0250    :  public Hook
0251 {
0252    private:
0253    //Non-copyable
0254    intrusive_value_type_impl(const intrusive_value_type_impl &);
0255    intrusive_value_type_impl& operator=(const intrusive_value_type_impl &);
0256 
0257    public:
0258    typedef CharType char_type;
0259    typedef SizeType size_type;
0260 
0261    intrusive_value_type_impl(){}
0262 
0263    enum  {  BlockHdrAlignment = ::boost::container::dtl::alignment_of<block_header<size_type> >::value  };
0264 
0265    block_header<size_type> *get_block_header() const
0266    {
0267       return const_cast<block_header<size_type>*>
0268          (move_detail::force_ptr<const block_header<size_type> *>(reinterpret_cast<const char*>(this) +
0269             get_rounded_size(size_type(sizeof(*this)), size_type(BlockHdrAlignment))));
0270    }
0271 
0272    bool operator <(const intrusive_value_type_impl<Hook, CharType, SizeType> & other) const
0273    {  return (this->get_block_header())->template less_comp<CharType>(*other.get_block_header());  }
0274 
0275    bool operator ==(const intrusive_value_type_impl<Hook, CharType, SizeType> & other) const
0276    {  return (this->get_block_header())->template equal_comp<CharType>(*other.get_block_header());  }
0277 
0278    static intrusive_value_type_impl *get_intrusive_value_type(block_header<size_type> *hdr)
0279    {
0280       return move_detail::force_ptr<intrusive_value_type_impl*>(reinterpret_cast<char*>(hdr) -
0281          get_rounded_size(size_type(sizeof(intrusive_value_type_impl)), size_type(BlockHdrAlignment)));
0282    }
0283 
0284    CharType *name() const
0285    {  return get_block_header()->template name<CharType>(); }
0286 
0287    unsigned short name_length() const
0288    {  return get_block_header()->name_length(); }
0289 
0290    void *value() const
0291    {  return get_block_header()->value(); }
0292 };
0293 
0294 template<class CharType>
0295 class char_ptr_holder
0296 {
0297    public:
0298    char_ptr_holder(const CharType *name)
0299       : m_name(name)
0300    {}
0301 
0302    char_ptr_holder(const anonymous_instance_t *)
0303       : m_name(static_cast<CharType*>(0))
0304    {}
0305 
0306    char_ptr_holder(const unique_instance_t *)
0307       : m_name(reinterpret_cast<CharType*>(-1))
0308    {}
0309 
0310    operator const CharType *()
0311    {  return m_name;  }
0312 
0313    const CharType *get() const
0314    {  return m_name;  }
0315 
0316    bool is_unique() const
0317    {  return m_name == reinterpret_cast<CharType*>(-1);  }
0318 
0319    bool is_anonymous() const
0320    {  return m_name == static_cast<CharType*>(0);  }
0321 
0322    private:
0323    const CharType *m_name;
0324 };
0325 
0326 //!The key of the the named allocation information index. Stores an offset pointer
0327 //!to a null terminated string and the length of the string to speed up sorting
0328 template<class CharT, class VoidPointer>
0329 struct index_key
0330 {
0331    typedef typename boost::intrusive::
0332       pointer_traits<VoidPointer>::template
0333          rebind_pointer<const CharT>::type               const_char_ptr_t;
0334    typedef CharT                                         char_type;
0335    typedef typename boost::intrusive::pointer_traits<const_char_ptr_t>::difference_type difference_type;
0336    typedef typename boost::move_detail::make_unsigned<difference_type>::type size_type;
0337 
0338    private:
0339    //Offset pointer to the object's name
0340    const_char_ptr_t  mp_str;
0341    //Length of the name buffer (null NOT included)
0342    size_type         m_len;
0343    public:
0344 
0345    //!Constructor of the key
0346    index_key (const char_type *nm, size_type length)
0347       : mp_str(nm), m_len(length)
0348    {}
0349 
0350    //!Less than function for index ordering
0351    bool operator < (const index_key & right) const
0352    {
0353       return (m_len < right.m_len) ||
0354                (m_len == right.m_len &&
0355                 std::char_traits<char_type>::compare
0356                   (to_raw_pointer(mp_str),to_raw_pointer(right.mp_str), m_len) < 0);
0357    }
0358 
0359    //!Equal to function for index ordering
0360    bool operator == (const index_key & right) const
0361    {
0362       return   m_len == right.m_len &&
0363                std::char_traits<char_type>::compare
0364                   (to_raw_pointer(mp_str), to_raw_pointer(right.mp_str), m_len) == 0;
0365    }
0366 
0367    void name(const CharT *nm)
0368    {  mp_str = nm; }
0369 
0370    void name_length(size_type len)
0371    {  m_len = len; }
0372 
0373    const CharT *name() const
0374    {  return to_raw_pointer(mp_str); }
0375 
0376    size_type name_length() const
0377    {  return m_len; }
0378 };
0379 
0380 //!The index_data stores a pointer to a buffer and the element count needed
0381 //!to know how many destructors must be called when calling destroy
0382 template<class VoidPointer>
0383 struct index_data
0384 {
0385    typedef VoidPointer void_pointer;
0386    void_pointer    m_ptr;
0387    explicit index_data(void *ptr) : m_ptr(ptr){}
0388 
0389    void *value() const
0390    {  return static_cast<void*>(to_raw_pointer(m_ptr));  }
0391 };
0392 
0393 template<class MemoryAlgorithm>
0394 struct segment_manager_base_type
0395 {  typedef segment_manager_base<MemoryAlgorithm> type;   };
0396 
0397 template<class CharT, class MemoryAlgorithm>
0398 struct index_config
0399 {
0400    typedef typename MemoryAlgorithm::void_pointer        void_pointer;
0401    typedef CharT                                         char_type;
0402    typedef index_key<CharT, void_pointer>        key_type;
0403    typedef index_data<void_pointer>              mapped_type;
0404    typedef typename segment_manager_base_type
0405       <MemoryAlgorithm>::type                            segment_manager_base;
0406 
0407    template<class HeaderBase>
0408    struct intrusive_value_type
0409    {  typedef intrusive_value_type_impl<HeaderBase, CharT, typename segment_manager_base::size_type>  type; };
0410 
0411    typedef intrusive_compare_key<CharT>            intrusive_compare_key_type;
0412 };
0413 
0414 template<class Iterator, bool intrusive>
0415 class segment_manager_iterator_value_adaptor
0416 {
0417    typedef typename Iterator::value_type        iterator_val_t;
0418    typedef typename iterator_val_t::char_type   char_type;
0419 
0420    public:
0421    segment_manager_iterator_value_adaptor(const typename Iterator::value_type &val)
0422       :  m_val(&val)
0423    {}
0424 
0425    const char_type *name() const
0426    {  return m_val->name(); }
0427 
0428    unsigned short name_length() const
0429    {  return m_val->name_length(); }
0430 
0431    const void *value() const
0432    {  return m_val->value(); }
0433 
0434    const typename Iterator::value_type *m_val;
0435 };
0436 
0437 
0438 template<class Iterator>
0439 class segment_manager_iterator_value_adaptor<Iterator, false>
0440 {
0441    typedef typename Iterator::value_type        iterator_val_t;
0442    typedef typename iterator_val_t::first_type  first_type;
0443    typedef typename iterator_val_t::second_type second_type;
0444    typedef typename first_type::char_type       char_type;
0445    typedef typename first_type::size_type       size_type;
0446 
0447    public:
0448    segment_manager_iterator_value_adaptor(const typename Iterator::value_type &val)
0449       :  m_val(&val)
0450    {}
0451 
0452    const char_type *name() const
0453    {  return m_val->first.name(); }
0454 
0455    size_type name_length() const
0456    {  return m_val->first.name_length(); }
0457 
0458    const void *value() const
0459    {
0460       return move_detail::force_ptr<block_header<size_type>*>
0461          (to_raw_pointer(m_val->second.m_ptr))->value();
0462    }
0463 
0464    const typename Iterator::value_type *m_val;
0465 };
0466 
0467 template<class Iterator, bool intrusive>
0468 struct segment_manager_iterator_transform
0469 {
0470    typedef segment_manager_iterator_value_adaptor<Iterator, intrusive> result_type;
0471 
0472    template <class T> result_type operator()(const T &arg) const
0473    {  return result_type(arg); }
0474 };
0475 
0476 }  //namespace ipcdetail {
0477 
0478 //These pointers are the ones the user will use to
0479 //indicate previous allocation types
0480 static const ipcdetail::anonymous_instance_t   * anonymous_instance = 0;
0481 static const ipcdetail::unique_instance_t      * unique_instance = 0;
0482 
0483 namespace ipcdetail_really_deep_namespace {
0484 
0485 //Otherwise, gcc issues a warning of previously defined
0486 //anonymous_instance and unique_instance
0487 struct dummy
0488 {
0489    dummy()
0490    {
0491       (void)anonymous_instance;
0492       (void)unique_instance;
0493    }
0494 };
0495 
0496 }  //detail_really_deep_namespace
0497 
0498 }} //namespace boost { namespace interprocess
0499 
0500 #include <boost/interprocess/detail/config_end.hpp>
0501 
0502 #endif //#ifndef BOOST_INTERPROCESS_SEGMENT_MANAGER_BASE_HPP
0503