Ticket #5738: mapped_region.patch

File mapped_region.patch, 8.2 KB (added by andysem, 2 years ago)

The patch that fixes initial address of mapped region.

  • boost/interprocess/mapped_region.hpp

     
    6565   public: 
    6666 
    6767   //!Creates a mapping region of the mapped memory "mapping", starting in 
    68    //!offset "offset", and the mapping's size will be "size". The mapping  
    69    //!can be opened for read-only "read_only" or read-write  
     68   //!offset "offset", and the mapping's size will be "size". The mapping 
     69   //!can be opened for read-only "read_only" or read-write 
    7070   //!"read_write. 
    7171   template<class MemoryMappable> 
    7272   mapped_region(const MemoryMappable& mapping 
     
    7575                ,std::size_t size = 0 
    7676                ,const void *address = 0); 
    7777 
    78    //!Default constructor. Address will be invalid_address(). 
     78   //!Default constructor. Address will be NULL. 
    7979   //!Size and offset will be 0. 
    8080   //!Does not throw 
    8181   mapped_region(); 
    8282 
    83    //!Move constructor. *this will be constructed taking ownership of "other"'s  
     83   //!Move constructor. *this will be constructed taking ownership of "other"'s 
    8484   //!region and "other" will be left in default constructor state. 
    8585   mapped_region(BOOST_RV_REF(mapped_region) other) 
    8686   #if defined (BOOST_INTERPROCESS_WINDOWS) 
     
    8989   ,  m_mode(read_only) 
    9090   ,  m_file_mapping_hnd(ipcdetail::invalid_file()) 
    9191   #else 
    92    :  m_base(MAP_FAILED), m_size(0), m_offset(0),  m_extra_offset(0), m_mode(read_only), m_is_xsi(false) 
     92   :  m_base(0), m_size(0), m_offset(0),  m_extra_offset(0), m_mode(read_only), m_is_xsi(false) 
    9393   #endif 
    9494   {  this->swap(other);   } 
    9595 
     
    123123   //!Never throws. 
    124124   mode_t get_mode() const; 
    125125 
    126    //!Returns the value that represents an invalid mapping address 
    127    //!Never throws. 
    128    static void* invalid_address(); 
    129  
    130    //!Flushes to the disk a byte range within the mapped memory.  
     126   //!Flushes to the disk a byte range within the mapped memory. 
    131127   //!Never throws 
    132128   bool flush(std::size_t mapping_offset = 0, std::size_t numbytes = 0); 
    133129 
     
    173169inline void swap(mapped_region &x, mapped_region &y) 
    174170{  x.swap(y);  } 
    175171 
    176 inline mapped_region::~mapped_region()  
     172inline mapped_region::~mapped_region() 
    177173{  this->priv_close(); } 
    178174 
    179 inline std::size_t mapped_region::get_size()  const   
     175inline std::size_t mapped_region::get_size()  const 
    180176{  return m_size; } 
    181177 
    182 inline offset_t mapped_region::get_offset()  const   
     178inline offset_t mapped_region::get_offset()  const 
    183179{  return m_offset;   } 
    184180 
    185 inline mode_t mapped_region::get_mode()  const   
     181inline mode_t mapped_region::get_mode()  const 
    186182{  return m_mode;   } 
    187183 
    188 inline void*    mapped_region::get_address()  const   
     184inline void*    mapped_region::get_address()  const 
    189185{  return m_base; } 
    190186 
    191187#if defined (BOOST_INTERPROCESS_WINDOWS) 
     
    254250            throw interprocess_exception(err); 
    255251         } 
    256252 
    257          if(static_cast<unsigned __int64>(total_size) >  
     253         if(static_cast<unsigned __int64>(total_size) > 
    258254            (std::numeric_limits<std::size_t>::max)()){ 
    259255            error_info err(size_error); 
    260256            throw interprocess_exception(err); 
     
    263259      } 
    264260 
    265261      //Create file mapping 
    266       native_mapping_handle =  
     262      native_mapping_handle = 
    267263         winapi::create_file_mapping 
    268264         (ipcdetail::file_handle_from_mapping_handle(mapping.get_mapping_handle()), file_map_access, 0, 0, 0, 0); 
    269265 
     
    275271      } 
    276272   } 
    277273 
    278    //We can't map any offset so we have to obtain system's  
     274   //We can't map any offset so we have to obtain system's 
    279275   //memory granularity 
    280276   unsigned long granularity = 0; 
    281277   unsigned long foffset_low; 
     
    315311   //Map with new offsets and size 
    316312   m_base = winapi::map_view_of_file_ex 
    317313                               (native_mapping_handle, 
    318                                 map_access,  
     314                                map_access, 
    319315                                foffset_high, 
    320                                 foffset_low,  
    321                                 m_size ? static_cast<std::size_t>(m_extra_offset + m_size) : 0,  
     316                                foffset_low, 
     317                                m_size ? static_cast<std::size_t>(m_extra_offset + m_size) : 0, 
    322318                                const_cast<void*>(address)); 
    323319 
    324320   if(!mhandle.is_shm){ 
     
    357353 
    358354   //Flush it all 
    359355   return winapi::flush_view_of_file 
    360       (static_cast<char*>(m_base)+mapping_offset,  
     356      (static_cast<char*>(m_base)+mapping_offset, 
    361357       static_cast<std::size_t>(numbytes)); 
    362358} 
    363359 
     
    375371   #endif 
    376372} 
    377373 
    378 inline void* mapped_region::invalid_address()   
    379 {  return 0; } 
    380  
    381374inline void mapped_region::dont_close_on_destruction() 
    382375{} 
    383376 
    384377#else    //#if (defined BOOST_INTERPROCESS_WINDOWS) 
    385378 
    386379inline mapped_region::mapped_region() 
    387    :  m_base(MAP_FAILED), m_size(0), m_offset(0),  m_extra_offset(0), m_mode(read_only), m_is_xsi(false) 
     380   :  m_base(0), m_size(0), m_offset(0),  m_extra_offset(0), m_mode(read_only), m_is_xsi(false) 
    388381{} 
    389382 
    390383template<int dummy> 
     
    398391   offset_t offset, 
    399392   std::size_t size, 
    400393   const void *address) 
    401    :  m_base(MAP_FAILED), m_size(0), m_offset(0),  m_extra_offset(0), m_mode(mode), m_is_xsi(false) 
     394   :  m_base(0), m_size(0), m_offset(0),  m_extra_offset(0), m_mode(mode), m_is_xsi(false) 
    402395{ 
    403396   mapping_handle_t map_hnd = mapping.get_mapping_handle(); 
    404397 
     
    496489   } 
    497490 
    498491   //We calculate the difference between demanded and valid offset 
    499    std::size_t page_size = this->get_page_size(); 
    500    m_extra_offset = (offset - (offset / page_size) * page_size); 
     492   const std::size_t page_size = this->get_page_size(); 
     493   const std::size_t extra_offset = (offset - (offset / page_size) * page_size); 
    501494 
    502    //Store user values in memory 
    503    m_offset = offset; 
    504    m_size   = size; 
    505  
    506495   //Update the mapping address 
    507496   if(address){ 
    508       address = static_cast<const char*>(address) - m_extra_offset; 
     497      address = static_cast<const char*>(address) - extra_offset; 
    509498   } 
    510499 
    511500   //Map it to the address space 
    512    m_base  = mmap  ( const_cast<void*>(address) 
    513                     , static_cast<std::size_t>(m_extra_offset + m_size) 
    514                     , prot 
    515                     , flags 
    516                     , mapping.get_mapping_handle().handle 
    517                     , offset - m_extra_offset); 
     501   void* base = mmap  ( const_cast<void*>(address) 
     502                      , static_cast<std::size_t>(extra_offset + size) 
     503                      , prot 
     504                      , flags 
     505                      , mapping.get_mapping_handle().handle 
     506                      , offset - extra_offset); 
    518507 
    519508   //Check if mapping was successful 
    520    if(m_base == MAP_FAILED){ 
     509   if(base == MAP_FAILED){ 
    521510      error_info err = system_error_code(); 
    522       this->priv_close(); 
    523511      throw interprocess_exception(err); 
    524512   } 
    525513 
    526514   //Calculate new base for the user 
    527    const void *old_base = m_base; 
    528    m_base = static_cast<char*>(m_base) + m_extra_offset; 
     515   m_base = static_cast<char*>(base) + extra_offset; 
     516   m_extra_offset = extra_offset; 
    529517   m_offset = offset; 
    530518   m_size   = size; 
    531519 
    532520   //Check for fixed mapping error 
    533    if(address && (old_base != address)){ 
     521   if(address && (base != address)){ 
    534522      error_info err(busy_error); 
    535523      this->priv_close(); 
    536524      throw interprocess_exception(err); 
     
    547535      numbytes = m_size - mapping_offset; 
    548536   } 
    549537   //Flush it all 
    550    return msync(static_cast<char*>(m_base)+mapping_offset,  
     538   return msync(static_cast<char*>(m_base)+mapping_offset, 
    551539                numbytes, MS_ASYNC) == 0; 
    552540} 
    553541 
    554542inline void mapped_region::priv_close() 
    555543{ 
    556    if(m_base != MAP_FAILED){ 
     544   if(m_base != 0){ 
    557545      #ifdef BOOST_INTERPROCESS_XSI_SHARED_MEMORY_OBJECTS 
    558546      if(m_is_xsi){ 
    559547         int ret = ::shmdt(m_base); 
     
    563551      } 
    564552      #endif //#ifdef BOOST_INTERPROCESS_XSI_SHARED_MEMORY_OBJECTS 
    565553      munmap(static_cast<char*>(m_base) - m_extra_offset, m_size + m_extra_offset); 
    566       m_base = MAP_FAILED; 
     554      m_base = 0; 
    567555   } 
    568556} 
    569557 
    570 inline void* mapped_region::invalid_address() 
    571 {  return MAP_FAILED; } 
    572  
    573558inline void mapped_region::dont_close_on_destruction() 
    574 {  m_base = MAP_FAILED;   } 
     559{  m_base = 0;   } 
    575560 
    576561#endif   //##if (defined BOOST_INTERPROCESS_WINDOWS) 
    577562