]> granicus.if.org Git - icu/commitdiff
ICU-10183 Use std::mutex by default; clean up related dependency check issues.
authorAndy Heninger <andy.heninger@gmail.com>
Mon, 12 Nov 2018 18:20:49 +0000 (10:20 -0800)
committerAndy Heninger <andy.heninger@gmail.com>
Mon, 19 Nov 2018 00:28:40 +0000 (16:28 -0800)
icu4c/source/common/putilimp.h
icu4c/source/common/umutex.cpp
icu4c/source/common/umutex.h [changed mode: 0644->0755]
icu4c/source/test/depstest/dependencies.txt
icu4c/source/test/depstest/depstest.py

index e4821e420bfdd0536af99dbf97c75afe97644edb..73defd9d072809459ee8693f221ad4a6928e2999 100644 (file)
@@ -245,7 +245,7 @@ typedef size_t uintptr_t;
 #ifdef U_HAVE_STD_MUTEX
     /* Use the predefined value. */
 #else
-#    define U_HAVE_STD_MUTEX 0
+#    define U_HAVE_STD_MUTEX 1
 #endif
 
 /*===========================================================================*/
index b4671e3b5562626088acefa24f6a814a60e3c7d7..8044430120e7f08918910a227d85c8e9b179a2c6 100644 (file)
@@ -64,6 +64,11 @@ umtx_unlock(UMutex* mutex)
     mutex->fMutex.unlock();
 }
 
+UConditionVar::UConditionVar() : fCV() {
+}
+
+UConditionVar::~UConditionVar() {
+}
 
 U_CAPI void U_EXPORT2
 umtx_condWait(UConditionVar *cond, UMutex *mutex) {
old mode 100644 (file)
new mode 100755 (executable)
index 9416663..92539e4
@@ -341,19 +341,42 @@ U_NAMESPACE_END
 #include <mutex>
 #include <condition_variable>
 
+#include "unicode/uobject.h"
 
-struct UMutex {
-    std::mutex   fMutex;
+struct UMutex : public icu::UMemory {
+    UMutex() = default;
+    ~UMutex() = default;
+    UMutex(const UMutex &other) = delete;
+    UMutex &operator =(const UMutex &other) = delete;
+
+    std::mutex   fMutex = {};    // Note: struct - pubic members - because most access is from
+    //                           //       plain C style functions (umtx_lock(), etc.)
 };
 
-struct UConditionVar {
+
+struct UConditionVar : public icu::UMemory {
+       U_COMMON_API UConditionVar();
+       U_COMMON_API ~UConditionVar();
+    UConditionVar(const UConditionVar &other) = delete;
+    UConditionVar &operator =(const UConditionVar &other) = delete;
+
     std::condition_variable_any fCV;
 };
 
 #define U_MUTEX_INITIALIZER {}
 #define U_CONDITION_INITIALIZER {}
 
-
+// Implementation notes for UConditionVar:
+//
+// Use an out-of-line constructor to reduce problems with the ICU dependency checker.
+// On Linux, the default constructor of std::condition_variable_any
+// produces an in-line reference to global operator new(), which the
+// dependency checker flags for any file that declares a UConditionVar. With
+// an out-of-line constructor, the dependency is constrained to umutex.o
+//
+// Do not export (U_COMMON_API) the entire class, but only the constructor
+// and destructor, to avoid Windows build problems with attempting to export the
+// std::condition_variable_any.
 
 #elif U_PLATFORM_USES_ONLY_WIN32_API
 
index 7e447afb54ebbb41ecb87f364037ab83b440ed1b..00cc5ff29754e179137bc249e2e03cfef5d05769 100644 (file)
@@ -24,6 +24,7 @@ system_symbols:
     stdio_input stdio_output file_io readlink_function dir_io mmap_functions dlfcn
     # C++
     cplusplus iostream
+    std_mutex
 
 group: PIC
     # Position-Independent Code (-fPIC) requires a Global Offset Table.
@@ -38,6 +39,15 @@ group: system_debug
 group: malloc_functions
     free malloc realloc
 
+group: std_mutex
+    std::condition_variable::notify_one()
+    std::condition_variable::wait(std::unique_lock<std::mutex>&)
+    std::condition_variable::notify_all()
+    std::condition_variable::condition_variable()
+    std::condition_variable::~condition_variable()
+    std::condition_variable_any::condition_variable_any()
+    std::condition_variable_any::~condition_variable_any()
+
 group: ubsan
     # UBSan=UndefinedBehaviorSanitizer, clang -fsanitize=bounds
     __ubsan_handle_out_of_bounds
@@ -819,6 +829,7 @@ group: platform
     stdio_input readlink_function dir_io
     dlfcn  # Move related code into icuplug.c?
     cplusplus
+    std_mutex
 
 # ICU i18n library ----------------------------------------------------------- #
 
index 231c6819c6e1c0d2c6844d4fcfddf02197b467fb..dcdbca8af0b07cbca96e6a39ba173a30feb15a06 100755 (executable)
@@ -16,8 +16,11 @@ This probably works only on Linux.
 
 The exit code is 0 if everything is fine, 1 for errors, 2 for only warnings.
 
-Sample invocation:
-  ~/svn.icu/trunk/src/source/test/depstest$ ./depstest.py ~/svn.icu/trunk/dbg
+Sample invocation with an in-source build:
+  ~/icu/icu4c/source/test/depstest$ ./depstest.py ../../
+
+Sample invocation with an out-of-source build:
+  ~/icu/icu4c/source/test/depstest$ ./depstest.py ~/build/
 """
 
 __author__ = "Markus W. Scherer"
@@ -87,6 +90,16 @@ def _ReadLibrary(root_path, library_name):
   for path in obj_paths:
     _ReadObjFile(root_path, library_name, os.path.basename(path))
 
+# Dependencies that would otherwise be errors, but that are to be allowed
+# in a limited (not transitive) context.  List of (file_name, symbol)
+# TODO: Move this data to dependencies.txt?
+allowed_errors = (
+  ("common/umutex.o", "operator new(unsigned long)"),
+  ("common/umutex.o", "std::__throw_bad_alloc()"),
+  ("common/umutex.o", "std::__throw_system_error(int)"),
+  ("common/umutex.o", "std::uncaught_exception()"),
+)
+
 def _Resolve(name, parents):
   global _ignored_symbols, _obj_files, _symbols_to_files, _return_value
   item = dependencies.items[name]
@@ -130,6 +143,9 @@ def _Resolve(name, parents):
   imports -= exports | system_symbols
   for symbol in imports:
     for file_name in files:
+      if (file_name, symbol) in allowed_errors:
+         sys.stderr.write("Info:  ignoring %s imports %s\n\n" % (file_name, symbol))
+         continue
       if symbol in _obj_files[file_name]["imports"]:
         neededFile = _symbols_to_files.get(symbol)
         if neededFile in dependencies.file_to_item:
@@ -138,7 +154,7 @@ def _Resolve(name, parents):
           neededItem = "- is this a new system symbol?"
         sys.stderr.write("Error: in %s %s: %s imports %s %s\n" %
                          (item_type, name, file_name, symbol, neededItem))
-    _return_value = 1
+        _return_value = 1
   del parents[-1]
   return item