mirror of
https://github.com/shadps4-emu/ext-cryptopp.git
synced 2024-11-23 09:59:42 +00:00
Use C++03 Singleton on select Microsoft platforms (Issues 372, 373, 389, 391)
We are back to the "... one object may end up being memory leaked" if faced with concurrent initialization
This commit is contained in:
parent
354502d59d
commit
46c9cc725c
100
config.h
100
config.h
@ -787,113 +787,127 @@ NAMESPACE_END
|
||||
// C++11 or C++14 is available
|
||||
#if defined(CRYPTOPP_CXX11)
|
||||
|
||||
// atomics: MS at VS2012 (17.00); GCC at 4.4; Clang at 3.1/3.2; Intel 13.0; SunCC 12.5.
|
||||
// Compatibility with non-clang compilers.
|
||||
#ifndef __has_feature
|
||||
# define __has_feature(x) 0
|
||||
#endif
|
||||
|
||||
// atomics: MS at VS2012 (17.00); GCC at 4.4; Clang at 3.1/3.2; Intel 13.0; SunCC 5.14.
|
||||
#if (CRYPTOPP_MSC_VERSION >= 1700)
|
||||
# define CRYPTOPP_CXX11_ATOMICS 1
|
||||
#elif __has_feature(cxx_atomic)
|
||||
# define CRYPTOPP_CXX11_ATOMICS 1
|
||||
#elif (__INTEL_COMPILER >= 1300)
|
||||
# define CRYPTOPP_CXX11_ATOMICS 1
|
||||
#elif defined(__clang__)
|
||||
# if __has_feature(cxx_atomic)
|
||||
# define CRYPTOPP_CXX11_ATOMICS 1
|
||||
# endif
|
||||
#elif (CRYPTOPP_GCC_VERSION >= 40400)
|
||||
# define CRYPTOPP_CXX11_ATOMICS 1
|
||||
#elif (__SUNPRO_CC >= 0x5140)
|
||||
# define CRYPTOPP_CXX11_ATOMICS 1
|
||||
#endif // atomics
|
||||
|
||||
// synchronization: MS at VS2012 (17.00); GCC at 4.4; Clang at 3.3; Xcode 5.0; Intel 12.0; SunCC 12.4.
|
||||
// synchronization: MS at VS2012 (17.00); GCC at 4.4; Clang at 3.3; Xcode 5.0; Intel 12.0; SunCC 5.13.
|
||||
// TODO: verify Clang and Intel versions; find __has_feature(x) extension for Clang
|
||||
#if (CRYPTOPP_MSC_VERSION >= 1700)
|
||||
# define CRYPTOPP_CXX11_SYNCHRONIZATION 1
|
||||
#elif (__INTEL_COMPILER >= 1200)
|
||||
# define CRYPTOPP_CXX11_SYNCHRONIZATION 1
|
||||
#elif (CRYPTOPP_LLVM_CLANG_VERSION >= 30300) || (CRYPTOPP_APPLE_CLANG_VERSION >= 50000)
|
||||
# define CRYPTOPP_CXX11_SYNCHRONIZATION 1
|
||||
#elif (__INTEL_COMPILER >= 1200)
|
||||
# define CRYPTOPP_CXX11_SYNCHRONIZATION 1
|
||||
#elif (CRYPTOPP_GCC_VERSION >= 40400)
|
||||
# define CRYPTOPP_CXX11_SYNCHRONIZATION 1
|
||||
#elif (__SUNPRO_CC >= 0x5130)
|
||||
# define CRYPTOPP_CXX11_SYNCHRONIZATION 1
|
||||
#endif // synchronization
|
||||
|
||||
// alignof/alignas: MS at VS2015 (19.00); GCC at 4.8; Clang at 3.3; Intel 15.0; SunCC 12.4.
|
||||
// Dynamic Initialization and Destruction with Concurrency ("Magic Statics")
|
||||
// MS at VS2015 (19.00); GCC at 4.3; LLVM Clang at 2.9; Apple Clang at 4.0; Intel 11.1; SunCC 5.13.
|
||||
// Microsoft's implementation only works for Vista and above, so its further
|
||||
// limited. http://connect.microsoft.com/VisualStudio/feedback/details/1789709
|
||||
#if (CRYPTOPP_MSC_VERSION >= 1900) && ((WINVER >= 0x0600 /*_WIN32_WINNT_VISTA*/) || (_WIN32_WINNT >= 0x0600 /*_WIN32_WINNT_VISTA*/))
|
||||
# define CRYPTOPP_CXX11_DYNAMIC_INIT 1
|
||||
#elif (CRYPTOPP_LLVM_CLANG_VERSION >= 20900) || (CRYPTOPP_APPLE_CLANG_VERSION >= 40000)
|
||||
# define CRYPTOPP_CXX11_DYNAMIC_INIT 1
|
||||
#elif (__INTEL_COMPILER >= 1110)
|
||||
# define CRYPTOPP_CXX11_DYNAMIC_INIT 1
|
||||
#elif (CRYPTOPP_GCC_VERSION >= 40300)
|
||||
# define CRYPTOPP_CXX11_DYNAMIC_INIT 1
|
||||
#elif (__SUNPRO_CC >= 0x5130)
|
||||
# define CRYPTOPP_CXX11_DYNAMIC_INIT 1
|
||||
#endif // Dynamic Initialization compilers
|
||||
|
||||
// alignof/alignas: MS at VS2015 (19.00); GCC at 4.8; Clang at 3.0; Intel 15.0; SunCC 5.13.
|
||||
#if (CRYPTOPP_MSC_VERSION >= 1900)
|
||||
# define CRYPTOPP_CXX11_ALIGNAS 1
|
||||
# define CRYPTOPP_CXX11_ALIGNOF 1
|
||||
#elif __has_feature(cxx_alignas)
|
||||
# define CRYPTOPP_CXX11_ALIGNAS 1
|
||||
#elif (__INTEL_COMPILER >= 1500)
|
||||
# define CRYPTOPP_CXX11_ALIGNAS 1
|
||||
# define CRYPTOPP_CXX11_ALIGNOF 1
|
||||
#elif defined(__clang__)
|
||||
# if __has_feature(cxx_alignas)
|
||||
# define CRYPTOPP_CXX11_ALIGNAS 1
|
||||
# endif
|
||||
# if __has_feature(cxx_alignof)
|
||||
# define CRYPTOPP_CXX11_ALIGNOF 1
|
||||
# endif
|
||||
#elif (CRYPTOPP_GCC_VERSION >= 40800)
|
||||
# define CRYPTOPP_CXX11_ALIGNAS 1
|
||||
# define CRYPTOPP_CXX11_ALIGNOF 1
|
||||
#elif (__SUNPRO_CC >= 0x5130)
|
||||
# define CRYPTOPP_CXX11_ALIGNAS 1
|
||||
# define CRYPTOPP_CXX11_ALIGNOF 1
|
||||
#endif // alignof/alignas
|
||||
#endif // alignas
|
||||
|
||||
// noexcept: MS at VS2015 (19.00); GCC at 4.6; Clang at 3.0; Intel 14.0; SunCC 12.4.
|
||||
// alignof: MS at VS2015 (19.00); GCC at 4.5; Clang at 2.9; Intel 15.0; SunCC 5.13.
|
||||
#if (CRYPTOPP_MSC_VERSION >= 1900)
|
||||
# define CRYPTOPP_CXX11_ALIGNOF 1
|
||||
#elif __has_feature(cxx_alignof)
|
||||
# define CRYPTOPP_CXX11_ALIGNOF 1
|
||||
#elif (__INTEL_COMPILER >= 1500)
|
||||
# define CRYPTOPP_CXX11_ALIGNOF 1
|
||||
#elif (CRYPTOPP_GCC_VERSION >= 40500)
|
||||
# define CRYPTOPP_CXX11_ALIGNOF 1
|
||||
#elif (__SUNPRO_CC >= 0x5130)
|
||||
# define CRYPTOPP_CXX11_ALIGNOF 1
|
||||
#endif // alignof
|
||||
|
||||
// noexcept: MS at VS2015 (19.00); GCC at 4.6; Clang at 3.0; Intel 14.0; SunCC 5.13.
|
||||
#if (CRYPTOPP_MSC_VERSION >= 1900)
|
||||
# define CRYPTOPP_CXX11_NOEXCEPT 1
|
||||
#elif __has_feature(cxx_noexcept)
|
||||
# define CRYPTOPP_CXX11_NOEXCEPT 1
|
||||
#elif (__INTEL_COMPILER >= 1400)
|
||||
# define CRYPTOPP_CXX11_NOEXCEPT 1
|
||||
#elif defined(__clang__)
|
||||
# if __has_feature(cxx_noexcept)
|
||||
# define CRYPTOPP_CXX11_NOEXCEPT 1
|
||||
# endif
|
||||
#elif (CRYPTOPP_GCC_VERSION >= 40600)
|
||||
# define CRYPTOPP_CXX11_NOEXCEPT 1
|
||||
#elif (__SUNPRO_CC >= 0x5130)
|
||||
# define CRYPTOPP_CXX11_NOEXCEPT 1
|
||||
#endif // noexcept compilers
|
||||
|
||||
// variadic templates: MS at VS2013 (18.00); GCC at 4.3; Clang at 2.9; Intel 12.1; SunCC 12.4.
|
||||
// variadic templates: MS at VS2013 (18.00); GCC at 4.3; Clang at 2.9; Intel 12.1; SunCC 5.13.
|
||||
#if (CRYPTOPP_MSC_VERSION >= 1800)
|
||||
# define CRYPTOPP_CXX11_VARIADIC_TEMPLATES 1
|
||||
#elif __has_feature(cxx_variadic_templates)
|
||||
# define CRYPTOPP_CXX11_VARIADIC_TEMPLATES 1
|
||||
#elif (__INTEL_COMPILER >= 1210)
|
||||
# define CRYPTOPP_CXX11_VARIADIC_TEMPLATES 1
|
||||
#elif defined(__clang__)
|
||||
# if __has_feature(cxx_variadic_templates)
|
||||
# define CRYPTOPP_CXX11_VARIADIC_TEMPLATES 1
|
||||
# endif
|
||||
#elif (CRYPTOPP_GCC_VERSION >= 40300)
|
||||
# define CRYPTOPP_CXX11_VARIADIC_TEMPLATES 1
|
||||
#elif (__SUNPRO_CC >= 0x5130)
|
||||
# define CRYPTOPP_CXX11_VARIADIC_TEMPLATES 1
|
||||
#endif // variadic templates
|
||||
|
||||
// constexpr: MS at VS2015 (19.00); GCC at 4.6; Clang at 3.0; Intel 16.0; SunCC 12.4.
|
||||
// constexpr: MS at VS2015 (19.00); GCC at 4.6; Clang at 3.1; Intel 16.0; SunCC 5.13.
|
||||
// Intel has mis-supported the feature since at least ICPC 13.00
|
||||
#if (CRYPTOPP_MSC_VERSION >= 1900)
|
||||
# define CRYPTOPP_CXX11_CONSTEXPR 1
|
||||
#elif __has_feature(cxx_constexpr)
|
||||
# define CRYPTOPP_CXX11_CONSTEXPR 1
|
||||
#elif (__INTEL_COMPILER >= 1600)
|
||||
# define CRYPTOPP_CXX11_CONSTEXPR 1
|
||||
#elif defined(__clang__)
|
||||
# if __has_feature(cxx_constexpr)
|
||||
# define CRYPTOPP_CXX11_CONSTEXPR 1
|
||||
# endif
|
||||
#elif (CRYPTOPP_GCC_VERSION >= 40600)
|
||||
# define CRYPTOPP_CXX11_CONSTEXPR 1
|
||||
#elif (__SUNPRO_CC >= 0x5130)
|
||||
# define CRYPTOPP_CXX11_CONSTEXPR 1
|
||||
#endif // constexpr compilers
|
||||
|
||||
// nullptr_t: MS at VS2010 (16.00); GCC at 4.6; Clang at 3.3; Intel 12.0; SunCC 12.4.
|
||||
// Intel has upported the feature since at least ICPC 12.00
|
||||
// nullptr_t: MS at VS2010 (16.00); GCC at 4.6; Clang at 3.3; Intel 10.0; SunCC 5.13.
|
||||
#if (CRYPTOPP_MSC_VERSION >= 1600)
|
||||
# define CRYPTOPP_CXX11_NULLPTR 1
|
||||
#elif (__INTEL_COMPILER >= 1200)
|
||||
#elif __has_feature(cxx_nullptr)
|
||||
# define CRYPTOPP_CXX11_NULLPTR 1
|
||||
#elif (__INTEL_COMPILER >= 1000)
|
||||
# define CRYPTOPP_CXX11_NULLPTR 1
|
||||
#elif defined(__clang__)
|
||||
# if __has_feature(cxx_nullptr)
|
||||
# define CRYPTOPP_CXX11_NULLPTR 1
|
||||
# endif
|
||||
#elif (CRYPTOPP_GCC_VERSION >= 40600)
|
||||
# define CRYPTOPP_CXX11_NULLPTR 1
|
||||
#elif (__SUNPRO_CC >= 0x5130)
|
||||
|
22
misc.h
22
misc.h
@ -290,7 +290,7 @@ struct NewObject
|
||||
//! \brief Restricts the instantiation of a class to one static object without locks
|
||||
//! \tparam T the class or type
|
||||
//! \tparam F the object factory for T
|
||||
//! \tparam instance the initiali instance count
|
||||
//! \tparam instance an instance counter for the class object
|
||||
//! \details This class safely initializes a static object in a multithreaded environment. For C++03
|
||||
//! and below it will do so without using locks for portability. 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
|
||||
@ -298,8 +298,14 @@ struct NewObject
|
||||
//! local storage on early Windows platforms, like Windows XP and Windows 2003.
|
||||
//! \details For C++11 and above, a standard double-checked locking pattern with thread fences
|
||||
//! are used. The locks and fences are standard and do not hinder portability.
|
||||
//! \sa <A HREF="http://preshing.com/20130930/double-checked-locking-is-fixed-in-cpp11/">Double-Checked
|
||||
//! Locking is Fixed In C++11</A>
|
||||
//! \details Microsoft's C++11 implementation provides the necessary primitive support on Windows Vista and
|
||||
//! above when using Visual Studio 2015 (<tt>cl.exe</tt> version 19.00). If C++11 is desired, you should
|
||||
//! set <tt>WINVER</tt> or <tt>_WIN32_WINNT</tt> to 0x600 (or above), and compile with Visual Studio 2015.
|
||||
//! \sa <A HREF="http://preshing.com/20130930/double-checked-locking-is-fixed-in-cpp11/">Double-Checked Locking
|
||||
//! is Fixed In C++11</A>, <A HREF="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2660.htm">Dynamic
|
||||
//! Initialization and Destruction with Concurrency</A> and
|
||||
//! <A HREF="http://msdn.microsoft.com/en-us/library/6yh4a9k1.aspx">Thread Local Storage (TLS)</A> on MSDN.
|
||||
//! \since Crypto++ 5.2
|
||||
template <class T, class F = NewObject<T>, int instance=0>
|
||||
class Singleton
|
||||
{
|
||||
@ -316,13 +322,15 @@ private:
|
||||
//! \brief Return a reference to the inner Singleton object
|
||||
//! \tparam T the class or type
|
||||
//! \tparam F the object factory for T
|
||||
//! \tparam instance an instance counter for the class object
|
||||
//! \details Ref() is used to create the object using the object factory. The
|
||||
//! object is only created once with the limitations discussed in the class documentation.
|
||||
//! \sa <A HREF="http://preshing.com/20130930/double-checked-locking-is-fixed-in-cpp11/">Double-Checked Locking is Fixed In C++11</A>
|
||||
#if defined(CRYPTOPP_CXX11_ATOMICS) && defined(CRYPTOPP_CXX11_SYNCHRONIZATION)
|
||||
//! \since Crypto++ 5.2
|
||||
template <class T, class F, int instance>
|
||||
const T & Singleton<T, F, instance>::Ref(CRYPTOPP_NOINLINE_DOTDOTDOT) const
|
||||
{
|
||||
#if defined(CRYPTOPP_CXX11_ATOMICS) && defined(CRYPTOPP_CXX11_SYNCHRONIZATION) && defined(CRYPTOPP_CXX11_DYNAMIC_INIT)
|
||||
static std::mutex s_mutex;
|
||||
static std::atomic<T*> s_pObject;
|
||||
|
||||
@ -344,11 +352,7 @@ template <class T, class F, int instance>
|
||||
std::atomic_thread_fence(std::memory_order_release);
|
||||
|
||||
return *newObject;
|
||||
}
|
||||
#else
|
||||
template <class T, class F, int instance>
|
||||
const T & Singleton<T, F, instance>::Ref(CRYPTOPP_NOINLINE_DOTDOTDOT) const
|
||||
{
|
||||
static volatile simple_ptr<T> s_pObject;
|
||||
T *p = s_pObject.m_p;
|
||||
MEMORY_BARRIER();
|
||||
@ -370,8 +374,8 @@ const T & Singleton<T, F, instance>::Ref(CRYPTOPP_NOINLINE_DOTDOTDOT) const
|
||||
MEMORY_BARRIER();
|
||||
|
||||
return *newObject;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// ************** misc functions ***************
|
||||
|
||||
|
@ -26,6 +26,8 @@ ThreadLocalStorage::Err::Err(const std::string& operation, int error)
|
||||
{
|
||||
}
|
||||
|
||||
// Windows: "a process may have up to TLS_MINIMUM_AVAILABLE indexes (guaranteed to be greater than
|
||||
// or equal to 64)", https://support.microsoft.com/en-us/help/94804/info-thread-local-storage-overview
|
||||
ThreadLocalStorage::ThreadLocalStorage()
|
||||
{
|
||||
#ifdef HAS_WINTHREADS
|
||||
|
Loading…
Reference in New Issue
Block a user