Re: double-checked locking for singleton pattern
"Jan Pfeifer" <pfeifer@stanford.edu> wrote in message
news:g1p6n2$nl6$1@news.stanford.edu...
On Fri, 30 May 2008 08:50:54 -0600, gpderetta wrote:
Whether you use a lock or a barrier for synchronization, you need to use
the same object on all threads that need to be synchronized.
Sorry, that is true. I failed to detail that in my pseudo-code. Let me
retry it:
Singleton *pInstance = 0;
Mutex mtx1, mtx2;
Singleton* Singleton::instance()
{
if (pInstance == 0) {
Lock lock_1(mtx1);
if (pInstance == 0) {
static Singleton* volatile temp = new Singleton();
{
Lock lock_2(mtx2);
pInstance = temp;
}
}
}
}
[...]
Its not guaranteed to work because there are mutex implementations out there
which do not use a memory barrier after every lock procedure; here is an
example:
http://groups.google.com/group/comp.programming.threads/browse_frm/thread/22b2736484af3ca6
Therefore, you would need to store into `pInstance' _after_ mtx2 has been
acquired and released. Here is a sketch:
______________________________________________________________
#include <pthread.h>
class mutex_guard {
pthread_mutex_t* const m_mtx;
public:
mutex_guard(pthread_mutex_t* const mtx) : m_mtx(mtx) {
pthread_mutex_lock(m_mtx);
}
~mutex_guard() throw() {
pthread_mutex_unlock(m_mtx);
}
};
template<typename T>
static T& once() {
static T* volatile g_this = NULL;
static pthread_mutex_t g_main_mtx = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t g_mem_mtx = PTHREAD_MUTEX_INITIALIZER;
T* l_this = g_this;
if (! l_this) {
mutex_guard const main_lock(&g_main_mtx);
if (! l_this) {
l_this = new T;
{
mutex_guard const mem_lock(&g_mem_mtx);
}
g_this = l_this;
}
}
return *l_this;
}
______________________________________________________________
However, its still not guaranteed to work because it has undefined behavior
according to the PThread Standard. Although, it will most certainly work in
practice on some existing platforms if the compiler does not optimize the
`g_mem_mtx' lock/unlock sequence away...
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]