#include <windows.h>
template<class Key> class Lock_Guard
{
public:
Lock_Guard(Key& a_key)
: _key(a_key) { lock(); }
~Lock_Guard() { unlock(); }
void lock() { _key.acquire(); }
void unlock() { _key.release(); }
private:
Key& _key;
};
class Singleton
{
class Interlocked_Mutex
{
public:
void acquire();
void release();
private:
volatile LONG _mutex;
};
public:
static Singleton& instance();
//...
private:
static Singleton* _instance;
static volatile bool _is_created;
static Interlocked_Mutex _key;
};
Singleton*
Singleton::_instance = NULL;
volatile bool
Singleton::_is_created = false;
Singleton::Interlocked_Mutex
Singleton::_key;
void Singleton::Interlocked_Mutex
::acquire()
{
while(InterlockedExchange
(const_cast<LONG*>(&_mutex), 1)
== 1)
{ // We did not acquire
while(_mutex)
; // spin-lock
}
}
void Singleton::Interlocked_Mutex
::release()
{
_mutex = 0;
}
Singleton& Singleton::instance()
{
// Lock-hint check
// (race condition here)
if(!_is_created)
{
Lock_Guard<Interlocked_Mutex>
gate(_key);
// Double-check
// (race condition resolved)
if(!_is_created)
{
_instance = new Singleton;
_is_created = true;
}
}
return *_instance;
}