Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:38:27

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 inline void array_construct(void *mem, std::size_t num, in_place_interface &table)
0212 {
0213    //Try constructors
0214    std::size_t constructed = 0;
0215    BOOST_TRY{
0216       table.construct_n(mem, num, constructed);
0217    }
0218    //If there is an exception call destructors and erase index node
0219    BOOST_CATCH(...){
0220       std::size_t destroyed = 0;
0221       table.destroy_n(mem, constructed, destroyed);
0222       BOOST_RETHROW
0223    } BOOST_CATCH_END
0224 }
0225 
0226 template<class CharT>
0227 struct intrusive_compare_key
0228 {
0229    typedef CharT char_type;
0230 
0231    intrusive_compare_key(const CharT *str, std::size_t len)
0232       :  mp_str(str), m_len(len)
0233    {}
0234 
0235    const CharT *  mp_str;
0236    std::size_t    m_len;
0237 };
0238 
0239 //!This struct indicates an anonymous object creation
0240 //!allocation
0241 template<instance_type type>
0242 class instance_t
0243 {
0244    instance_t(){}
0245 };
0246 
0247 template<class T>
0248 struct char_if_void
0249 {
0250    typedef T type;
0251 };
0252 
0253 template<>
0254 struct char_if_void<void>
0255 {
0256    typedef char type;
0257 };
0258 
0259 typedef instance_t<anonymous_type>  anonymous_instance_t;
0260 typedef instance_t<unique_type>     unique_instance_t;
0261 
0262 
0263 template<class Hook, class CharType, class SizeType>
0264 struct intrusive_value_type_impl
0265    :  public Hook
0266 {
0267    private:
0268    //Non-copyable
0269    intrusive_value_type_impl(const intrusive_value_type_impl &);
0270    intrusive_value_type_impl& operator=(const intrusive_value_type_impl &);
0271 
0272    public:
0273    typedef CharType char_type;
0274    typedef SizeType size_type;
0275 
0276    intrusive_value_type_impl(){}
0277 
0278    enum  {  BlockHdrAlignment = ::boost::container::dtl::alignment_of<block_header<size_type> >::value  };
0279 
0280    block_header<size_type> *get_block_header() const
0281    {
0282       return const_cast<block_header<size_type>*>
0283          (move_detail::force_ptr<const block_header<size_type> *>(reinterpret_cast<const char*>(this) +
0284             get_rounded_size(size_type(sizeof(*this)), size_type(BlockHdrAlignment))));
0285    }
0286 
0287    bool operator <(const intrusive_value_type_impl<Hook, CharType, SizeType> & other) const
0288    {  return (this->get_block_header())->template less_comp<CharType>(*other.get_block_header());  }
0289 
0290    bool operator ==(const intrusive_value_type_impl<Hook, CharType, SizeType> & other) const
0291    {  return (this->get_block_header())->template equal_comp<CharType>(*other.get_block_header());  }
0292 
0293    static intrusive_value_type_impl *get_intrusive_value_type(block_header<size_type> *hdr)
0294    {
0295       return move_detail::force_ptr<intrusive_value_type_impl*>(reinterpret_cast<char*>(hdr) -
0296          get_rounded_size(size_type(sizeof(intrusive_value_type_impl)), size_type(BlockHdrAlignment)));
0297    }
0298 
0299    CharType *name() const
0300    {  return get_block_header()->template name<CharType>(); }
0301 
0302    unsigned short name_length() const
0303    {  return get_block_header()->name_length(); }
0304 
0305    void *value() const
0306    {  return get_block_header()->value(); }
0307 };
0308 
0309 template<class CharType>
0310 class char_ptr_holder
0311 {
0312    public:
0313    char_ptr_holder(const CharType *name)
0314       : m_name(name)
0315    {}
0316 
0317    char_ptr_holder(const anonymous_instance_t *)
0318       : m_name(static_cast<CharType*>(0))
0319    {}
0320 
0321    char_ptr_holder(const unique_instance_t *)
0322       : m_name(reinterpret_cast<CharType*>(-1))
0323    {}
0324 
0325    operator const CharType *()
0326    {  return m_name;  }
0327 
0328    const CharType *get() const
0329    {  return m_name;  }
0330 
0331    bool is_unique() const
0332    {  return m_name == reinterpret_cast<CharType*>(-1);  }
0333 
0334    bool is_anonymous() const
0335    {  return m_name == static_cast<CharType*>(0);  }
0336 
0337    private:
0338    const CharType *m_name;
0339 };
0340 
0341 //!The key of the the named allocation information index. Stores an offset pointer
0342 //!to a null terminated string and the length of the string to speed up sorting
0343 template<class CharT, class VoidPointer>
0344 struct index_key
0345 {
0346    typedef typename boost::intrusive::
0347       pointer_traits<VoidPointer>::template
0348          rebind_pointer<const CharT>::type               const_char_ptr_t;
0349    typedef CharT                                         char_type;
0350    typedef typename boost::intrusive::pointer_traits<const_char_ptr_t>::difference_type difference_type;
0351    typedef typename boost::move_detail::make_unsigned<difference_type>::type size_type;
0352 
0353    private:
0354    //Offset pointer to the object's name
0355    const_char_ptr_t  mp_str;
0356    //Length of the name buffer (null NOT included)
0357    size_type         m_len;
0358    public:
0359 
0360    //!Constructor of the key
0361    index_key (const char_type *nm, size_type length)
0362       : mp_str(nm), m_len(length)
0363    {}
0364 
0365    //!Less than function for index ordering
0366    bool operator < (const index_key & right) const
0367    {
0368       return (m_len < right.m_len) ||
0369                (m_len == right.m_len &&
0370                 std::char_traits<char_type>::compare
0371                   (to_raw_pointer(mp_str),to_raw_pointer(right.mp_str), m_len) < 0);
0372    }
0373 
0374    //!Equal to function for index ordering
0375    bool operator == (const index_key & right) const
0376    {
0377       return   m_len == right.m_len &&
0378                std::char_traits<char_type>::compare
0379                   (to_raw_pointer(mp_str), to_raw_pointer(right.mp_str), m_len) == 0;
0380    }
0381 
0382    void name(const CharT *nm)
0383    {  mp_str = nm; }
0384 
0385    void name_length(size_type len)
0386    {  m_len = len; }
0387 
0388    const CharT *name() const
0389    {  return to_raw_pointer(mp_str); }
0390 
0391    size_type name_length() const
0392    {  return m_len; }
0393 };
0394 
0395 //!The index_data stores a pointer to a buffer and the element count needed
0396 //!to know how many destructors must be called when calling destroy
0397 template<class VoidPointer>
0398 struct index_data
0399 {
0400    typedef VoidPointer void_pointer;
0401    void_pointer    m_ptr;
0402    explicit index_data(void *ptr) : m_ptr(ptr){}
0403 
0404    void *value() const
0405    {  return static_cast<void*>(to_raw_pointer(m_ptr));  }
0406 };
0407 
0408 template<class MemoryAlgorithm>
0409 struct segment_manager_base_type
0410 {  typedef segment_manager_base<MemoryAlgorithm> type;   };
0411 
0412 template<class CharT, class MemoryAlgorithm>
0413 struct index_config
0414 {
0415    typedef typename MemoryAlgorithm::void_pointer        void_pointer;
0416    typedef CharT                                         char_type;
0417    typedef index_key<CharT, void_pointer>        key_type;
0418    typedef index_data<void_pointer>              mapped_type;
0419    typedef typename segment_manager_base_type
0420       <MemoryAlgorithm>::type                            segment_manager_base;
0421 
0422    template<class HeaderBase>
0423    struct intrusive_value_type
0424    {  typedef intrusive_value_type_impl<HeaderBase, CharT, typename segment_manager_base::size_type>  type; };
0425 
0426    typedef intrusive_compare_key<CharT>            intrusive_compare_key_type;
0427 };
0428 
0429 template<class Iterator, bool intrusive>
0430 class segment_manager_iterator_value_adaptor
0431 {
0432    typedef typename Iterator::value_type        iterator_val_t;
0433    typedef typename iterator_val_t::char_type   char_type;
0434 
0435    public:
0436    segment_manager_iterator_value_adaptor(const typename Iterator::value_type &val)
0437       :  m_val(&val)
0438    {}
0439 
0440    const char_type *name() const
0441    {  return m_val->name(); }
0442 
0443    unsigned short name_length() const
0444    {  return m_val->name_length(); }
0445 
0446    const void *value() const
0447    {  return m_val->value(); }
0448 
0449    const typename Iterator::value_type *m_val;
0450 };
0451 
0452 
0453 template<class Iterator>
0454 class segment_manager_iterator_value_adaptor<Iterator, false>
0455 {
0456    typedef typename Iterator::value_type        iterator_val_t;
0457    typedef typename iterator_val_t::first_type  first_type;
0458    typedef typename iterator_val_t::second_type second_type;
0459    typedef typename first_type::char_type       char_type;
0460    typedef typename first_type::size_type       size_type;
0461 
0462    public:
0463    segment_manager_iterator_value_adaptor(const typename Iterator::value_type &val)
0464       :  m_val(&val)
0465    {}
0466 
0467    const char_type *name() const
0468    {  return m_val->first.name(); }
0469 
0470    size_type name_length() const
0471    {  return m_val->first.name_length(); }
0472 
0473    const void *value() const
0474    {
0475       return move_detail::force_ptr<block_header<size_type>*>
0476          (to_raw_pointer(m_val->second.m_ptr))->value();
0477    }
0478 
0479    const typename Iterator::value_type *m_val;
0480 };
0481 
0482 template<class Iterator, bool intrusive>
0483 struct segment_manager_iterator_transform
0484 {
0485    typedef segment_manager_iterator_value_adaptor<Iterator, intrusive> result_type;
0486 
0487    template <class T> result_type operator()(const T &arg) const
0488    {  return result_type(arg); }
0489 };
0490 
0491 }  //namespace ipcdetail {
0492 
0493 //These pointers are the ones the user will use to
0494 //indicate previous allocation types
0495 static const ipcdetail::anonymous_instance_t   * anonymous_instance = 0;
0496 static const ipcdetail::unique_instance_t      * unique_instance = 0;
0497 
0498 namespace ipcdetail_really_deep_namespace {
0499 
0500 //Otherwise, gcc issues a warning of previously defined
0501 //anonymous_instance and unique_instance
0502 struct dummy
0503 {
0504    dummy()
0505    {
0506       (void)anonymous_instance;
0507       (void)unique_instance;
0508    }
0509 };
0510 
0511 }  //detail_really_deep_namespace
0512 
0513 }} //namespace boost { namespace interprocess
0514 
0515 #include <boost/interprocess/detail/config_end.hpp>
0516 
0517 #endif //#ifndef BOOST_INTERPROCESS_SEGMENT_MANAGER_BASE_HPP
0518