Listing 1: A mutex object that relies on zero-initialization of non-local statics
#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; }