Followup for PR #1744

The commit 6c77740485 was not complete:
> CORE MemoryPool<T> has to be destroyed last
>
> If Boost implementation of thread local storage is used, the order of
> destructors is reversed, compared to C++11 `static thread_local`. The
> solution for CORE `MemoryPool<T>` is to make the static variable a
> static member of the class, and initialize the pointer only inside the
> function. That ensures that the destructor will be called after the
> destructor of local static variables.

Actually the explanation about the reverse order is not right, and even
with C++ `thread_local`, we have to ensure that the static data member
of `MemoryPool<T>` is created before any other CORE static variable.

This commit is a followup of the commit
6c7774048521d2779d1657871f476624a46d220b: even in C++11, the `memPool`
variable becomes a thread-local data member, instead of a thread-local
variable at function scope.

Fix #1844.
This commit is contained in:
Laurent Rineau 2017-02-07 14:18:32 +01:00
parent 760076510c
commit 4e1b250b9c
1 changed files with 12 additions and 4 deletions

View File

@ -84,8 +84,6 @@ public:
#if CGAL_STATIC_THREAD_LOCAL_USE_BOOST
if(memPool_ptr.get() == NULL) {memPool_ptr.reset(new Self());}
Self& memPool = * memPool_ptr.get();
#else // CGAL_STATIC_THREAD_LOCAL uses C++11 thread_local
CGAL_STATIC_THREAD_LOCAL_VARIABLE_0(Self, memPool);
#endif
return memPool;
}
@ -96,14 +94,24 @@ private:
#if CGAL_STATIC_THREAD_LOCAL_USE_BOOST
static boost::thread_specific_ptr<Self> memPool_ptr;
#endif
#elif defined(CGAL_HAS_THREADS) // use the C++11 implementation
static thread_local Self memPool;
#else // not CGAL_HAS_THREADS
static Self memPool;
#endif // not CGAL_HAS_THREADS
};
#if CGAL_STATIC_THREAD_LOCAL_USE_BOOST
template <class T, int nObjects >
boost::thread_specific_ptr<MemoryPool<T, nObjects> >
MemoryPool<T, nObjects>::memPool_ptr;
#endif // CGAL_STATIC_THREAD_LOCAL_USE_BOOST
#else // use C++11 or without CGAL_HAS_THREADS
template <class T, int nObjects >
# ifdef CGAL_HAS_THREADS
thread_local
# endif
MemoryPool<T, nObjects> MemoryPool<T, nObjects>::memPool;
#endif
template< class T, int nObjects >
void* MemoryPool< T, nObjects >::allocate(std::size_t) {