Change to file scope statics for Zero(), One(), Two() (Thanks DB, Issue 310)

This commit is contained in:
Jeffrey Walton 2016-09-29 21:10:11 -04:00
parent 1c30ffc64a
commit 8518d22760
No known key found for this signature in database
GPG Key ID: B36AB348921B1838
2 changed files with 14 additions and 5 deletions

View File

@ -3011,21 +3011,27 @@ struct NewInteger
}
};
// File scope static due to subtle initialization problems in a threaded
// Windows environment. See the comments for Singleton. Thanks DB.
static const Integer& s_zero = Singleton<Integer>().Ref();
const Integer &Integer::Zero()
{
static const Integer& s_zero = Singleton<Integer>().Ref();
return s_zero;
}
// File scope static due to subtle initialization problems in a threaded
// Windows environment. See the comments for Singleton. Thanks DB.
static const Integer& s_one = Singleton<Integer, NewInteger<1> >().Ref();
const Integer &Integer::One()
{
static const Integer& s_one = Singleton<Integer, NewInteger<1> >().Ref();
return s_one;
}
// File scope static due to subtle initialization problems in a threaded
// Windows environment. See the comments for Singleton. Thanks DB.
static const Integer& s_two = Singleton<Integer, NewInteger<2> >().Ref();
const Integer &Integer::Two()
{
static const Integer& s_two = Singleton<Integer, NewInteger<2> >().Ref();
return s_two;
}

7
misc.h
View File

@ -257,9 +257,12 @@ struct NewObject
//! \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
//! is by design. For C++11 and above, a standard double-checked locking pattern with thread fences
//! is by design and it avoids a subltle initialization problem ina multithreaded environment with thread
//! 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>
//! \sa <A HREF="http://preshing.com/20130930/double-checked-locking-is-fixed-in-cpp11/">Double-Checked
//! Locking is Fixed In C++11</A>
template <class T, class F = NewObject<T>, int instance=0>
class Singleton
{