[Boost-bugs] [Boost C++ Libraries] #2359: Static initialization problems with fast_pool_allocator

Subject: [Boost-bugs] [Boost C++ Libraries] #2359: Static initialization problems with fast_pool_allocator
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2008-09-22 20:55:31


#2359: Static initialization problems with fast_pool_allocator
--------------------------+-------------------------------------------------
 Reporter: cnewbold | Owner: cnewbold
     Type: Bugs | Status: new
Milestone: Boost 1.37.0 | Component: pool
  Version: Boost 1.36.0 | Severity: Problem
 Keywords: |
--------------------------+-------------------------------------------------
 == Detailed analysis from Joaquín M López Muñoz: ==

 Hello, I did look hard into pool/detail/singleton.hpp in the past because
 it deals with a problem that I also had to face in the implementation of
 Boost.Flyweight. These are my conclusions wrt to pool/detail/singleton.hpp
 and with respect to the particular problem you're now studying:



 * pool/detail/singleton.hpp claims that singleton_default<T>::instance()
 is automatically called before main() if no user code does it explicitly.
 Strictly speaking, the implementation does not guarantee this, but only
 that singleton_default<T>::instance() will be called during the so-called
 dynamic initialization phase of the program startup sequence. For all
 practical purposes, however, this is equivalent to the orignal claim, so
 the problem does not lie here.



 * Where the problem lies can be found by looking at the usage of
 singleton_pool by fast_pool_allocator: notice that singleton_pool is used
 *only* when fast_pool_allocator::allocate or ::deallocate are invoked. So,
 it is perfectly possible to construct a fast_pool_allocator without that
 forcing the compiler to construct the underying singleton_pool *yet*. And
 this is what's happening indeed, the sequence of objects construction
 we're having is this:



   1. owned_base::pool_ begins construction

   1.1 call of new pool_lii() inside pool::pool

   1.1.1 a fast_pool_allocator is cted inside pool_lii ctor.

   1.2 pool_ii ends construction

   2. pool_ ends construction

   3. the singleton instance associated to singleton_pool<...>is

   cted before main() because fast_pool_allocator uses it later

   (singleton guarantee).



 This sequence is consistent with the guarantees provided by
 singleton_default<T>. The problem lies in the design of

 fast_pool_allocator: as it stands, the construction of a
 fast_pool_allocator does *not* force the prior construction of the
 internal singleton instance, and this is a mistake.

 If my analysis is correct, to fix the problem one need only ensure that
 his construction order is preserved for instance by explicitly using
 singleton_pool<...> inside fast_pool_allocator ctors like this:



 {{{
     fast_pool_allocator()

     {

       singleton_pool<fast_pool_allocator_tag, sizeof(T),

         UserAllocator, Mutex, NextSize>::is_from(0);

     }



     template <typename U>

     fast_pool_allocator(

         const fast_pool_allocator<U, UserAllocator, Mutex, NextSize> &)

     {

       singleton_pool<fast_pool_allocator_tag, sizeof(T),

         UserAllocator, Mutex, NextSize>::is_from(0);

     }

 }}}

-- 
Ticket URL: <http://svn.boost.org/trac/boost/ticket/2359>
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:49:58 UTC