[Boost-bugs] [Boost C++ Libraries] #12494: Cannot expand vector in place using interprocess::allocator and interprocess::rbtree_best_fit

Subject: [Boost-bugs] [Boost C++ Libraries] #12494: Cannot expand vector in place using interprocess::allocator and interprocess::rbtree_best_fit
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2016-09-30 16:22:34


#12494: Cannot expand vector in place using interprocess::allocator and
interprocess::rbtree_best_fit
------------------------------+--------------------------
 Reporter: camden.mannett@… | Owner: igaztanaga
     Type: Bugs | Status: new
Milestone: To Be Determined | Component: interprocess
  Version: Boost 1.60.0 | Severity: Problem
 Keywords: |
------------------------------+--------------------------
 When using reserve() on a {{{interprocess::vector}}} (synomyn for
 {{{container::vector}}}) inside a
 {{{interprocess::basic_managed_mapped_file}}} (using the default
 {{{interprocess::rbtree_best_fit}}} memory algorithm), it cannot in place
 expand forward.

 I noticed this when getting help on
 [https://stackoverflow.com/questions/39780787/boostmanaged-mapped-file-
 cannot-allocate-all-of-grown-space this] SO question. Using the code in
 that question, put a breakpoint at
 \boost\interprocess\mem_algo\rbtree_best_fit.hpp:964, and then trace the
 call stack back to {{{vector::priv_reserve_no_capacity(size_type new_cap,
 version_2)}}}:

 {{{
 pointer reuse = 0;
 pointer const ret(this->m_holder.allocation_command(allocate_new |
 expand_fwd | expand_bwd, new_cap, real_cap = new_cap, reuse));
 }}}

 The {{{reuse}}} pointer is set to null, resumably so it can be overridden
 by the allocator. The pointer is passed up the stack to
 {{{interprocess::allocator::allocation_command(boost::interprocess::allocation_type
 command, size_type limit_size, size_type &prefer_in_recvd_out_size,
 pointer &reuse)}}} where the raw pointer is retrieved:

 {{{
 value_type *reuse_raw = ipcdetail::to_raw_pointer(reuse);
 pointer const p = mp_mngr->allocation_command(command, limit_size,
 prefer_in_recvd_out_size, reuse_raw);
 }}}

 {{{reuse_raw}}} continues to be passed up the stack to where our
 breakpoint is:

 {{{
 //Expand in place
 prefer_in_recvd_out_size = preferred_size;
 if(reuse_ptr && (command & (boost::interprocess::expand_fwd |
 boost::interprocess::expand_bwd))){
   void *ret = priv_expand_both_sides
      (command, limit_size, prefer_in_recvd_out_size, reuse_ptr, true,
 backwards_multiple);
   if(ret)
      return ret;
 }
 }}}

 {{{reuse_ptr}}} is our raw pointer and is as null as it was when created,
 causing the expand in place block to be skipped. In short there appears
 to be no way for a vector to be in place expanded when used inside a
 memory mapped file.

-- 
Ticket URL: <https://svn.boost.org/trac/boost/ticket/12494>
Boost C++ Libraries <http://www.boost.org/>
Boost provides free peer-reviewed portable C++ source libraries.

This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:20 UTC