fix possible race condition in Singleton::Ref()
tolerate double destruction of Singleton and g_nullNameValuePairs fix #include of standard headersimport/raw
parent
a84dd77076
commit
227b0810cf
|
|
@ -30,7 +30,14 @@ const std::string DEFAULT_CHANNEL;
|
||||||
const std::string AAD_CHANNEL = "AAD";
|
const std::string AAD_CHANNEL = "AAD";
|
||||||
const std::string &BufferedTransformation::NULL_CHANNEL = DEFAULT_CHANNEL;
|
const std::string &BufferedTransformation::NULL_CHANNEL = DEFAULT_CHANNEL;
|
||||||
|
|
||||||
const NullNameValuePairs g_nullNameValuePairs;
|
class NullNameValuePairs : public NameValuePairs
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const {return false;}
|
||||||
|
};
|
||||||
|
|
||||||
|
simple_ptr<NullNameValuePairs> s_pNullNameValuePairs(new NullNameValuePairs);
|
||||||
|
const NameValuePairs &g_nullNameValuePairs = *s_pNullNameValuePairs.m_p;
|
||||||
|
|
||||||
BufferedTransformation & TheBitBucket()
|
BufferedTransformation & TheBitBucket()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -318,14 +318,7 @@ DOCUMENTED_NAMESPACE_BEGIN(Name)
|
||||||
DOCUMENTED_NAMESPACE_END
|
DOCUMENTED_NAMESPACE_END
|
||||||
|
|
||||||
//! empty set of name-value pairs
|
//! empty set of name-value pairs
|
||||||
class CRYPTOPP_DLL NullNameValuePairs : public NameValuePairs
|
extern CRYPTOPP_DLL const NameValuePairs &g_nullNameValuePairs;
|
||||||
{
|
|
||||||
public:
|
|
||||||
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const {return false;}
|
|
||||||
};
|
|
||||||
|
|
||||||
//! _
|
|
||||||
extern CRYPTOPP_DLL const NullNameValuePairs g_nullNameValuePairs;
|
|
||||||
|
|
||||||
// ********************************************************
|
// ********************************************************
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@
|
||||||
#include <string.h> // for memcpy and memmove
|
#include <string.h> // for memcpy and memmove
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#include <stdlib.h>
|
|
||||||
#if _MSC_VER >= 1400
|
#if _MSC_VER >= 1400
|
||||||
// VC2005 workaround: disable declarations that conflict with winnt.h
|
// VC2005 workaround: disable declarations that conflict with winnt.h
|
||||||
#define _interlockedbittestandset CRYPTOPP_DISABLED_INTRINSIC_1
|
#define _interlockedbittestandset CRYPTOPP_DISABLED_INTRINSIC_1
|
||||||
|
|
@ -101,9 +100,9 @@ struct NewObject
|
||||||
T* operator()() const {return new T;}
|
T* operator()() const {return new T;}
|
||||||
};
|
};
|
||||||
|
|
||||||
/*! This function safely initializes a static object in a multithreaded environment without using locks.
|
/*! This function safely initializes a static object in a multithreaded environment without using locks (for portability).
|
||||||
It may leak memory when two threads try to initialize the static object at the same time
|
Note that if two threads call Ref() at the same time, they may get back different references, and one object
|
||||||
but this should be acceptable since each static object is only initialized once per session.
|
may end up being memory leaked. This is by design.
|
||||||
*/
|
*/
|
||||||
template <class T, class F = NewObject<T>, int instance=0>
|
template <class T, class F = NewObject<T>, int instance=0>
|
||||||
class Singleton
|
class Singleton
|
||||||
|
|
@ -121,31 +120,23 @@ private:
|
||||||
template <class T, class F, int instance>
|
template <class T, class F, int instance>
|
||||||
const T & Singleton<T, F, instance>::Ref(CRYPTOPP_NOINLINE_DOTDOTDOT) const
|
const T & Singleton<T, F, instance>::Ref(CRYPTOPP_NOINLINE_DOTDOTDOT) const
|
||||||
{
|
{
|
||||||
static simple_ptr<T> s_pObject;
|
static volatile simple_ptr<T> s_pObject;
|
||||||
static volatile char s_objectState = 0;
|
T *p = s_pObject.m_p;
|
||||||
|
|
||||||
retry:
|
if (p)
|
||||||
switch (s_objectState)
|
return *p;
|
||||||
|
|
||||||
|
T *newObject = m_objectFactory();
|
||||||
|
p = s_pObject.m_p;
|
||||||
|
|
||||||
|
if (p)
|
||||||
{
|
{
|
||||||
case 0:
|
delete newObject;
|
||||||
s_objectState = 1;
|
return *p;
|
||||||
try
|
|
||||||
{
|
|
||||||
s_pObject.m_p = m_objectFactory();
|
|
||||||
}
|
|
||||||
catch(...)
|
|
||||||
{
|
|
||||||
s_objectState = 0;
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
s_objectState = 2;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
goto retry;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
return *s_pObject.m_p;
|
|
||||||
|
s_pObject.m_p = newObject;
|
||||||
|
return *newObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ************** misc functions ***************
|
// ************** 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.
|
#pragma warning(disable: 4996) // 'wcstombs': This function or variable may be unsafe.
|
||||||
#endif
|
#endif
|
||||||
size_t size = wcstombs(NULL, str, 0);
|
size_t size = wcstombs(NULL, str, 0);
|
||||||
if (size == -1)
|
if (size == size_t(0)-1)
|
||||||
{
|
{
|
||||||
if (throwOnError)
|
if (throwOnError)
|
||||||
throw InvalidArgument("StringNarrow: wcstombs() call failed");
|
throw InvalidArgument("StringNarrow: wcstombs() call failed");
|
||||||
|
|
|
||||||
|
|
@ -69,14 +69,6 @@ being unloaded from L1 cache, until that round is finished.
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
|
|
||||||
#ifdef __sun
|
|
||||||
#include <alloca.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __MINGW32__
|
|
||||||
#include <malloc.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
NAMESPACE_BEGIN(CryptoPP)
|
NAMESPACE_BEGIN(CryptoPP)
|
||||||
|
|
||||||
#ifdef CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS
|
#ifdef CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,6 @@
|
||||||
|
|
||||||
#if defined(CRYPTOPP_MEMALIGN_AVAILABLE) || defined(CRYPTOPP_MM_MALLOC_AVAILABLE) || defined(QNX)
|
#if defined(CRYPTOPP_MEMALIGN_AVAILABLE) || defined(CRYPTOPP_MM_MALLOC_AVAILABLE) || defined(QNX)
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#else
|
|
||||||
#include <stdlib.h>
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
NAMESPACE_BEGIN(CryptoPP)
|
NAMESPACE_BEGIN(CryptoPP)
|
||||||
|
|
@ -352,8 +350,11 @@ public:
|
||||||
//! copy contents and size from another SecBlock
|
//! copy contents and size from another SecBlock
|
||||||
void Assign(const SecBlock<T, A> &t)
|
void Assign(const SecBlock<T, A> &t)
|
||||||
{
|
{
|
||||||
New(t.m_size);
|
if (this != &t)
|
||||||
memcpy_s(m_ptr, m_size*sizeof(T), t.m_ptr, m_size*sizeof(T));
|
{
|
||||||
|
New(t.m_size);
|
||||||
|
memcpy_s(m_ptr, m_size*sizeof(T), t.m_ptr, m_size*sizeof(T));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SecBlock<T, A>& operator=(const SecBlock<T, A> &t)
|
SecBlock<T, A>& operator=(const SecBlock<T, A> &t)
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,8 @@ NAMESPACE_BEGIN(CryptoPP)
|
||||||
template <class T> class simple_ptr
|
template <class T> class simple_ptr
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
simple_ptr() : m_p(NULL) {}
|
simple_ptr(T *p = NULL) : m_p(p) {}
|
||||||
~simple_ptr() {delete m_p;}
|
~simple_ptr() {delete m_p; m_p = NULL;} // set m_p to NULL so double destruction (which might occur in Singleton) will be harmless
|
||||||
T *m_p;
|
T *m_p;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,24 +4,28 @@
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <exception>
|
#include <exception>
|
||||||
#include <typeinfo>
|
#include <typeinfo>
|
||||||
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#include <string.h> // CodeWarrior doesn't have memory.h
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
// re-disable this
|
// for alloca
|
||||||
#pragma warning(disable: 4231)
|
#ifdef __sun
|
||||||
|
#include <alloca.h>
|
||||||
|
#elif defined(__MINGW32__)
|
||||||
|
#include <malloc.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(_MSC_VER) && defined(_CRTAPI1)
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(disable: 4231) // re-disable this
|
||||||
|
#ifdef _CRTAPI1
|
||||||
#define CRYPTOPP_MSVCRT6
|
#define CRYPTOPP_MSVCRT6
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue