Reputation: 3143
I was reading a paper on "Perils of double check locking by Scott Meyers". http://www.aristeia.com/Papers/DDJ_Jul_Aug_2004_revised.pdf
The author gives reasons why the double check lock fails (page 3, section 4). I was thinking of ways to get around this problem without using C++11. Not that I don't want to use C++ 11 but just to see if it is possible to solve it without using functions such as std::call_once, etc
class Singleton {
public:
static Singleton* instance();
private:
static Singleton* pInstance;
int someData_;
};
Singleton* Singleton::instance()
{
class SeqAssign{
public:
SeqAssign(Singleton*& pInst, Singleton* pNew):
pInstance(pInst), pNewedInst(pNew){
}
~SeqAssign(){
pInstance = pNewedInst;
}
private:
Singleton*& pInstance;
Singleton* pNewedInst;
};
if (pInstance == 0) { // 1st test
Lock lock;
if (pInstance == 0) { // 2nd test
SeqAssign seq(pInstance, new Singleton);
}
}
return pInstance;
}
Will the code in Singleton::instance() work in a multi-threaded environment as the order in which the constructor and destructor is called for the SeqAssign class is deterministic.
Upvotes: 1
Views: 415
Reputation: 153977
No. The variable pInstance
is accessed from more than one thread. It
is modified. The code has undefined behavior. And I'm not sure what
you thing SeqAssign
will do, since it doesn't introduce any additional
inter-thread sequencing.
There is no way to make double checked logging work in standard C++; all of the solutions involve atomic variables (possibly implemented using inline assembler) or thread local storage.
Upvotes: 2