Ticket #5738: mapped_region.patch
File mapped_region.patch, 8.2 KB (added by , 11 years ago) |
---|
-
boost/interprocess/mapped_region.hpp
65 65 public: 66 66 67 67 //!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 70 70 //!"read_write. 71 71 template<class MemoryMappable> 72 72 mapped_region(const MemoryMappable& mapping … … 75 75 ,std::size_t size = 0 76 76 ,const void *address = 0); 77 77 78 //!Default constructor. Address will be invalid_address().78 //!Default constructor. Address will be NULL. 79 79 //!Size and offset will be 0. 80 80 //!Does not throw 81 81 mapped_region(); 82 82 83 //!Move constructor. *this will be constructed taking ownership of "other"'s 83 //!Move constructor. *this will be constructed taking ownership of "other"'s 84 84 //!region and "other" will be left in default constructor state. 85 85 mapped_region(BOOST_RV_REF(mapped_region) other) 86 86 #if defined (BOOST_INTERPROCESS_WINDOWS) … … 89 89 , m_mode(read_only) 90 90 , m_file_mapping_hnd(ipcdetail::invalid_file()) 91 91 #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) 93 93 #endif 94 94 { this->swap(other); } 95 95 … … 123 123 //!Never throws. 124 124 mode_t get_mode() const; 125 125 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. 131 127 //!Never throws 132 128 bool flush(std::size_t mapping_offset = 0, std::size_t numbytes = 0); 133 129 … … 173 169 inline void swap(mapped_region &x, mapped_region &y) 174 170 { x.swap(y); } 175 171 176 inline mapped_region::~mapped_region() 172 inline mapped_region::~mapped_region() 177 173 { this->priv_close(); } 178 174 179 inline std::size_t mapped_region::get_size() const 175 inline std::size_t mapped_region::get_size() const 180 176 { return m_size; } 181 177 182 inline offset_t mapped_region::get_offset() const 178 inline offset_t mapped_region::get_offset() const 183 179 { return m_offset; } 184 180 185 inline mode_t mapped_region::get_mode() const 181 inline mode_t mapped_region::get_mode() const 186 182 { return m_mode; } 187 183 188 inline void* mapped_region::get_address() const 184 inline void* mapped_region::get_address() const 189 185 { return m_base; } 190 186 191 187 #if defined (BOOST_INTERPROCESS_WINDOWS) … … 254 250 throw interprocess_exception(err); 255 251 } 256 252 257 if(static_cast<unsigned __int64>(total_size) > 253 if(static_cast<unsigned __int64>(total_size) > 258 254 (std::numeric_limits<std::size_t>::max)()){ 259 255 error_info err(size_error); 260 256 throw interprocess_exception(err); … … 263 259 } 264 260 265 261 //Create file mapping 266 native_mapping_handle = 262 native_mapping_handle = 267 263 winapi::create_file_mapping 268 264 (ipcdetail::file_handle_from_mapping_handle(mapping.get_mapping_handle()), file_map_access, 0, 0, 0, 0); 269 265 … … 275 271 } 276 272 } 277 273 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 279 275 //memory granularity 280 276 unsigned long granularity = 0; 281 277 unsigned long foffset_low; … … 315 311 //Map with new offsets and size 316 312 m_base = winapi::map_view_of_file_ex 317 313 (native_mapping_handle, 318 map_access, 314 map_access, 319 315 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, 322 318 const_cast<void*>(address)); 323 319 324 320 if(!mhandle.is_shm){ … … 357 353 358 354 //Flush it all 359 355 return winapi::flush_view_of_file 360 (static_cast<char*>(m_base)+mapping_offset, 356 (static_cast<char*>(m_base)+mapping_offset, 361 357 static_cast<std::size_t>(numbytes)); 362 358 } 363 359 … … 375 371 #endif 376 372 } 377 373 378 inline void* mapped_region::invalid_address()379 { return 0; }380 381 374 inline void mapped_region::dont_close_on_destruction() 382 375 {} 383 376 384 377 #else //#if (defined BOOST_INTERPROCESS_WINDOWS) 385 378 386 379 inline 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) 388 381 {} 389 382 390 383 template<int dummy> … … 398 391 offset_t offset, 399 392 std::size_t size, 400 393 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) 402 395 { 403 396 mapping_handle_t map_hnd = mapping.get_mapping_handle(); 404 397 … … 496 489 } 497 490 498 491 //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); 501 494 502 //Store user values in memory503 m_offset = offset;504 m_size = size;505 506 495 //Update the mapping address 507 496 if(address){ 508 address = static_cast<const char*>(address) - m_extra_offset;497 address = static_cast<const char*>(address) - extra_offset; 509 498 } 510 499 511 500 //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 , prot515 , flags516 , mapping.get_mapping_handle().handle517 , 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); 518 507 519 508 //Check if mapping was successful 520 if( m_base == MAP_FAILED){509 if(base == MAP_FAILED){ 521 510 error_info err = system_error_code(); 522 this->priv_close();523 511 throw interprocess_exception(err); 524 512 } 525 513 526 514 //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; 529 517 m_offset = offset; 530 518 m_size = size; 531 519 532 520 //Check for fixed mapping error 533 if(address && ( old_base != address)){521 if(address && (base != address)){ 534 522 error_info err(busy_error); 535 523 this->priv_close(); 536 524 throw interprocess_exception(err); … … 547 535 numbytes = m_size - mapping_offset; 548 536 } 549 537 //Flush it all 550 return msync(static_cast<char*>(m_base)+mapping_offset, 538 return msync(static_cast<char*>(m_base)+mapping_offset, 551 539 numbytes, MS_ASYNC) == 0; 552 540 } 553 541 554 542 inline void mapped_region::priv_close() 555 543 { 556 if(m_base != MAP_FAILED){544 if(m_base != 0){ 557 545 #ifdef BOOST_INTERPROCESS_XSI_SHARED_MEMORY_OBJECTS 558 546 if(m_is_xsi){ 559 547 int ret = ::shmdt(m_base); … … 563 551 } 564 552 #endif //#ifdef BOOST_INTERPROCESS_XSI_SHARED_MEMORY_OBJECTS 565 553 munmap(static_cast<char*>(m_base) - m_extra_offset, m_size + m_extra_offset); 566 m_base = MAP_FAILED;554 m_base = 0; 567 555 } 568 556 } 569 557 570 inline void* mapped_region::invalid_address()571 { return MAP_FAILED; }572 573 558 inline void mapped_region::dont_close_on_destruction() 574 { m_base = MAP_FAILED; }559 { m_base = 0; } 575 560 576 561 #endif //##if (defined BOOST_INTERPROCESS_WINDOWS) 577 562