Boost logo

Boost Users :

Subject: Re: [Boost-users] serialization1.36.0 extended_type_info exit issue(s)
From: troy d. straszheim (troy_at_[hidden])
Date: 2008-10-08 20:17:46


Robert Ramey wrote:
>
> So trap on this line and verify that
> singleton<detail::ktmap>::is_destroyed() is not true
>
> then trap on the destructor of singleton<detail::ktmap>::is_destroyed() to
> verify that
>
> m_is_destroyed is in fact getting set when the table is destroyed.

The detail::ktmap is getting destroyed *before* the singleton
that holds it. So is_destroyed() returns false... but that's wrong.
Does the standard guarantee that the static T that is inside
singleton<T>::get_instance() will be destroyed *after* the singleton<T>
itself? It seems like the compiler could figure out that the singleton<T>
never actually talks to the static T inside get_instance(), ie. it looks
like it would be pretty easy to figure out that use() doesn't do anything
and get rid of it entirely.

I put together a fix which works... not sure what I think of it.
Singletons inherit from a singleton_instance class that notifies the singleton (!)
of its destruction. Looks like this:

in extended_type_info.cpp, detail::ktmap is no longer a typedef:

   struct ktmap : std::multiset<const extended_type_info*, key_compare>,
                 singleton_instance<ktmap>
   { };

and in singleton.hpp, you've got this:

template <class T>
class singleton_instance;

template <class T>
class singleton : public singleton_module
{
     static bool m_is_destroyed;
     BOOST_DLLEXPORT static T & instance;
     // include this to provoke instantiation at pre-execution time
     static void use(T const &) {}

     BOOST_DLLEXPORT static T & get_instance() {
       static T t;
         // refer to instance, causing it to be instantiated (and
         // initialized at startup on working compilers)
         assert(! m_is_destroyed);
         use(instance);
         return t;
     }

     BOOST_DLLEXPORT static void destroy() { m_is_destroyed = true; }

public:
     BOOST_DLLEXPORT static T & get_mutable_instance(){
         assert(! is_locked());
         return get_instance();
     }
     BOOST_DLLEXPORT static const T & get_const_instance(){
         return get_instance();
     }
     BOOST_DLLEXPORT static bool is_destroyed(){
       return m_is_destroyed;
     }
     ~singleton(){
       m_is_destroyed = true;
     }
   friend class singleton_instance<T>;
};

template<class T>
BOOST_DLLEXPORT T & singleton<T>::instance = singleton<T>::get_instance();

template<class T> bool singleton<T>::m_is_destroyed = false;

template <class T>
class singleton_instance
{
public:
   ~singleton_instance() { singleton<T>::destroy(); }
};

What do you make of all this?

-t


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net