implement DCLP using c++11 (http://preshing.com/20130930/double-checked-locking-is-fixed-in-cpp11/)
ref #2838
This commit is contained in:
parent
c399469d95
commit
b3af8bd5f9
1 changed files with 32 additions and 29 deletions
|
@ -29,7 +29,7 @@
|
|||
#include <stdexcept> // std::runtime_error
|
||||
#include <cstdlib> // std::atexit
|
||||
#include <new> // operator new
|
||||
|
||||
#include <atomic>
|
||||
#ifdef MAPNIK_THREADSAFE
|
||||
#include <mutex>
|
||||
#endif
|
||||
|
@ -93,7 +93,7 @@ template <typename T,
|
|||
{
|
||||
#endif
|
||||
friend class CreatePolicy<T>;
|
||||
static T* pInstance_;
|
||||
static std::atomic<T*> pInstance_;
|
||||
static bool destroyed_;
|
||||
singleton(const singleton &rhs);
|
||||
singleton& operator=(const singleton&);
|
||||
|
@ -116,15 +116,18 @@ protected:
|
|||
static std::mutex mutex_;
|
||||
#endif
|
||||
singleton() {}
|
||||
|
||||
public:
|
||||
static T& instance()
|
||||
{
|
||||
if (! pInstance_)
|
||||
T * tmp = pInstance_.load(std::memory_order_acquire);
|
||||
if (tmp == nullptr)
|
||||
{
|
||||
#ifdef MAPNIK_THREADSAFE
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
#endif
|
||||
if (! pInstance_)
|
||||
tmp = pInstance_.load(std::memory_order_relaxed);
|
||||
if (tmp == nullptr)
|
||||
{
|
||||
if (destroyed_)
|
||||
{
|
||||
|
@ -133,14 +136,14 @@ protected:
|
|||
}
|
||||
else
|
||||
{
|
||||
pInstance_ = CreatePolicy<T>::create();
|
||||
|
||||
tmp = CreatePolicy<T>::create();
|
||||
pInstance_.store(tmp, std::memory_order_release);
|
||||
// register destruction
|
||||
std::atexit(&DestroySingleton);
|
||||
}
|
||||
}
|
||||
}
|
||||
return *pInstance_;
|
||||
return *tmp;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -150,7 +153,7 @@ protected:
|
|||
#endif
|
||||
|
||||
template <typename T,
|
||||
template <typename U> class CreatePolicy> T* singleton<T,CreatePolicy>::pInstance_=0;
|
||||
template <typename U> class CreatePolicy> std::atomic<T*> singleton<T,CreatePolicy>::pInstance_;
|
||||
template <typename T,
|
||||
template <typename U> class CreatePolicy> bool singleton<T,CreatePolicy>::destroyed_=false;
|
||||
|
||||
|
|
Loading…
Reference in a new issue