]> granicus.if.org Git - icu/commitdiff
ICU-20845 UMutex not trivially but constexpr constructible
authorMarkus Scherer <markus.icu@gmail.com>
Tue, 1 Oct 2019 23:33:53 +0000 (16:33 -0700)
committerMarkus Scherer <markus.icu@gmail.com>
Wed, 2 Oct 2019 18:00:19 +0000 (11:00 -0700)
icu4c/source/common/umutex.cpp
icu4c/source/common/umutex.h

index fe50d866d4f5456f12fe6e384941c628bfa289be..ccbee9960a39e7bea47b4f76a41e30ae671e5f0f 100644 (file)
@@ -36,15 +36,6 @@ U_NAMESPACE_BEGIN
 #error U_USER_MUTEX_CPP not supported
 #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::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;
 
 std::once_flag initFlag;
index d154ff8433916418588c17e8cf5556768a8a518b..2503aa4a29144c4c3e86901d897d19e95402a187 100755 (executable)
@@ -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.
@@ -212,7 +222,7 @@ template<class T> void umtx_initOnce(UInitOnce &uio, void (U_CALLCONV *fp)(T, UE
 
 class U_COMMON_API UMutex {
 public:
-    UMutex() = default;
+    UMUTEX_CONSTEXPR UMutex() {}
     ~UMutex() = default;
 
     UMutex(const UMutex &other) = delete;
@@ -230,13 +240,13 @@ public:
     static void cleanup();
 
 private:
-    alignas(std::mutex) char fStorage[sizeof(std::mutex)];
-    std::atomic<std::mutex *> fMutex;
+    alignas(std::mutex) char fStorage[sizeof(std::mutex)] {};
+    std::atomic<std::mutex *> fMutex { nullptr };
 
     /** All initialized UMutexes are kept in a linked list, so that they can be found,
      * and the underlying std::mutex destructed, by u_cleanup().
      */
-    UMutex *fListLink;
+    UMutex *fListLink { nullptr };
     static UMutex *gListHead;
 
     /** Out-of-line function to lazily initialize a UMutex on first use.