File indexing completed on 2025-01-30 09:44:12
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_INTERPROCESS_MAPPED_REGION_HPP
0012 #define BOOST_INTERPROCESS_MAPPED_REGION_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 #include <boost/interprocess/interprocess_fwd.hpp>
0026 #include <boost/interprocess/exceptions.hpp>
0027 #include <boost/move/utility_core.hpp>
0028 #include <boost/interprocess/detail/utilities.hpp>
0029 #include <boost/interprocess/detail/os_file_functions.hpp>
0030 #include <string>
0031 #include <boost/cstdint.hpp>
0032 #include <boost/assert.hpp>
0033 #include <boost/move/adl_move_swap.hpp>
0034
0035
0036
0037 #if defined(sun) || defined(__sun) || defined(__osf__) || defined(__osf) || defined(_hpux) || defined(hpux) || defined(_AIX)
0038 #define BOOST_INTERPROCESS_MADVISE_USES_CADDR_T
0039 #include <sys/types.h>
0040 #endif
0041
0042
0043
0044 #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__APPLE__)
0045 #define BOOST_INTERPROCESS_MADV_DONTNEED_HAS_NONDESTRUCTIVE_SEMANTICS
0046 #endif
0047
0048 #if defined (BOOST_INTERPROCESS_WINDOWS)
0049 # include <boost/interprocess/detail/win32_api.hpp>
0050 #else
0051 # ifdef BOOST_HAS_UNISTD_H
0052 # include <fcntl.h>
0053 # include <sys/mman.h> //mmap
0054 # include <unistd.h>
0055 # include <sys/stat.h>
0056 # include <sys/types.h>
0057 # if defined(BOOST_INTERPROCESS_XSI_SHARED_MEMORY_OBJECTS)
0058 # include <sys/shm.h> //System V shared memory...
0059 # endif
0060 # include <boost/assert.hpp>
0061 # else
0062 # error Unknown platform
0063 # endif
0064
0065 #endif
0066
0067
0068
0069
0070 namespace boost {
0071 namespace interprocess {
0072
0073 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0074
0075
0076
0077 #if (defined(sun) || defined(__sun)) && defined(MADV_NORMAL)
0078 extern "C" int madvise(caddr_t, size_t, int);
0079 #endif
0080
0081 namespace ipcdetail{ class interprocess_tester; }
0082 namespace ipcdetail{ class raw_mapped_region_creator; }
0083
0084 #endif
0085
0086
0087
0088
0089
0090
0091
0092 class mapped_region
0093 {
0094 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0095
0096 BOOST_MOVABLE_BUT_NOT_COPYABLE(mapped_region)
0097 #endif
0098
0099 public:
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127 template<class MemoryMappable>
0128 mapped_region(const MemoryMappable& mapping
0129 ,mode_t mode
0130 ,offset_t offset = 0
0131 ,std::size_t size = 0
0132 ,const void *address = 0
0133 ,map_options_t map_options = default_map_options);
0134
0135
0136
0137
0138 mapped_region() BOOST_NOEXCEPT;
0139
0140
0141
0142 mapped_region(BOOST_RV_REF(mapped_region) other) BOOST_NOEXCEPT
0143 #if defined (BOOST_INTERPROCESS_WINDOWS)
0144 : m_base(0), m_size(0)
0145 , m_page_offset(0)
0146 , m_mode(read_only)
0147 , m_file_or_mapping_hnd(ipcdetail::invalid_file())
0148 #else
0149 : m_base(0), m_size(0), m_page_offset(0), m_mode(read_only), m_is_xsi(false)
0150 #endif
0151 { this->swap(other); }
0152
0153
0154
0155 ~mapped_region();
0156
0157
0158
0159 mapped_region &operator=(BOOST_RV_REF(mapped_region) other) BOOST_NOEXCEPT
0160 {
0161 mapped_region tmp(boost::move(other));
0162 this->swap(tmp);
0163 return *this;
0164 }
0165
0166
0167
0168 void swap(mapped_region &other) BOOST_NOEXCEPT;
0169
0170
0171 std::size_t get_size() const BOOST_NOEXCEPT;
0172
0173
0174
0175 void* get_address() const BOOST_NOEXCEPT;
0176
0177
0178
0179 mode_t get_mode() const BOOST_NOEXCEPT;
0180
0181
0182
0183
0184
0185
0186 bool flush(std::size_t mapping_offset = 0, std::size_t numbytes = 0, bool async = true);
0187
0188
0189
0190
0191
0192
0193
0194 bool shrink_by(std::size_t bytes, bool from_back = true);
0195
0196
0197
0198 enum advice_types{
0199
0200
0201 advice_normal,
0202
0203
0204
0205 advice_sequential,
0206
0207
0208 advice_random,
0209
0210
0211 advice_willneed,
0212
0213
0214 advice_dontneed
0215 };
0216
0217
0218
0219
0220
0221
0222 bool advise(advice_types advise);
0223
0224
0225
0226
0227 static std::size_t get_page_size() BOOST_NOEXCEPT;
0228
0229 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0230 private:
0231
0232 void priv_close();
0233
0234 void* priv_map_address() const;
0235 std::size_t priv_map_size() const;
0236 bool priv_flush_param_check(std::size_t mapping_offset, void *&addr, std::size_t &numbytes) const;
0237 bool priv_shrink_param_check(std::size_t bytes, bool from_back, void *&shrink_page_start, std::size_t &shrink_page_bytes);
0238 static void priv_size_from_mapping_size
0239 (offset_t mapping_size, offset_t offset, offset_t page_offset, std::size_t &size);
0240 static offset_t priv_page_offset_addr_fixup(offset_t page_offset, const void *&addr);
0241
0242 template<int dummy>
0243 struct page_size_holder
0244 {
0245 static const std::size_t PageSize;
0246 static std::size_t get_page_size();
0247 };
0248
0249 void* m_base;
0250 std::size_t m_size;
0251 std::size_t m_page_offset;
0252 mode_t m_mode;
0253 #if defined(BOOST_INTERPROCESS_WINDOWS)
0254 file_handle_t m_file_or_mapping_hnd;
0255 #else
0256 bool m_is_xsi;
0257 #endif
0258
0259 friend class ipcdetail::interprocess_tester;
0260 friend class ipcdetail::raw_mapped_region_creator;
0261 void dont_close_on_destruction();
0262 #if defined(BOOST_INTERPROCESS_WINDOWS) && !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION)
0263 template<int Dummy>
0264 static void destroy_syncs_in_range(const void *addr, std::size_t size);
0265 #endif
0266 #endif
0267 };
0268
0269 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0270
0271 inline void swap(mapped_region &x, mapped_region &y) BOOST_NOEXCEPT
0272 { x.swap(y); }
0273
0274 inline mapped_region::~mapped_region()
0275 { this->priv_close(); }
0276
0277 inline std::size_t mapped_region::get_size() const BOOST_NOEXCEPT
0278 { return m_size; }
0279
0280 inline mode_t mapped_region::get_mode() const BOOST_NOEXCEPT
0281 { return m_mode; }
0282
0283 inline void* mapped_region::get_address() const BOOST_NOEXCEPT
0284 { return m_base; }
0285
0286 inline void* mapped_region::priv_map_address() const
0287 { return static_cast<char*>(m_base) - m_page_offset; }
0288
0289 inline std::size_t mapped_region::priv_map_size() const
0290 { return m_size + m_page_offset; }
0291
0292 inline bool mapped_region::priv_flush_param_check
0293 (std::size_t mapping_offset, void *&addr, std::size_t &numbytes) const
0294 {
0295
0296 if(m_base == 0)
0297 return false;
0298
0299 if(mapping_offset >= m_size || numbytes > (m_size - size_t(mapping_offset))){
0300 return false;
0301 }
0302
0303
0304 if(numbytes == 0){
0305 numbytes = m_size - mapping_offset;
0306 }
0307 addr = (char*)this->priv_map_address() + mapping_offset;
0308 numbytes += m_page_offset;
0309 return true;
0310 }
0311
0312 inline bool mapped_region::priv_shrink_param_check
0313 (std::size_t bytes, bool from_back, void *&shrink_page_start, std::size_t &shrink_page_bytes)
0314 {
0315
0316 if(m_base == 0 || bytes > m_size){
0317 return false;
0318 }
0319 else if(bytes == m_size){
0320 this->priv_close();
0321 return true;
0322 }
0323 else{
0324 const std::size_t page_size = mapped_region::get_page_size();
0325 if(from_back){
0326 const std::size_t new_pages = (m_size + m_page_offset - bytes - 1)/page_size + 1;
0327 shrink_page_start = static_cast<char*>(this->priv_map_address()) + new_pages*page_size;
0328 shrink_page_bytes = m_page_offset + m_size - new_pages*page_size;
0329 m_size -= bytes;
0330 }
0331 else{
0332 shrink_page_start = this->priv_map_address();
0333 m_page_offset += bytes;
0334 shrink_page_bytes = (m_page_offset/page_size)*page_size;
0335 m_page_offset = m_page_offset % page_size;
0336 m_size -= bytes;
0337 m_base = static_cast<char *>(m_base) + bytes;
0338 BOOST_ASSERT(shrink_page_bytes%page_size == 0);
0339 }
0340 return true;
0341 }
0342 }
0343
0344 inline void mapped_region::priv_size_from_mapping_size
0345 (offset_t mapping_size, offset_t offset, offset_t page_offset, std::size_t &size)
0346 {
0347
0348
0349 if(mapping_size < offset ||
0350 boost::uintmax_t(mapping_size - (offset - page_offset)) >
0351 boost::uintmax_t(std::size_t(-1))){
0352 error_info err(size_error);
0353 throw interprocess_exception(err);
0354 }
0355 size = static_cast<std::size_t>(mapping_size - offset);
0356 }
0357
0358 inline offset_t mapped_region::priv_page_offset_addr_fixup(offset_t offset, const void *&address)
0359 {
0360
0361
0362 const std::size_t page_size = mapped_region::get_page_size();
0363
0364
0365
0366 const std::size_t page_offset =
0367 static_cast<std::size_t>(offset - (offset / offset_t(page_size)) * offset_t(page_size));
0368
0369 if(address){
0370 address = static_cast<const char*>(address) - page_offset;
0371 }
0372 return offset_t(page_offset);
0373 }
0374
0375 #if defined (BOOST_INTERPROCESS_WINDOWS)
0376
0377 inline mapped_region::mapped_region() BOOST_NOEXCEPT
0378 : m_base(0), m_size(0), m_page_offset(0), m_mode(read_only)
0379 , m_file_or_mapping_hnd(ipcdetail::invalid_file())
0380 {}
0381
0382 template<int dummy>
0383 inline std::size_t mapped_region::page_size_holder<dummy>::get_page_size()
0384 {
0385 winapi::interprocess_system_info info;
0386 winapi::get_system_info(&info);
0387 return std::size_t(info.dwAllocationGranularity);
0388 }
0389
0390 template<class MemoryMappable>
0391 inline mapped_region::mapped_region
0392 (const MemoryMappable &mapping
0393 ,mode_t mode
0394 ,offset_t offset
0395 ,std::size_t size
0396 ,const void *address
0397 ,map_options_t map_options)
0398 : m_base(0), m_size(0), m_page_offset(0), m_mode(mode)
0399 , m_file_or_mapping_hnd(ipcdetail::invalid_file())
0400 {
0401 mapping_handle_t mhandle = mapping.get_mapping_handle();
0402 {
0403 file_handle_t native_mapping_handle = 0;
0404
0405
0406
0407 unsigned long protection = 0;
0408
0409 unsigned long map_access = map_options == default_map_options ? 0 : map_options;
0410
0411 switch(mode)
0412 {
0413 case read_only:
0414 case read_private:
0415 protection |= winapi::page_readonly;
0416 map_access |= winapi::file_map_read;
0417 break;
0418 case read_write:
0419 protection |= winapi::page_readwrite;
0420 map_access |= winapi::file_map_write;
0421 break;
0422 case copy_on_write:
0423 protection |= winapi::page_writecopy;
0424 map_access |= winapi::file_map_copy;
0425 break;
0426 default:
0427 {
0428 error_info err(mode_error);
0429 throw interprocess_exception(err);
0430 }
0431 break;
0432 }
0433
0434
0435
0436
0437
0438
0439 void * handle_to_close = winapi::invalid_handle_value;
0440 if(!mhandle.is_shm){
0441
0442 native_mapping_handle = winapi::create_file_mapping
0443 ( ipcdetail::file_handle_from_mapping_handle(mapping.get_mapping_handle())
0444 , protection, 0, (char*)0, 0);
0445
0446
0447 if(!native_mapping_handle){
0448 error_info err ((int)winapi::get_last_error());
0449 throw interprocess_exception(err);
0450 }
0451 handle_to_close = native_mapping_handle;
0452 }
0453 else{
0454
0455
0456 native_mapping_handle = mhandle.handle;
0457 }
0458
0459 const winapi::handle_closer close_handle(handle_to_close);
0460 (void)close_handle;
0461
0462 const offset_t page_offset = priv_page_offset_addr_fixup(offset, address);
0463
0464
0465 if(size == 0){
0466 offset_t mapping_size;
0467 if(!winapi::get_file_mapping_size(native_mapping_handle, mapping_size)){
0468 error_info err((int)winapi::get_last_error());
0469 throw interprocess_exception(err);
0470 }
0471
0472 priv_size_from_mapping_size(mapping_size, offset, page_offset, size);
0473 }
0474
0475
0476 void *base = winapi::map_view_of_file_ex
0477 (native_mapping_handle,
0478 map_access,
0479 ::boost::ulong_long_type(offset - page_offset),
0480 static_cast<std::size_t>(page_offset + size),
0481 const_cast<void*>(address));
0482
0483 if(!base){
0484 error_info err((int)winapi::get_last_error());
0485 throw interprocess_exception(err);
0486 }
0487
0488
0489 m_base = static_cast<char*>(base) + page_offset;
0490 m_page_offset = static_cast<std::size_t>(page_offset);
0491 m_size = size;
0492 }
0493
0494
0495
0496
0497 if(!winapi::duplicate_current_process_handle(mhandle.handle, &m_file_or_mapping_hnd)){
0498 error_info err((int)winapi::get_last_error());
0499 this->priv_close();
0500 throw interprocess_exception(err);
0501 }
0502 }
0503
0504 inline bool mapped_region::flush(std::size_t mapping_offset, std::size_t numbytes, bool async)
0505 {
0506 void *addr;
0507 if(!this->priv_flush_param_check(mapping_offset, addr, numbytes)){
0508 return false;
0509 }
0510
0511 if(!winapi::flush_view_of_file(addr, numbytes)){
0512 return false;
0513 }
0514
0515
0516 else if(!async && m_file_or_mapping_hnd != winapi::invalid_handle_value &&
0517 winapi::get_file_type(m_file_or_mapping_hnd) == winapi::file_type_disk){
0518 return winapi::flush_file_buffers(m_file_or_mapping_hnd);
0519 }
0520 return true;
0521 }
0522
0523 inline bool mapped_region::shrink_by(std::size_t bytes, bool from_back)
0524 {
0525 void *shrink_page_start = 0;
0526 std::size_t shrink_page_bytes = 0;
0527 if(!this->priv_shrink_param_check(bytes, from_back, shrink_page_start, shrink_page_bytes)){
0528 return false;
0529 }
0530 else if(shrink_page_bytes){
0531
0532
0533
0534 unsigned long old_protect_ignored;
0535 bool b_ret = winapi::virtual_unlock(shrink_page_start, shrink_page_bytes)
0536 || (winapi::get_last_error() == winapi::error_not_locked);
0537 (void)old_protect_ignored;
0538
0539 b_ret = b_ret && winapi::virtual_protect
0540 (shrink_page_start, shrink_page_bytes, winapi::page_noaccess, old_protect_ignored);
0541 return b_ret;
0542 }
0543 else{
0544 return true;
0545 }
0546 }
0547
0548 inline bool mapped_region::advise(advice_types)
0549 {
0550
0551 return false;
0552 }
0553
0554 inline void mapped_region::priv_close()
0555 {
0556 if(m_base){
0557 void *addr = this->priv_map_address();
0558 #if !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION)
0559 mapped_region::destroy_syncs_in_range<0>(addr, m_size);
0560 #endif
0561 winapi::unmap_view_of_file(addr);
0562 m_base = 0;
0563 }
0564 if(m_file_or_mapping_hnd != ipcdetail::invalid_file()){
0565 winapi::close_handle(m_file_or_mapping_hnd);
0566 m_file_or_mapping_hnd = ipcdetail::invalid_file();
0567 }
0568 }
0569
0570 inline void mapped_region::dont_close_on_destruction()
0571 {}
0572
0573 #else
0574
0575 inline mapped_region::mapped_region() BOOST_NOEXCEPT
0576 : m_base(0), m_size(0), m_page_offset(0), m_mode(read_only), m_is_xsi(false)
0577 {}
0578
0579 template<int dummy>
0580 inline std::size_t mapped_region::page_size_holder<dummy>::get_page_size()
0581 { return std::size_t(sysconf(_SC_PAGESIZE)); }
0582
0583 template<class MemoryMappable>
0584 inline mapped_region::mapped_region
0585 ( const MemoryMappable &mapping
0586 , mode_t mode
0587 , offset_t offset
0588 , std::size_t size
0589 , const void *address
0590 , map_options_t map_options)
0591 : m_base(0), m_size(0), m_page_offset(0), m_mode(mode), m_is_xsi(false)
0592 {
0593 mapping_handle_t map_hnd = mapping.get_mapping_handle();
0594
0595
0596 #ifdef BOOST_INTERPROCESS_XSI_SHARED_MEMORY_OBJECTS
0597 if(map_hnd.is_xsi){
0598
0599 ::shmid_ds xsi_ds;
0600 int ret = ::shmctl(map_hnd.handle, IPC_STAT, &xsi_ds);
0601 if(ret == -1){
0602 error_info err(system_error_code());
0603 throw interprocess_exception(err);
0604 }
0605
0606 if(size == 0){
0607 size = (std::size_t)xsi_ds.shm_segsz;
0608 }
0609 else if(size != (std::size_t)xsi_ds.shm_segsz){
0610 error_info err(size_error);
0611 throw interprocess_exception(err);
0612 }
0613
0614 int flag = map_options == default_map_options ? 0 : map_options;
0615 if(m_mode == read_only){
0616 flag |= SHM_RDONLY;
0617 }
0618 else if(m_mode != read_write){
0619 error_info err(mode_error);
0620 throw interprocess_exception(err);
0621 }
0622
0623
0624
0625 void *const final_address = const_cast<void *>(address);
0626 void *base = ::shmat(map_hnd.handle, final_address, flag);
0627 if(base == (void*)-1){
0628 error_info err(system_error_code());
0629 throw interprocess_exception(err);
0630 }
0631
0632 m_base = base;
0633 m_size = size;
0634 m_mode = mode;
0635 m_page_offset = 0;
0636 m_is_xsi = true;
0637 return;
0638 }
0639 #endif
0640
0641
0642 const offset_t page_offset = priv_page_offset_addr_fixup(offset, address);
0643
0644 if(size == 0){
0645 struct ::stat buf;
0646 if(0 != fstat(map_hnd.handle, &buf)){
0647 error_info err(system_error_code());
0648 throw interprocess_exception(err);
0649 }
0650
0651 priv_size_from_mapping_size(buf.st_size, offset, page_offset, size);
0652 }
0653
0654 #ifdef MAP_NOSYNC
0655 #define BOOST_INTERPROCESS_MAP_NOSYNC MAP_NOSYNC
0656 #else
0657 #define BOOST_INTERPROCESS_MAP_NOSYNC 0
0658 #endif
0659
0660
0661 int prot = 0;
0662 int flags = map_options == default_map_options ? BOOST_INTERPROCESS_MAP_NOSYNC : map_options;
0663
0664 #undef BOOST_INTERPROCESS_MAP_NOSYNC
0665
0666 switch(mode)
0667 {
0668 case read_only:
0669 prot |= PROT_READ;
0670 flags |= MAP_SHARED;
0671 break;
0672
0673 case read_private:
0674 prot |= (PROT_READ);
0675 flags |= MAP_PRIVATE;
0676 break;
0677
0678 case read_write:
0679 prot |= (PROT_WRITE | PROT_READ);
0680 flags |= MAP_SHARED;
0681 break;
0682
0683 case copy_on_write:
0684 prot |= (PROT_WRITE | PROT_READ);
0685 flags |= MAP_PRIVATE;
0686 break;
0687
0688 default:
0689 {
0690 error_info err(mode_error);
0691 throw interprocess_exception(err);
0692 }
0693 break;
0694 }
0695
0696
0697 void* base = mmap ( const_cast<void*>(address)
0698 , static_cast<std::size_t>(page_offset) + size
0699 , prot
0700 , flags
0701 , mapping.get_mapping_handle().handle
0702 , offset - page_offset);
0703
0704
0705 if(base == MAP_FAILED){
0706 error_info err = system_error_code();
0707 throw interprocess_exception(err);
0708 }
0709
0710
0711 m_base = static_cast<char*>(base) + page_offset;
0712 m_page_offset = static_cast<std::size_t>(page_offset);
0713 m_size = size;
0714
0715
0716 if(address && (base != address)){
0717 error_info err(busy_error);
0718 this->priv_close();
0719 throw interprocess_exception(err);
0720 }
0721 }
0722
0723 inline bool mapped_region::shrink_by(std::size_t bytes, bool from_back)
0724 {
0725 void *shrink_page_start = 0;
0726 std::size_t shrink_page_bytes = 0;
0727 if(m_is_xsi || !this->priv_shrink_param_check(bytes, from_back, shrink_page_start, shrink_page_bytes)){
0728 return false;
0729 }
0730 else if(shrink_page_bytes){
0731
0732 return 0 == munmap(shrink_page_start, shrink_page_bytes);
0733 }
0734 else{
0735 return true;
0736 }
0737 }
0738
0739 inline bool mapped_region::flush(std::size_t mapping_offset, std::size_t numbytes, bool async)
0740 {
0741 void *addr;
0742 if(m_is_xsi || !this->priv_flush_param_check(mapping_offset, addr, numbytes)){
0743 return false;
0744 }
0745
0746 return msync(addr, numbytes, async ? MS_ASYNC : MS_SYNC) == 0;
0747 }
0748
0749 inline bool mapped_region::advise(advice_types advice)
0750 {
0751 int unix_advice = 0;
0752
0753 const unsigned int mode_none = 0;
0754 const unsigned int mode_padv = 1;
0755 const unsigned int mode_madv = 2;
0756
0757 (void)mode_padv;
0758 (void)mode_madv;
0759 unsigned int mode = mode_none;
0760
0761 switch(advice){
0762 case advice_normal:
0763 #if defined(POSIX_MADV_NORMAL)
0764 unix_advice = POSIX_MADV_NORMAL;
0765 mode = mode_padv;
0766 #elif defined(MADV_NORMAL)
0767 unix_advice = MADV_NORMAL;
0768 mode = mode_madv;
0769 #endif
0770 break;
0771 case advice_sequential:
0772 #if defined(POSIX_MADV_SEQUENTIAL)
0773 unix_advice = POSIX_MADV_SEQUENTIAL;
0774 mode = mode_padv;
0775 #elif defined(MADV_SEQUENTIAL)
0776 unix_advice = MADV_SEQUENTIAL;
0777 mode = mode_madv;
0778 #endif
0779 break;
0780 case advice_random:
0781 #if defined(POSIX_MADV_RANDOM)
0782 unix_advice = POSIX_MADV_RANDOM;
0783 mode = mode_padv;
0784 #elif defined(MADV_RANDOM)
0785 unix_advice = MADV_RANDOM;
0786 mode = mode_madv;
0787 #endif
0788 break;
0789 case advice_willneed:
0790 #if defined(POSIX_MADV_WILLNEED)
0791 unix_advice = POSIX_MADV_WILLNEED;
0792 mode = mode_padv;
0793 #elif defined(MADV_WILLNEED)
0794 unix_advice = MADV_WILLNEED;
0795 mode = mode_madv;
0796 #endif
0797 break;
0798 case advice_dontneed:
0799 #if defined(POSIX_MADV_DONTNEED)
0800 unix_advice = POSIX_MADV_DONTNEED;
0801 mode = mode_padv;
0802 #elif defined(MADV_DONTNEED) && defined(BOOST_INTERPROCESS_MADV_DONTNEED_HAS_NONDESTRUCTIVE_SEMANTICS)
0803 unix_advice = MADV_DONTNEED;
0804 mode = mode_madv;
0805 #endif
0806 break;
0807 default:
0808 return false;
0809 }
0810 switch(mode){
0811 #if defined(POSIX_MADV_NORMAL)
0812 case mode_padv:
0813 return 0 == posix_madvise(this->priv_map_address(), this->priv_map_size(), unix_advice);
0814 #endif
0815 #if defined(MADV_NORMAL)
0816 case mode_madv:
0817 return 0 == madvise(
0818 #if defined(BOOST_INTERPROCESS_MADVISE_USES_CADDR_T)
0819 (caddr_t)
0820 #endif
0821 this->priv_map_address(), this->priv_map_size(), unix_advice);
0822 #endif
0823 default:
0824 return false;
0825
0826 }
0827 }
0828
0829 inline void mapped_region::priv_close()
0830 {
0831 if(m_base != 0){
0832 #ifdef BOOST_INTERPROCESS_XSI_SHARED_MEMORY_OBJECTS
0833 if(m_is_xsi){
0834 int ret = ::shmdt(m_base);
0835 BOOST_ASSERT(ret == 0);
0836 (void)ret;
0837 return;
0838 }
0839 #endif
0840 munmap(this->priv_map_address(), this->priv_map_size());
0841 m_base = 0;
0842 }
0843 }
0844
0845 inline void mapped_region::dont_close_on_destruction()
0846 { m_base = 0; }
0847
0848 #endif
0849
0850 template<int dummy>
0851 const std::size_t mapped_region::page_size_holder<dummy>::PageSize
0852 = mapped_region::page_size_holder<dummy>::get_page_size();
0853
0854 inline std::size_t mapped_region::get_page_size() BOOST_NOEXCEPT
0855 {
0856 if(!page_size_holder<0>::PageSize)
0857 return page_size_holder<0>::get_page_size();
0858 else
0859 return page_size_holder<0>::PageSize;
0860 }
0861
0862 inline void mapped_region::swap(mapped_region &other) BOOST_NOEXCEPT
0863 {
0864 ::boost::adl_move_swap(this->m_base, other.m_base);
0865 ::boost::adl_move_swap(this->m_size, other.m_size);
0866 ::boost::adl_move_swap(this->m_page_offset, other.m_page_offset);
0867 ::boost::adl_move_swap(this->m_mode, other.m_mode);
0868 #if defined (BOOST_INTERPROCESS_WINDOWS)
0869 ::boost::adl_move_swap(this->m_file_or_mapping_hnd, other.m_file_or_mapping_hnd);
0870 #else
0871 ::boost::adl_move_swap(this->m_is_xsi, other.m_is_xsi);
0872 #endif
0873 }
0874
0875
0876 struct null_mapped_region_function
0877 {
0878 bool operator()(void *, std::size_t , bool) const
0879 { return true; }
0880
0881 static std::size_t get_min_size()
0882 { return 0; }
0883 };
0884
0885 #endif
0886
0887 }
0888 }
0889
0890 #include <boost/interprocess/detail/config_end.hpp>
0891
0892 #endif
0893
0894 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0895
0896 #ifndef BOOST_INTERPROCESS_MAPPED_REGION_EXT_HPP
0897 #define BOOST_INTERPROCESS_MAPPED_REGION_EXT_HPP
0898
0899 #if defined(BOOST_INTERPROCESS_WINDOWS) && !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION)
0900 # include <boost/interprocess/sync/windows/sync_utils.hpp>
0901 # include <boost/interprocess/detail/windows_intermodule_singleton.hpp>
0902
0903 namespace boost {
0904 namespace interprocess {
0905
0906 template<int Dummy>
0907 inline void mapped_region::destroy_syncs_in_range(const void *addr, std::size_t size)
0908 {
0909 ipcdetail::sync_handles &handles =
0910 ipcdetail::windows_intermodule_singleton<ipcdetail::sync_handles>::get();
0911 handles.destroy_syncs_in_range(addr, size);
0912 }
0913
0914 }
0915 }
0916
0917 #endif
0918
0919 #endif
0920
0921 #endif
0922