I'm trying to create a multi threaded and templated singleton as part of my advance c++ study. I've been told I have a race condition in my code and after hours of trying to figure it out i can't find it.
I won't write the whole class (though it's a simple one) but the exact location where I've been focused down to:
template <class T>
void Singleton<T>::onceFunction()
{
static T instanceObject;
Singleton<T>::instance = &instanceObject;
}
template <class T>
T& Singleton<T>::getInstance()
{
while (0 == Singleton::instance)
{
static pthread_once_t once_control = PTHREAD_ONCE_INIT;
pthread_once(&once_control, Singleton<T>::onceFunction);
}
return *Singleton::instance;
}
I'm using pthread_once() since I'm not compiling with c++11.
The code you show is designed to protect/serialize the initailization of
static T instanceObject;
as defined in Singleton<T>::onceFunction()
. In order to achieve that you use pthread_once
. However, you have declared the pthread_once_t
flag once_control
at function/block scope with static storage...
static pthread_once_t once_control = PTHREAD_ONCE_INIT;
Hence, I think the initialization of once_control
suffers from the same race condition that your code is designed to solve for instanceObject
.
Make once_control
a static member of Singleton<T>
instead.
Note: Your code also assumes the assignment...
Singleton<T>::instance = &instanceObject;
is atomic.