Boost logo

Boost :

From: Mithun R K (mithun.radhakrishnan_at_[hidden])
Date: 2005-01-13 10:58:05


Hello, Jason/All.

A couple of clarifications on my questions.

<quote>
I suspect that the one definition rule would require the linker to see that
the names are identical. Then the linker could verify that the definitions
are identical or assume that they are identical and ignore one. However I
could be completely wrong about this, so if I am someone please correct me.
</quote>

This is perfectly true when object-files (with multiple
template-instantiations) are being linked by the link-editor, when producing
the executable/lib. However, my question had more to do with separate
instantiations of Singleton<MyClass> in different shared libraries. Since
each lib has a separate Singleton<MyClass> definition, won't each lib also
have its own singleton-instance? I'm pretty sure the loader won't be
stripping out multiple instantiations across shared libraries (well, not on
HPUX, anyway). Won't this pose a problem?

<quote>
Perhaps the lifetime of the dlls themselves could be managed with
singletons? When the dll's dtor is called, it could unregister the relevant
classes and unload the dll.
</quote>

The loading/unloading of the dll's isn't really in our control, is it? It's
the dynamic-library-loader of the OS that does it. (/usr/lib/libdld.so, on
HPUX). This problem is bound to happen on any app with multiple dlls, right?
I've to use a hack on HPUX fix this... I'm open to ideas.

<quote>
By making this non-template base mandatory, I would think that making
destructors virtual would become mandatory, and introduce much overhead.
The method I plan to use will keep pointers to static Create and Destroy
methods (which the templated LongevityLifetime will introduce).
</quote>

Thank you for looking at my approach... I really appreciate it.

Ok, so I shouldn't be introducing a virtual-base for the singletons... If I
were to register only Destroy functors with the SingletonRegistry (each
knowing how to destroy its Singleton), would that do? That would move the
virtual-base out of the Singleton, and into the "SingletonDestroyer" (I'll
still need a virtual base, because the SingletonRegistry will need to hold
all the Destroyer functors).

Will that be any better?

With best regards,
Mithun

-----Original Message-----
From: boost-bounces_at_[hidden] [mailto:boost-bounces_at_[hidden]]
On Behalf Of Jason Hise
Sent: Wednesday, January 12, 2005 3:37 AM
To: boost_at_[hidden]
Subject: Re: [boost] Singleton

Mithun R K wrote:

>Hello, Jason/all.
>
>I find the discussion around the new/improved Singleton template very
>exciting.
>
>Perhaps a month ago, I'd written a Singleton class template in a manner
>similar to Jason's initial approach (though not *nearly* as
>cool/customizable). I.e.
>
>template < typename T, int Longevity = static_cast<int>( T::Longevity )
>> struct Singleton : public SingletonBase, public T {...};
>
>My approach was:
>
>1. Have a single SingletonRegistry that would keep pointers to all
>Singleton instances (well, actually, SingletonBase instances.
>SingletonBase is not a
>class-template.)
>2. Each instance has a longevity-int associated with it. At
>destruction-time, we sort the singleton-instances based on their
>relative longevities, and destroy the objects in order.
>It's kinda up to the "client" of Singleton<T> to figure out the
>collaboration between her classes, and assign longevity-values to her
>classes.
>3. Singleton<T> instances are "registered" with the SingletonRegistry,
>by its constructor.
>4. Singleton<T>::~Singleton() lets the registry know that the instance
>may be destroyed. The SingletonRegistry destroys the instance if all
>singletons with a lesser longevity have already been marked for
>destruction. (I guess that's simple mark-and-sweep.)
>
>I'd be honoured and grateful if anyone has comments on this approach.
>
This is interesting. The main problem that your code introduces is in the
SingletonRegistry, by keeping pointers to the non-template base. By making
this non-template base mandatory, I would think that making destructors
virtual would become mandatory, and introduce much overhead. The method I
plan to use will keep pointers to static Create and Destroy methods (which
the templated LongevityLifetime will introduce). This way the
SingletonRegistry can maintain a stack of nodes that have pointers to the
create and destroy methods, without needing to actually have access to the
singleton instance itself.

>I have a couple of (naïve?) questions regarding the new approach.
>Please bear with me:
>
>1. Why was the old approach abandoned in favour of CRTP? The reason I
>went with the above was that I wanted Singleton<T>& to be able to
>replace T&. I wanted the Singleton template to fit around an existing
>class definition, as inobtrusively as possible. Would somebody kindly
clarify?
>
>
The two problems mentioned with my previously used approach (anyone correct
me if I missed one) was that it introduced virtual functions, and that
typing out Singleton < Important > was harder than just writing out
Important. In my old model it would have made it illegal to create an
instance of Important, and thus a singleton around that type wouldn't really
be an unobtrusive wrapper, in that it would disable any code already using
the class as a non singleton. The new method simply cuts out some
unnecessary syntax.

>2. At least in Jason's first version, the Singleton class-template had
>a static Singleton<T> instance. Wouldn't that cause the instance to
>*always* be instantiated at load-time?
>
Au contraire! In fact, the original version had a static *pointer* to the
singleton. What was causing the singleton to always be instantiated before
main was the static dependency, which I quickly eliminated upon discovering
that this behavior is not always desirable.

>3. Say an application uses multiple shared libs. Say Singleton<MyClass>
>is used in more than one library. The definition of the static
>singleton-instance is in the template header (assuming that we're not
>using template exports, and all this stuff is inline). There's a good
>chance that the definition of Singleton<MyClass> might be generated
>multiply in different libraries of the same app. Won't that mean that
>there will be more than 1 instance of Singleton<MyClass>? I'm not sure
>how to get around this right now. Ideas?
>
>
I suspect that the one definition rule would require the linker to see that
the names are identical. Then the linker could verify that the definitions
are identical or assume that they are identical and ignore one. However I
could be completely wrong about this, so if I am someone please correct me.

>4. Will there be issues with dependencies across shared libraries? Say
>Singleton<MyClass> depends on Singleton<Logger> because
>MyClass::~MyClass() needs to log stuff. If these are in separate
>libraries, won't the order in which the libraries are unloaded pose a
problem?
>
Perhaps the lifetime of the dlls themselves could be managed with
singletons? When the dll's dtor is called, it could unregister the relevant
classes and unload the dll.

-Jason

_______________________________________________
Unsubscribe & other changes:
http://lists.boost.org/mailman/listinfo.cgi/boost


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk