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