/Src/Dependencies/Boost/boost/interprocess/detail/managed_memory_impl.hpp

http://hadesmem.googlecode.com/ · C++ Header · 752 lines · 335 code · 95 blank · 322 comment · 17 complexity · 41324236962c21f2be1ad6775974930f MD5 · raw file

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
  4. // Software License, Version 1.0. (See accompanying file
  5. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. //
  7. // See http://www.boost.org/libs/interprocess for documentation.
  8. //
  9. //////////////////////////////////////////////////////////////////////////////
  10. #ifndef BOOST_INTERPROCESS_DETAIL_MANAGED_MEMORY_IMPL_HPP
  11. #define BOOST_INTERPROCESS_DETAIL_MANAGED_MEMORY_IMPL_HPP
  12. #if (defined _MSC_VER) && (_MSC_VER >= 1200)
  13. # pragma once
  14. #endif
  15. #include <boost/interprocess/detail/config_begin.hpp>
  16. #include <boost/interprocess/detail/workaround.hpp>
  17. #include <boost/interprocess/interprocess_fwd.hpp>
  18. #include <boost/interprocess/mem_algo/rbtree_best_fit.hpp>
  19. #include <boost/interprocess/sync/mutex_family.hpp>
  20. #include <boost/interprocess/detail/utilities.hpp>
  21. #include <boost/interprocess/detail/os_file_functions.hpp>
  22. #include <boost/interprocess/creation_tags.hpp>
  23. #include <boost/interprocess/sync/interprocess_mutex.hpp>
  24. #include <boost/interprocess/exceptions.hpp>
  25. #include <boost/interprocess/offset_ptr.hpp>
  26. #include <boost/interprocess/segment_manager.hpp>
  27. #include <boost/interprocess/sync/scoped_lock.hpp>
  28. //
  29. #include <boost/detail/no_exceptions_support.hpp>
  30. //
  31. #include <utility>
  32. #include <fstream>
  33. #include <new>
  34. #include <boost/assert.hpp>
  35. //!\file
  36. //!Describes a named shared memory allocation user class.
  37. //!
  38. namespace boost {
  39. namespace interprocess {
  40. namespace detail {
  41. template<class BasicManagedMemoryImpl>
  42. class create_open_func;
  43. template<
  44. class CharType,
  45. class MemoryAlgorithm,
  46. template<class IndexConfig> class IndexType
  47. >
  48. struct segment_manager_type
  49. {
  50. typedef segment_manager<CharType, MemoryAlgorithm, IndexType> type;
  51. };
  52. //!This class is designed to be a base class to classes that manage
  53. //!creation of objects in a fixed size memory buffer. Apart
  54. //!from allocating raw memory, the user can construct named objects. To
  55. //!achieve this, this class uses the reserved space provided by the allocation
  56. //!algorithm to place a named_allocator_algo, who takes care of name mappings.
  57. //!The class can be customized with the char type used for object names
  58. //!and the memory allocation algorithm to be used.*/
  59. template < class CharType
  60. , class MemoryAlgorithm
  61. , template<class IndexConfig> class IndexType
  62. , std::size_t Offset = 0
  63. >
  64. class basic_managed_memory_impl
  65. {
  66. //Non-copyable
  67. basic_managed_memory_impl(const basic_managed_memory_impl &);
  68. basic_managed_memory_impl &operator=(const basic_managed_memory_impl &);
  69. template<class BasicManagedMemoryImpl>
  70. friend class create_open_func;
  71. public:
  72. typedef typename segment_manager_type
  73. <CharType, MemoryAlgorithm, IndexType>::type segment_manager;
  74. typedef CharType char_type;
  75. typedef MemoryAlgorithm memory_algorithm;
  76. typedef typename MemoryAlgorithm::mutex_family mutex_family;
  77. typedef CharType char_t;
  78. typedef std::ptrdiff_t handle_t;
  79. typedef typename segment_manager::
  80. const_named_iterator const_named_iterator;
  81. typedef typename segment_manager::
  82. const_unique_iterator const_unique_iterator;
  83. /// @cond
  84. typedef typename
  85. segment_manager::char_ptr_holder_t char_ptr_holder_t;
  86. //Experimental. Don't use.
  87. typedef typename segment_manager::multiallocation_chain multiallocation_chain;
  88. /// @endcond
  89. static const std::size_t PayloadPerAllocation = segment_manager::PayloadPerAllocation;
  90. private:
  91. typedef basic_managed_memory_impl
  92. <CharType, MemoryAlgorithm, IndexType, Offset> self_t;
  93. protected:
  94. template<class ManagedMemory>
  95. static bool grow(const char *filename, std::size_t extra_bytes)
  96. {
  97. typedef typename ManagedMemory::device_type device_type;
  98. //Increase file size
  99. try{
  100. offset_t old_size;
  101. {
  102. device_type f(open_or_create, filename, read_write);
  103. if(!f.get_size(old_size))
  104. return false;
  105. f.truncate(old_size + extra_bytes);
  106. }
  107. ManagedMemory managed_memory(open_only, filename);
  108. //Grow always works
  109. managed_memory.self_t::grow(extra_bytes);
  110. }
  111. catch(...){
  112. return false;
  113. }
  114. return true;
  115. }
  116. template<class ManagedMemory>
  117. static bool shrink_to_fit(const char *filename)
  118. {
  119. typedef typename ManagedMemory::device_type device_type;
  120. std::size_t new_size, old_size;
  121. try{
  122. ManagedMemory managed_memory(open_only, filename);
  123. old_size = managed_memory.get_size();
  124. managed_memory.self_t::shrink_to_fit();
  125. new_size = managed_memory.get_size();
  126. }
  127. catch(...){
  128. return false;
  129. }
  130. //Decrease file size
  131. {
  132. device_type f(open_or_create, filename, read_write);
  133. f.truncate(new_size);
  134. }
  135. return true;
  136. }
  137. //!Constructor. Allocates basic resources. Never throws.
  138. basic_managed_memory_impl()
  139. : mp_header(0){}
  140. //!Destructor. Calls close. Never throws.
  141. ~basic_managed_memory_impl()
  142. { this->close_impl(); }
  143. //!Places segment manager in the reserved space. This can throw.
  144. bool create_impl (void *addr, std::size_t size)
  145. {
  146. if(mp_header) return false;
  147. //Check if there is enough space
  148. if(size < segment_manager::get_min_size())
  149. return false;
  150. //This function should not throw. The index construction can
  151. //throw if constructor allocates memory. So we must catch it.
  152. BOOST_TRY{
  153. //Let's construct the allocator in memory
  154. mp_header = new(addr) segment_manager(size);
  155. }
  156. BOOST_CATCH(...){
  157. return false;
  158. }
  159. BOOST_CATCH_END
  160. return true;
  161. }
  162. //!Connects to a segment manager in the reserved buffer. Never throws.
  163. bool open_impl (void *addr, std::size_t)
  164. {
  165. if(mp_header) return false;
  166. mp_header = static_cast<segment_manager*>(addr);
  167. return true;
  168. }
  169. //!Frees resources. Never throws.
  170. bool close_impl()
  171. {
  172. bool ret = mp_header != 0;
  173. mp_header = 0;
  174. return ret;
  175. }
  176. //!Frees resources and destroys common resources. Never throws.
  177. bool destroy_impl()
  178. {
  179. if(mp_header == 0)
  180. return false;
  181. mp_header->~segment_manager();
  182. this->close_impl();
  183. return true;
  184. }
  185. //!
  186. void grow(std::size_t extra_bytes)
  187. { mp_header->grow(extra_bytes); }
  188. void shrink_to_fit()
  189. { mp_header->shrink_to_fit(); }
  190. public:
  191. //!Returns segment manager. Never throws.
  192. segment_manager *get_segment_manager() const
  193. { return mp_header; }
  194. //!Returns the base address of the memory in this process. Never throws.
  195. void * get_address () const
  196. { return reinterpret_cast<char*>(mp_header) - Offset; }
  197. //!Returns the size of memory segment. Never throws.
  198. std::size_t get_size () const
  199. { return mp_header->get_size() + Offset; }
  200. //!Returns the number of free bytes of the memory
  201. //!segment
  202. std::size_t get_free_memory() const
  203. { return mp_header->get_free_memory(); }
  204. //!Returns the result of "all_memory_deallocated()" function
  205. //!of the used memory algorithm
  206. bool all_memory_deallocated()
  207. { return mp_header->all_memory_deallocated(); }
  208. //!Returns the result of "check_sanity()" function
  209. //!of the used memory algorithm
  210. bool check_sanity()
  211. { return mp_header->check_sanity(); }
  212. //!Writes to zero free memory (memory not yet allocated) of
  213. //!the memory algorithm
  214. void zero_free_memory()
  215. { mp_header->zero_free_memory(); }
  216. //!Transforms an absolute address into an offset from base address.
  217. //!The address must belong to the memory segment. Never throws.
  218. handle_t get_handle_from_address (const void *ptr) const
  219. {
  220. return reinterpret_cast<const char*>(ptr) -
  221. reinterpret_cast<const char*>(this->get_address());
  222. }
  223. //!Returns true if the address belongs to the managed memory segment
  224. bool belongs_to_segment (const void *ptr) const
  225. {
  226. return ptr >= this->get_address() &&
  227. ptr < (reinterpret_cast<const char*>(this->get_address()) + this->get_size());
  228. }
  229. //!Transforms previously obtained offset into an absolute address in the
  230. //!process space of the current process. Never throws.*/
  231. void * get_address_from_handle (handle_t offset) const
  232. { return reinterpret_cast<char*>(this->get_address()) + offset; }
  233. //!Searches for nbytes of free memory in the segment, marks the
  234. //!memory as used and return the pointer to the memory. If no
  235. //!memory is available throws a boost::interprocess::bad_alloc exception
  236. void* allocate (std::size_t nbytes)
  237. { return mp_header->allocate(nbytes); }
  238. //!Searches for nbytes of free memory in the segment, marks the
  239. //!memory as used and return the pointer to the memory. If no memory
  240. //!is available returns 0. Never throws.
  241. void* allocate (std::size_t nbytes, std::nothrow_t nothrow)
  242. { return mp_header->allocate(nbytes, nothrow); }
  243. //!Allocates nbytes bytes aligned to "alignment" bytes. "alignment"
  244. //!must be power of two. If no memory
  245. //!is available returns 0. Never throws.
  246. void * allocate_aligned (std::size_t nbytes, std::size_t alignment, std::nothrow_t nothrow)
  247. { return mp_header->allocate_aligned(nbytes, alignment, nothrow); }
  248. template<class T>
  249. std::pair<T *, bool>
  250. allocation_command (boost::interprocess::allocation_type command, std::size_t limit_size,
  251. std::size_t preferred_size,std::size_t &received_size,
  252. T *reuse_ptr = 0)
  253. {
  254. return mp_header->allocation_command
  255. (command, limit_size, preferred_size, received_size, reuse_ptr);
  256. }
  257. //!Allocates nbytes bytes aligned to "alignment" bytes. "alignment"
  258. //!must be power of two. If no
  259. //!memory is available throws a boost::interprocess::bad_alloc exception
  260. void * allocate_aligned(std::size_t nbytes, std::size_t alignment)
  261. { return mp_header->allocate_aligned(nbytes, alignment); }
  262. /// @cond
  263. //Experimental. Don't use.
  264. //!Allocates n_elements of elem_size bytes.
  265. multiallocation_chain allocate_many(std::size_t elem_bytes, std::size_t num_elements)
  266. { return mp_header->allocate_many(elem_bytes, num_elements); }
  267. //!Allocates n_elements, each one of elem_sizes[i] bytes.
  268. multiallocation_chain allocate_many(const std::size_t *elem_sizes, std::size_t n_elements)
  269. { return mp_header->allocate_many(elem_sizes, n_elements); }
  270. //!Allocates n_elements of elem_size bytes.
  271. multiallocation_chain allocate_many(std::size_t elem_bytes, std::size_t num_elements, std::nothrow_t nothrow)
  272. { return mp_header->allocate_many(elem_bytes, num_elements, nothrow); }
  273. //!Allocates n_elements, each one of elem_sizes[i] bytes.
  274. multiallocation_chain allocate_many(const std::size_t *elem_sizes, std::size_t n_elements, std::nothrow_t nothrow)
  275. { return mp_header->allocate_many(elem_sizes, n_elements, nothrow); }
  276. //!Allocates n_elements, each one of elem_sizes[i] bytes.
  277. void deallocate_many(multiallocation_chain chain)
  278. { return mp_header->deallocate_many(boost::interprocess::move(chain)); }
  279. /// @endcond
  280. //!Marks previously allocated memory as free. Never throws.
  281. void deallocate (void *addr)
  282. { if (mp_header) mp_header->deallocate(addr); }
  283. //!Tries to find a previous named allocation address. Returns a memory
  284. //!buffer and the object count. If not found returned pointer is 0.
  285. //!Never throws.
  286. template <class T>
  287. std::pair<T*, std::size_t> find (char_ptr_holder_t name)
  288. { return mp_header->template find<T>(name); }
  289. //!Creates a named object or array in memory
  290. //!
  291. //!Allocates and constructs a T object or an array of T in memory,
  292. //!associates this with the given name and returns a pointer to the
  293. //!created object. If an array is being constructed all objects are
  294. //!created using the same parameters given to this function.
  295. //!
  296. //!-> If the name was previously used, returns 0.
  297. //!
  298. //!-> Throws boost::interprocess::bad_alloc if there is no available memory
  299. //!
  300. //!-> If T's constructor throws, the function throws that exception.
  301. //!
  302. //!Memory is freed automatically if T's constructor throws and if an
  303. //!array was being constructed, destructors of created objects are called
  304. //!before freeing the memory.
  305. template <class T>
  306. typename segment_manager::template construct_proxy<T>::type
  307. construct(char_ptr_holder_t name)
  308. { return mp_header->template construct<T>(name); }
  309. //!Finds or creates a named object or array in memory
  310. //!
  311. //!Tries to find an object with the given name in memory. If
  312. //!found, returns the pointer to this pointer. If the object is not found,
  313. //!allocates and constructs a T object or an array of T in memory,
  314. //!associates this with the given name and returns a pointer to the
  315. //!created object. If an array is being constructed all objects are
  316. //!created using the same parameters given to this function.
  317. //!
  318. //!-> Throws boost::interprocess::bad_alloc if there is no available memory
  319. //!
  320. //!-> If T's constructor throws, the function throws that exception.
  321. //!
  322. //!Memory is freed automatically if T's constructor throws and if an
  323. //!array was being constructed, destructors of created objects are called
  324. //!before freeing the memory.
  325. template <class T>
  326. typename segment_manager::template construct_proxy<T>::type
  327. find_or_construct(char_ptr_holder_t name)
  328. { return mp_header->template find_or_construct<T>(name); }
  329. //!Creates a named object or array in memory
  330. //!
  331. //!Allocates and constructs a T object or an array of T in memory,
  332. //!associates this with the given name and returns a pointer to the
  333. //!created object. If an array is being constructed all objects are
  334. //!created using the same parameters given to this function.
  335. //!
  336. //!-> If the name was previously used, returns 0.
  337. //!
  338. //!-> Returns 0 if there is no available memory
  339. //!
  340. //!-> If T's constructor throws, the function throws that exception.
  341. //!
  342. //!Memory is freed automatically if T's constructor throws and if an
  343. //!array was being constructed, destructors of created objects are called
  344. //!before freeing the memory.
  345. template <class T>
  346. typename segment_manager::template construct_proxy<T>::type
  347. construct(char_ptr_holder_t name, std::nothrow_t nothrow)
  348. { return mp_header->template construct<T>(name, nothrow); }
  349. //!Finds or creates a named object or array in memory
  350. //!
  351. //!Tries to find an object with the given name in memory. If
  352. //!found, returns the pointer to this pointer. If the object is not found,
  353. //!allocates and constructs a T object or an array of T in memory,
  354. //!associates this with the given name and returns a pointer to the
  355. //!created object. If an array is being constructed all objects are
  356. //!created using the same parameters given to this function.
  357. //!
  358. //!-> Returns 0 if there is no available memory
  359. //!
  360. //!-> If T's constructor throws, the function throws that exception.
  361. //!
  362. //!Memory is freed automatically if T's constructor throws and if an
  363. //!array was being constructed, destructors of created objects are called
  364. //!before freeing the memory.
  365. template <class T>
  366. typename segment_manager::template construct_proxy<T>::type
  367. find_or_construct(char_ptr_holder_t name, std::nothrow_t nothrow)
  368. { return mp_header->template find_or_construct<T>(name, nothrow); }
  369. //!Creates a named array from iterators in memory
  370. //!
  371. //!Allocates and constructs an array of T in memory,
  372. //!associates this with the given name and returns a pointer to the
  373. //!created object. Each element in the array is created using the
  374. //!objects returned when dereferencing iterators as parameters
  375. //!and incrementing all iterators for each element.
  376. //!
  377. //!-> If the name was previously used, returns 0.
  378. //!
  379. //!-> Throws boost::interprocess::bad_alloc if there is no available memory
  380. //!
  381. //!-> If T's constructor throws, the function throws that exception.
  382. //!
  383. //!Memory is freed automatically if T's constructor throws and
  384. //!destructors of created objects are called before freeing the memory.
  385. template <class T>
  386. typename segment_manager::template construct_iter_proxy<T>::type
  387. construct_it(char_ptr_holder_t name)
  388. { return mp_header->template construct_it<T>(name); }
  389. //!Finds or creates a named array from iterators in memory
  390. //!
  391. //!Tries to find an object with the given name in memory. If
  392. //!found, returns the pointer to this pointer. If the object is not found,
  393. //!allocates and constructs an array of T in memory,
  394. //!associates this with the given name and returns a pointer to the
  395. //!created object. Each element in the array is created using the
  396. //!objects returned when dereferencing iterators as parameters
  397. //!and incrementing all iterators for each element.
  398. //!
  399. //!-> If the name was previously used, returns 0.
  400. //!
  401. //!-> Throws boost::interprocess::bad_alloc if there is no available memory
  402. //!
  403. //!-> If T's constructor throws, the function throws that exception.
  404. //!
  405. //!Memory is freed automatically if T's constructor throws and
  406. //!destructors of created objects are called before freeing the memory.
  407. template <class T>
  408. typename segment_manager::template construct_iter_proxy<T>::type
  409. find_or_construct_it(char_ptr_holder_t name)
  410. { return mp_header->template find_or_construct_it<T>(name); }
  411. //!Creates a named array from iterators in memory
  412. //!
  413. //!Allocates and constructs an array of T in memory,
  414. //!associates this with the given name and returns a pointer to the
  415. //!created object. Each element in the array is created using the
  416. //!objects returned when dereferencing iterators as parameters
  417. //!and incrementing all iterators for each element.
  418. //!
  419. //!-> If the name was previously used, returns 0.
  420. //!
  421. //!-> If there is no available memory, returns 0.
  422. //!
  423. //!-> If T's constructor throws, the function throws that exception.
  424. //!
  425. //!Memory is freed automatically if T's constructor throws and
  426. //!destructors of created objects are called before freeing the memory.*/
  427. template <class T>
  428. typename segment_manager::template construct_iter_proxy<T>::type
  429. construct_it(char_ptr_holder_t name, std::nothrow_t nothrow)
  430. { return mp_header->template construct_it<T>(name, nothrow); }
  431. //!Finds or creates a named array from iterators in memory
  432. //!
  433. //!Tries to find an object with the given name in memory. If
  434. //!found, returns the pointer to this pointer. If the object is not found,
  435. //!allocates and constructs an array of T in memory,
  436. //!associates this with the given name and returns a pointer to the
  437. //!created object. Each element in the array is created using the
  438. //!objects returned when dereferencing iterators as parameters
  439. //!and incrementing all iterators for each element.
  440. //!
  441. //!-> If the name was previously used, returns 0.
  442. //!
  443. //!-> If there is no available memory, returns 0.
  444. //!
  445. //!-> If T's constructor throws, the function throws that exception.
  446. //!
  447. //!Memory is freed automatically if T's constructor throws and
  448. //!destructors of created objects are called before freeing the memory.*/
  449. template <class T>
  450. typename segment_manager::template construct_iter_proxy<T>::type
  451. find_or_construct_it(char_ptr_holder_t name, std::nothrow_t nothrow)
  452. { return mp_header->template find_or_construct_it<T>(name, nothrow); }
  453. //!Calls a functor and guarantees that no new construction, search or
  454. //!destruction will be executed by any process while executing the object
  455. //!function call. If the functor throws, this function throws.
  456. template <class Func>
  457. void atomic_func(Func &f)
  458. { mp_header->atomic_func(f); }
  459. //!Tries to call a functor guaranteeing that no new construction, search or
  460. //!destruction will be executed by any process while executing the object
  461. //!function call. If the atomic function can't be immediatelly executed
  462. //!because the internal mutex is already locked, returns false.
  463. //!If the functor throws, this function throws.
  464. template <class Func>
  465. bool try_atomic_func(Func &f)
  466. { return mp_header->try_atomic_func(f); }
  467. //!Destroys a named memory object or array.
  468. //!
  469. //!Finds the object with the given name, calls its destructors,
  470. //!frees used memory and returns true.
  471. //!
  472. //!-> If the object is not found, it returns false.
  473. //!
  474. //!Exception Handling:
  475. //!
  476. //!When deleting a dynamically object or array, the Standard
  477. //!does not guarantee that dynamically allocated memory, will be released.
  478. //!Also, when deleting arrays, the Standard doesn't require calling
  479. //!destructors for the rest of the objects if for one of them the destructor
  480. //!terminated with an exception.
  481. //!
  482. //!Destroying an object:
  483. //!
  484. //!If the destructor throws, the memory will be freed and that exception
  485. //!will be thrown.
  486. //!
  487. //!Destroying an array:
  488. //!
  489. //!When destroying an array, if a destructor throws, the rest of
  490. //!destructors are called. If any of these throws, the exceptions are
  491. //!ignored. The name association will be erased, memory will be freed and
  492. //!the first exception will be thrown. This guarantees the unlocking of
  493. //!mutexes and other resources.
  494. //!
  495. //!For all theses reasons, classes with throwing destructors are not
  496. //!recommended.
  497. template <class T>
  498. bool destroy(const CharType *name)
  499. { return mp_header->template destroy<T>(name); }
  500. //!Destroys the unique instance of type T
  501. //!
  502. //!Calls the destructor, frees used memory and returns true.
  503. //!
  504. //!Exception Handling:
  505. //!
  506. //!When deleting a dynamically object, the Standard does not
  507. //!guarantee that dynamically allocated memory will be released.
  508. //!
  509. //!Destroying an object:
  510. //!
  511. //!If the destructor throws, the memory will be freed and that exception
  512. //!will be thrown.
  513. //!
  514. //!For all theses reasons, classes with throwing destructors are not
  515. //!recommended for memory.
  516. template <class T>
  517. bool destroy(const detail::unique_instance_t *const )
  518. { return mp_header->template destroy<T>(unique_instance); }
  519. //!Destroys the object (named, unique, or anonymous)
  520. //!
  521. //!Calls the destructor, frees used memory and returns true.
  522. //!
  523. //!Exception Handling:
  524. //!
  525. //!When deleting a dynamically object, the Standard does not
  526. //!guarantee that dynamically allocated memory will be released.
  527. //!
  528. //!Destroying an object:
  529. //!
  530. //!If the destructor throws, the memory will be freed and that exception
  531. //!will be thrown.
  532. //!
  533. //!For all theses reasons, classes with throwing destructors are not
  534. //!recommended for memory.
  535. template <class T>
  536. void destroy_ptr(const T *ptr)
  537. { mp_header->template destroy_ptr<T>(ptr); }
  538. //!Returns the name of an object created with construct/find_or_construct
  539. //!functions. Does not throw
  540. template<class T>
  541. static const char_type *get_instance_name(const T *ptr)
  542. { return segment_manager::get_instance_name(ptr); }
  543. //!Returns is the type an object created with construct/find_or_construct
  544. //!functions. Does not throw.
  545. template<class T>
  546. static instance_type get_instance_type(const T *ptr)
  547. { return segment_manager::get_instance_type(ptr); }
  548. //!Returns the length of an object created with construct/find_or_construct
  549. //!functions (1 if is a single element, >=1 if it's an array). Does not throw.
  550. template<class T>
  551. static std::size_t get_instance_length(const T *ptr)
  552. { return segment_manager::get_instance_length(ptr); }
  553. //!Preallocates needed index resources to optimize the
  554. //!creation of "num" named objects in the memory segment.
  555. //!Can throw boost::interprocess::bad_alloc if there is no enough memory.
  556. void reserve_named_objects(std::size_t num)
  557. { mp_header->reserve_named_objects(num); }
  558. //!Preallocates needed index resources to optimize the
  559. //!creation of "num" unique objects in the memory segment.
  560. //!Can throw boost::interprocess::bad_alloc if there is no enough memory.
  561. void reserve_unique_objects(std::size_t num)
  562. { mp_header->reserve_unique_objects(num); }
  563. //!Calls shrink_to_fit in both named and unique object indexes
  564. //to try to free unused memory from those indexes.
  565. void shrink_to_fit_indexes()
  566. { mp_header->shrink_to_fit_indexes(); }
  567. //!Returns the number of named objects stored
  568. //!in the managed segment.
  569. std::size_t get_num_named_objects()
  570. { return mp_header->get_num_named_objects(); }
  571. //!Returns the number of unique objects stored
  572. //!in the managed segment.
  573. std::size_t get_num_unique_objects()
  574. { return mp_header->get_num_unique_objects(); }
  575. //!Returns a constant iterator to the index storing the
  576. //!named allocations. NOT thread-safe. Never throws.
  577. const_named_iterator named_begin() const
  578. { return mp_header->named_begin(); }
  579. //!Returns a constant iterator to the end of the index
  580. //!storing the named allocations. NOT thread-safe. Never throws.
  581. const_named_iterator named_end() const
  582. { return mp_header->named_end(); }
  583. //!Returns a constant iterator to the index storing the
  584. //!unique allocations. NOT thread-safe. Never throws.
  585. const_unique_iterator unique_begin() const
  586. { return mp_header->unique_begin(); }
  587. //!Returns a constant iterator to the end of the index
  588. //!storing the unique allocations. NOT thread-safe. Never throws.
  589. const_unique_iterator unique_end() const
  590. { return mp_header->unique_end(); }
  591. //!This is the default allocator to allocate types T
  592. //!from this managed segment
  593. template<class T>
  594. struct allocator
  595. {
  596. typedef typename segment_manager::template allocator<T>::type type;
  597. };
  598. //!Returns an instance of the default allocator for type T
  599. //!initialized that allocates memory from this segment manager.
  600. template<class T>
  601. typename allocator<T>::type
  602. get_allocator()
  603. { return mp_header->template get_allocator<T>(); }
  604. //!This is the default deleter to delete types T
  605. //!from this managed segment.
  606. template<class T>
  607. struct deleter
  608. {
  609. typedef typename segment_manager::template deleter<T>::type type;
  610. };
  611. //!Returns an instance of the default allocator for type T
  612. //!initialized that allocates memory from this segment manager.
  613. template<class T>
  614. typename deleter<T>::type
  615. get_deleter()
  616. { return mp_header->template get_deleter<T>(); }
  617. /// @cond
  618. //!Tries to find a previous named allocation address. Returns a memory
  619. //!buffer and the object count. If not found returned pointer is 0.
  620. //!Never throws.
  621. template <class T>
  622. std::pair<T*, std::size_t> find_no_lock (char_ptr_holder_t name)
  623. { return mp_header->template find_no_lock<T>(name); }
  624. /// @endcond
  625. protected:
  626. //!Swaps the segment manager's managed by this managed memory segment.
  627. //!NOT thread-safe. Never throws.
  628. void swap(basic_managed_memory_impl &other)
  629. { std::swap(mp_header, other.mp_header); }
  630. private:
  631. segment_manager *mp_header;
  632. };
  633. template<class BasicManagedMemoryImpl>
  634. class create_open_func
  635. {
  636. public:
  637. create_open_func(BasicManagedMemoryImpl * const frontend, detail::create_enum_t type)
  638. : m_frontend(frontend), m_type(type){}
  639. bool operator()(void *addr, std::size_t size, bool created) const
  640. {
  641. if(((m_type == detail::DoOpen) && created) ||
  642. ((m_type == detail::DoCreate) && !created))
  643. return false;
  644. if(created)
  645. return m_frontend->create_impl(addr, size);
  646. else
  647. return m_frontend->open_impl (addr, size);
  648. }
  649. private:
  650. BasicManagedMemoryImpl *m_frontend;
  651. detail::create_enum_t m_type;
  652. };
  653. } //namespace detail {
  654. } //namespace interprocess {
  655. } //namespace boost {
  656. #include <boost/interprocess/detail/config_end.hpp>
  657. #endif //BOOST_INTERPROCESS_DETAIL_MANAGED_MEMORY_IMPL_HPP