ICU-20845 UMutex not trivially but constexpr constructible
This commit is contained in:
parent
7f862281da
commit
e5381c956b
@ -36,15 +36,6 @@ U_NAMESPACE_BEGIN
|
|||||||
#error U_USER_MUTEX_CPP not supported
|
#error U_USER_MUTEX_CPP not supported
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Check that UMutex is trivially constructable & destructable, which ensures that
|
|
||||||
// static instances are not running static constructors or destructors.
|
|
||||||
#if (defined(__GNUG__) && __GNUC__ < 5) || (defined(__clang__) && __clang_major__ < 5)
|
|
||||||
// skip
|
|
||||||
#else
|
|
||||||
static_assert(std::is_trivially_constructible<UMutex>::value, "UMutex not trivially constructable.");
|
|
||||||
static_assert(std::is_trivially_destructible<UMutex>::value, "UMutex not trivially destructable.");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************************************
|
/*************************************************************************************************
|
||||||
*
|
*
|
||||||
@ -56,7 +47,8 @@ namespace {
|
|||||||
std::mutex *initMutex;
|
std::mutex *initMutex;
|
||||||
std::condition_variable *initCondition;
|
std::condition_variable *initCondition;
|
||||||
|
|
||||||
// The ICU global mutex. Used when ICU implementation code passes NULL for the mutex pointer.
|
// The ICU global mutex.
|
||||||
|
// Used when ICU implementation code passes nullptr for the mutex pointer.
|
||||||
UMutex globalMutex;
|
UMutex globalMutex;
|
||||||
|
|
||||||
std::once_flag initFlag;
|
std::once_flag initFlag;
|
||||||
|
@ -184,6 +184,16 @@ template<class T> void umtx_initOnce(UInitOnce &uio, void (U_CALLCONV *fp)(T, UE
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UMutex should be constexpr-constructible, so that no initialization code
|
||||||
|
// is run during startup.
|
||||||
|
// This works on all C++ libraries except MS VS before VS2019.
|
||||||
|
#if (defined(_CPPLIB_VER) && !defined(_MSVC_STL_VERSION)) || \
|
||||||
|
(defined(_MSVC_STL_VERSION) && _MSVC_STL_VERSION < 142)
|
||||||
|
// (VS std lib older than VS2017) || (VS std lib version < VS2019)
|
||||||
|
# define UMUTEX_CONSTEXPR
|
||||||
|
#else
|
||||||
|
# define UMUTEX_CONSTEXPR constexpr
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* UMutex - ICU Mutex class.
|
* UMutex - ICU Mutex class.
|
||||||
@ -212,7 +222,7 @@ template<class T> void umtx_initOnce(UInitOnce &uio, void (U_CALLCONV *fp)(T, UE
|
|||||||
|
|
||||||
class U_COMMON_API UMutex {
|
class U_COMMON_API UMutex {
|
||||||
public:
|
public:
|
||||||
UMutex() = default;
|
UMUTEX_CONSTEXPR UMutex() {}
|
||||||
~UMutex() = default;
|
~UMutex() = default;
|
||||||
|
|
||||||
UMutex(const UMutex &other) = delete;
|
UMutex(const UMutex &other) = delete;
|
||||||
@ -230,13 +240,13 @@ public:
|
|||||||
static void cleanup();
|
static void cleanup();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
alignas(std::mutex) char fStorage[sizeof(std::mutex)];
|
alignas(std::mutex) char fStorage[sizeof(std::mutex)] {};
|
||||||
std::atomic<std::mutex *> fMutex;
|
std::atomic<std::mutex *> fMutex { nullptr };
|
||||||
|
|
||||||
/** All initialized UMutexes are kept in a linked list, so that they can be found,
|
/** All initialized UMutexes are kept in a linked list, so that they can be found,
|
||||||
* and the underlying std::mutex destructed, by u_cleanup().
|
* and the underlying std::mutex destructed, by u_cleanup().
|
||||||
*/
|
*/
|
||||||
UMutex *fListLink;
|
UMutex *fListLink { nullptr };
|
||||||
static UMutex *gListHead;
|
static UMutex *gListHead;
|
||||||
|
|
||||||
/** Out-of-line function to lazily initialize a UMutex on first use.
|
/** Out-of-line function to lazily initialize a UMutex on first use.
|
||||||
|
Loading…
Reference in New Issue
Block a user