Reputation: 1
Singleton* Singleton::instance() {
if (pInstance == 0) {
Lock lock;
if (pInstance == 0) {
Singleton* temp = new Singleton; // initialize to temp
pInstance = temp; // assign temp to pInstance
}
}
Suppose compiler is not optimizing the redundant temp. Thread A is in and allocated and constructed the Singleton object, this object is pointed by temp. Now A is preempted just after that. Now thread B gets the lock, get into in and check that pInstance is NULL. It will also create the Singleton object and over writes the existing pointer. I guess there is a memory leak now. What is your opinion ? Complete source is here: Code Reference:http://erdani.com/publications/DDJ_Jul_Aug_2004_revised.pdf
Upvotes: 0
Views: 120
Reputation: 5118
In C++11, the standard stipulates in paragraph 6.7 that:
such a variable is initialized the first time control passes through its declaration; such a variable is considered initialized upon the completion of its initialization. [...] If control enters the declaration concurrently while the variable is being initialized, the concurrent execution shall wait for completion of the initialization.
The implementation must not introduce any deadlock around execution of the initializer.
This leads to the following very simple and thread-safe singleton method implementation:
Singleton* Singleton::instance() {
Singleton instance;
return &instance;
}
See this question for more details on which compilers support this.
Upvotes: 1
Reputation: 8180
No. When A is interrupted, it sill owns the lock. Thus B has to wait until A releases the lock, but then pInstance is assigned and B's second check for null will fail.
Upvotes: 1