From: Tobias Schwinger (tschwinger_at_[hidden])
Date: 2008-01-16 03:15:55


Pierre-Jules,

thank you for your review.

Pierre-Jules Tremblay wrote:
> On Jan 14, 2008 12:10 PM, John Torjo <john.groups_at_[hidden]> wrote:
>
>> * What is your evaluation of the design?
>>
>
> Not generic enough. It addresses a number of specific problems (e.g. use in
> MT contexts, order-of-initialisation fiasco, etc) but the author's design
> choices are neither customizable nor overridable.

> For instance, the design
> could be made more flexible by allowing thread-safety to be specified as a
> policy (with appropriate default) or by delegating the responsibility to the
> wrapped type.

OK, FWIW policies complicate things. And what's their benefit here?

> If BOOST_HAS_THREADS is defined, it looks as though I have no
> choice but to use mutexed instantiation and/or access. If I'm not
> interested in synchronised access, then the lease interface is useless.

Wrong:

The lease interface is useful to improves performance. The test whether
the Singleton has been initialized (which requires synchronization) can
be performed only once.

>
> The solution to the OOI problem does not scale, and I would go as far as
> saying that it doesn't work in practice. In my experience, it's a constant
> maintenance nightmare to try and keep the various slot assignments in the
> correct order (I have to deal with a large number of singletons; yes that is
> a problem in and of itself - this library will do nothing to discourage
> it).

You must have misunderstood the docs. OOI is not done with slots. The
slots are to prevent unnecessary resurrection during destruction.

> The only scheme I've personally had any success with, so far, involves
> some form of reference counting, i.e. singletons that depend on other
> singletons do so explicitly (by incrementing the other's refcount on
> construction; the singletons are destroyed when their refcount goes to
> zero).

You might have gotten away with it in practice, but introducing this
kind of coupling seems really bad design to me.

>
> Another reason why the proposed OOI solution fails in practice is that other
> singletons are not a singleton's only dependency: client code ( e.g. objects
> that reference the singleton) are dependencies as well and may affect the
> order of destruction.

What is the "proposed OOI solution" you are talking about?

> You just can't assume the singleton manager will be
> the last thing to go - there may be other globals.

It's the "we should remove pointers from C++ because one can dereference
NULL" kind-of argumentation.

> BTW I find the very idea
> of being able to "force" singleton destruction quite scary, but I haven't
> looked at the implementation details.

It's necessary, as long as C++ runs on top of ABIs that don't support
code to be run automatically when a dynamic library is unloaded and I
can assure you that running code in an unloaded, dynamic library is a
lot scarier :-).

> The following sentence is also cause
> for concern: " Attempts to access an already destroyed Singleton instance
> cause the instance to be re-created." Is that true only for DLL usage?

It's true in general.

> My biggest problem with this design is that it is unsuitable for library
> writers: types derived from typical singleton class designs, including
> boost::singleton and friends under review, invariably give rise to
> untestable code. To make a singleton's client code testable involves
> exposing some kind of overridable factory so that the singletonized type can
> be replaced with a test mockup. So far I have found this to be a hard
> problem to solve in general.

Interesting point.

>
> Finally, this may constitute a minority opinion but I like to consider
> global access and single instance as orthogonal concepts. One may want to
> ensure a resource is only instantiated once without necessarily providing
> global access to that resource.

So Singletons should be dynamic arrays in your opinion?

Regards,
Tobias