diff options
Diffstat (limited to 'misc.h')
-rw-r--r-- | misc.h | 45 |
1 files changed, 18 insertions, 27 deletions
@@ -6,7 +6,6 @@ #include <string.h> // for memcpy and memmove #ifdef _MSC_VER - #include <stdlib.h> #if _MSC_VER >= 1400 // VC2005 workaround: disable declarations that conflict with winnt.h #define _interlockedbittestandset CRYPTOPP_DISABLED_INTRINSIC_1 @@ -101,9 +100,9 @@ struct NewObject T* operator()() const {return new T;} }; -/*! This function safely initializes a static object in a multithreaded environment without using locks. - It may leak memory when two threads try to initialize the static object at the same time - but this should be acceptable since each static object is only initialized once per session. +/*! This function safely initializes a static object in a multithreaded environment without using locks (for portability). + Note that if two threads call Ref() at the same time, they may get back different references, and one object + may end up being memory leaked. This is by design. */ template <class T, class F = NewObject<T>, int instance=0> class Singleton @@ -121,31 +120,23 @@ private: template <class T, class F, int instance> const T & Singleton<T, F, instance>::Ref(CRYPTOPP_NOINLINE_DOTDOTDOT) const { - static simple_ptr<T> s_pObject; - static volatile char s_objectState = 0; + static volatile simple_ptr<T> s_pObject; + T *p = s_pObject.m_p; -retry: - switch (s_objectState) + if (p) + return *p; + + T *newObject = m_objectFactory(); + p = s_pObject.m_p; + + if (p) { - case 0: - s_objectState = 1; - try - { - s_pObject.m_p = m_objectFactory(); - } - catch(...) - { - s_objectState = 0; - throw; - } - s_objectState = 2; - break; - case 1: - goto retry; - default: - break; + delete newObject; + return *p; } - return *s_pObject.m_p; + + s_pObject.m_p = newObject; + return *newObject; } // ************** misc functions *************** @@ -555,7 +546,7 @@ static std::string StringNarrow(const wchar_t *str, bool throwOnError = true) #pragma warning(disable: 4996) // 'wcstombs': This function or variable may be unsafe. #endif size_t size = wcstombs(NULL, str, 0); - if (size == -1) + if (size == size_t(0)-1) { if (throwOnError) throw InvalidArgument("StringNarrow: wcstombs() call failed"); |