intersegment_ptr.hpp
来自「Boost provides free peer-reviewed portab」· HPP 代码 · 共 1,042 行 · 第 1/3 页
HPP
1,042 行
//!Increments internal //!offset void inc_offset(std::ptrdiff_t bytes) { this->set_from_pointer(static_cast<char*>(this->get_pointer()) + bytes); } //!Decrements internal //!offset void dec_offset(std::ptrdiff_t bytes) { this->set_from_pointer(static_cast<char*>(this->get_pointer()) - bytes); } ////////////////////////////////////// ////////////////////////////////////// ////////////////////////////////////// flat_map_intersegment() : intersegment_base() {} ~flat_map_intersegment() {} private: class segment_group_t { struct segment_data { void *addr; std::size_t size; }; vector<segment_data> m_segments; multi_segment_services &m_ms_services; public: segment_group_t(multi_segment_services &ms_services) : m_ms_services(ms_services) {} void push_back(void *addr, std::size_t size) { segment_data d = { addr, size }; m_segments.push_back(d); } void pop_back() { assert(!m_segments.empty()); m_segments.erase(--m_segments.end()); } void *address_of(std::size_t segment_id) { assert(segment_id < (std::size_t)m_segments.size()); return m_segments[segment_id].addr; } void clear_segments() { m_segments.clear(); } std::size_t get_size() const { return m_segments.size(); } multi_segment_services &get_multi_segment_services() const { return m_ms_services; } friend bool operator< (const segment_group_t&l, const segment_group_t &r) { return &l.m_ms_services < &r.m_ms_services; } }; struct segment_info_t { std::size_t size; std::size_t id; segment_group_t *group; segment_info_t() : size(0), id(0), group(0) {} }; typedef set<segment_group_t> segment_groups_t; typedef boost::interprocess::flat_map <const void * ,segment_info_t ,std::less<const void *> > ptr_to_segment_info_t; struct mappings_t : Mutex { //!Mutex to preserve integrity in multi-threaded //!enviroments typedef Mutex mutex_type; //!Maps base addresses and segment information //!(size and segment group and id)* ptr_to_segment_info_t m_ptr_to_segment_info; ~mappings_t() { //Check that all mappings have been erased assert(m_ptr_to_segment_info.empty()); } }; //Static members static mappings_t s_map; static segment_groups_t s_groups; public: typedef segment_group_t* segment_group_id; //!Returns the segment and offset //!of an address static void get_segment_info_and_offset(const void *ptr, segment_info_t &segment, std::size_t &offset, void *&base) { //------------------------------------------------------------------ boost::interprocess::scoped_lock<typename mappings_t::mutex_type> lock(s_map); //------------------------------------------------------------------ base = 0; if(s_map.m_ptr_to_segment_info.empty()){ segment = segment_info_t(); offset = reinterpret_cast<const char*>(ptr) - static_cast<const char*>(0); return; } //Find the first base address greater than ptr typename ptr_to_segment_info_t::iterator it = s_map.m_ptr_to_segment_info.upper_bound(ptr); if(it == s_map.m_ptr_to_segment_info.begin()){ segment = segment_info_t(); offset = reinterpret_cast<const char*>(ptr) - static_cast<const char *>(0); } //Go to the previous one --it; char * segment_base = const_cast<char*>(reinterpret_cast<const char*>(it->first)); std::size_t segment_size = it->second.size; if(segment_base <= reinterpret_cast<const char*>(ptr) && (segment_base + segment_size) >= reinterpret_cast<const char*>(ptr)){ segment = it->second; offset = reinterpret_cast<const char*>(ptr) - segment_base; base = segment_base; } else{ segment = segment_info_t(); offset = reinterpret_cast<const char*>(ptr) - static_cast<const char*>(0); } } //!Associates a segment defined by group/id with a base address and size. //!Returns false if the group is not found or there is an error static void insert_mapping(segment_group_id group_id, void *ptr, std::size_t size) { //------------------------------------------------------------------ boost::interprocess::scoped_lock<typename mappings_t::mutex_type> lock(s_map); //------------------------------------------------------------------ typedef typename ptr_to_segment_info_t::value_type value_type; typedef typename ptr_to_segment_info_t::iterator iterator; typedef std::pair<iterator, bool> it_b_t; segment_info_t info; info.group = group_id; info.size = size; info.id = group_id->get_size(); it_b_t ret = s_map.m_ptr_to_segment_info.insert(value_type(ptr, info)); assert(ret.second); value_eraser<ptr_to_segment_info_t> v_eraser(s_map.m_ptr_to_segment_info, ret.first); group_id->push_back(ptr, size); v_eraser.release(); } static bool erase_last_mapping(segment_group_id group_id) { //------------------------------------------------------------------ boost::interprocess::scoped_lock<typename mappings_t::mutex_type> lock(s_map); //------------------------------------------------------------------ if(!group_id->get_size()){ return false; } else{ void *addr = group_id->address_of(group_id->get_size()-1); group_id->pop_back(); std::size_t erased = s_map.m_ptr_to_segment_info.erase(addr); (void)erased; assert(erased); return true; } } static segment_group_id new_segment_group(multi_segment_services *services) { { //------------------------------------------------------------------ boost::interprocess::scoped_lock<typename mappings_t::mutex_type> lock(s_map); //------------------------------------------------------------------ typedef typename segment_groups_t::iterator iterator; std::pair<iterator, bool> ret = s_groups.insert(segment_group_t(*services)); assert(ret.second); return &*ret.first; } } static bool delete_group(segment_group_id id) { { //------------------------------------------------------------------ boost::interprocess::scoped_lock<typename mappings_t::mutex_type> lock(s_map); //------------------------------------------------------------------ bool success = 1u == s_groups.erase(segment_group_t(*id)); if(success){ typedef typename ptr_to_segment_info_t::iterator ptr_to_segment_info_it; ptr_to_segment_info_it it(s_map.m_ptr_to_segment_info.begin()); while(it != s_map.m_ptr_to_segment_info.end()){ if(it->second.group == id){ it = s_map.m_ptr_to_segment_info.erase(it); } else{ ++it; } } } return success; } }};//!Static map-segment_info associated with//!flat_map_intersegment<>template <class Mutex>typename flat_map_intersegment<Mutex>::mappings_t flat_map_intersegment<Mutex>::s_map;//!Static segment group container associated with//!flat_map_intersegment<>template <class Mutex>typename flat_map_intersegment<Mutex>::segment_groups_t flat_map_intersegment<Mutex>::s_groups;//!A smart pointer that can point to a pointee that resides in another memory //!memory mapped or shared memory segment.template <class T>class intersegment_ptr : public flat_map_intersegment<interprocess_mutex>{ typedef flat_map_intersegment<interprocess_mutex> PT; typedef intersegment_ptr<T> self_t; typedef PT base_t; void unspecified_bool_type_func() const {} typedef void (self_t::*unspecified_bool_type)() const; public: typedef T * pointer; typedef typename detail::add_reference<T>::type reference; typedef T value_type; typedef std::ptrdiff_t difference_type; typedef std::random_access_iterator_tag iterator_category; public: //Public Functions //!Constructor from raw pointer (allows "0" pointer conversion). //!Never throws. intersegment_ptr(pointer ptr = 0) { base_t::set_from_pointer(ptr); } //!Constructor from other pointer. //!Never throws. template <class U> intersegment_ptr(U *ptr){ base_t::set_from_pointer(pointer(ptr)); } //!Constructor from other intersegment_ptr //!Never throws intersegment_ptr(const intersegment_ptr& ptr) { base_t::set_from_other(ptr); } //!Constructor from other intersegment_ptr. If pointers of pointee types are //!convertible, intersegment_ptrs will be convertibles. Never throws. template<class T2> intersegment_ptr(const intersegment_ptr<T2> &ptr) { pointer p(ptr.get()); (void)p; base_t::set_from_other(ptr); } //!Emulates static_cast operator. //!Never throws. template<class U> intersegment_ptr(const intersegment_ptr<U> &r, detail::static_cast_tag) { base_t::set_from_pointer(static_cast<T*>(r.get())); } //!Emulates const_cast operator. //!Never throws. template<class U> intersegment_ptr(const intersegment_ptr<U> &r, detail::const_cast_tag) { base_t::set_from_pointer(const_cast<T*>(r.get())); } //!Emulates dynamic_cast operator. //!Never throws. template<class U> intersegment_ptr(const intersegment_ptr<U> &r, detail::dynamic_cast_tag) { base_t::set_from_pointer(dynamic_cast<T*>(r.get())); } //!Emulates reinterpret_cast operator. //!Never throws. template<class U> intersegment_ptr(const intersegment_ptr<U> &r, detail::reinterpret_cast_tag) { base_t::set_from_pointer(reinterpret_cast<T*>(r.get())); } //!Obtains raw pointer from offset. //!Never throws. pointer get()const { return static_cast<pointer>(base_t::get_pointer()); } //!Pointer-like -> operator. It can return 0 pointer. //!Never throws. pointer operator->() const { return self_t::get(); } //!Dereferencing operator, if it is a null intersegment_ptr behavior //!is undefined. Never throws. reference operator* () const { return *(self_t::get()); } //!Indexing operator. //!Never throws. reference operator[](std::ptrdiff_t idx) const { return self_t::get()[idx]; } //!Assignment from pointer (saves extra conversion). //!Never throws. intersegment_ptr& operator= (pointer from) { base_t::set_from_pointer(from); return *this; } //!Assignment from other intersegment_ptr. //!Never throws. intersegment_ptr& operator= (const intersegment_ptr &ptr) { base_t::set_from_other(ptr); return *this; } //!Assignment from related intersegment_ptr. If pointers of pointee types //!are assignable, intersegment_ptrs will be assignable. Never throws. template <class T2> intersegment_ptr& operator= (const intersegment_ptr<T2> & ptr) { pointer p(ptr.get()); (void)p; base_t::set_from_other(ptr); return *this; }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?