Ticket #5738: mapped_region.patch

File mapped_region.patch, 8.2 KB (added by Andrey Semashev, 11 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