Joshua Maurice wrote:
On Jun 30, 11:46 am, mattb <matthew.b...@l-3com.com> wrote:
I have come across a singleton implementation of the following form in
some code I have to maintain...
[Out of order quote]
Is this safe?
Not in the slightest.
Are you really sure about slightest ? (see below)
file - Singleton.h
#ifndef SINGLETON_H
#define SINGLETON_H
You may want a more unique name for the macro, something involving
your company name for example. I'd imagine SINGLETON_H would be a
common name.
Also, "xxx.hpp" is the way of C++, not "xxx.h". Just a stylistic
nitpick.
It's perhaps often used for header files with only templates inside. But
is that an official recommendation of the C++ standard ? I don't think so.
See "C++ and the Perils of Double Checked Locking"
http://www.aristeia.com/Papers/DDJ_Jul_Aug_2004_revised.pdf
for a thorough description of why the above does not work and has
never worked.
It depends perhaps (?) on the CPU / OS, but I think the synchronization
primitives should work equally on each CPU, since safe multi threaded
code couldn't be written safely without memory fences.
But to play it safe [for me ;-)] I refer to Windows with a x86 / x64 CPU.
The relevant code, which IMHO makes the code safe (beside perhaps one
detail) is:
AccessLock<CriticalSection> access(key_);
if ( !instance_ )
{
static Singleton<T> theInstance;
instance_ = &theInstance;
}
Let me rewrite the code, how I interpret it to work (internally):
a) CriticalSection.EnterCriticalSection();
b) if (!instance) {...}
c) CriticalSection.LeaveCriticalSection();
At point a) c) memory barrier instructions are executed, which ensure
that no reordering occurs inside the boundaries and that all changes to
memory are visible to all cores.
be a matching memory barrier instruction _before_ reading a variable.
from the time before the constructor did its job. This is why
double-checked locking fails.
[ comp.lang.c++.moderated. First time posters: Do this! ]