annotate DEPENDENCIES/generic/include/boost/interprocess/detail/managed_memory_impl.hpp @ 125:34e428693f5d vext

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