]> git.saurik.com Git - apple/icu.git/blobdiff - icuSources/common/unifiedcache.cpp
ICU-66108.tar.gz
[apple/icu.git] / icuSources / common / unifiedcache.cpp
index 58abcfdd3b4f8eeeafa04868baacfd70e5ba2dff..f2dd916559588cc83e42ecf359726a355a3bc696 100644 (file)
 #include "ucln_cmn.h"
 
 static icu::UnifiedCache *gCache = NULL;
-static std::mutex &gCacheMutex() {
-    static std::mutex *m = STATIC_NEW(std::mutex);
-    return *m;
-}
-static std::condition_variable &gInProgressValueAddedCond() {
-    static std::condition_variable *cv = STATIC_NEW(std::condition_variable);
-    return *cv;
-}
+static std::mutex *gCacheMutex = nullptr;
+static std::condition_variable *gInProgressValueAddedCond;
 static icu::UInitOnce gCacheInitOnce = U_INITONCE_INITIALIZER;
 
 static const int32_t MAX_EVICT_ITERATIONS = 10;
@@ -38,10 +32,12 @@ static const int32_t DEFAULT_PERCENTAGE_OF_IN_USE = 100;
 U_CDECL_BEGIN
 static UBool U_CALLCONV unifiedcache_cleanup() {
     gCacheInitOnce.reset();
-    if (gCache) {
-        delete gCache;
-        gCache = NULL;
-    }
+    delete gCache;
+    gCache = nullptr;
+    gCacheMutex->~mutex();
+    gCacheMutex = nullptr;
+    gInProgressValueAddedCond->~condition_variable();
+    gInProgressValueAddedCond = nullptr;
     return TRUE;
 }
 U_CDECL_END
@@ -76,6 +72,8 @@ static void U_CALLCONV cacheInit(UErrorCode &status) {
     ucln_common_registerCleanup(
             UCLN_COMMON_UNIFIED_CACHE, unifiedcache_cleanup);
 
+    gCacheMutex = STATIC_NEW(std::mutex);
+    gInProgressValueAddedCond = STATIC_NEW(std::condition_variable);
     gCache = new UnifiedCache(status);
     if (gCache == NULL) {
         status = U_MEMORY_ALLOCATION_ERROR;
@@ -137,28 +135,28 @@ void UnifiedCache::setEvictionPolicy(
         status = U_ILLEGAL_ARGUMENT_ERROR;
         return;
     }
-    std::lock_guard<std::mutex> lock(gCacheMutex());
+    std::lock_guard<std::mutex> lock(*gCacheMutex);
     fMaxUnused = count;
     fMaxPercentageOfInUse = percentageOfInUseItems;
 }
 
 int32_t UnifiedCache::unusedCount() const {
-    std::lock_guard<std::mutex> lock(gCacheMutex());
+    std::lock_guard<std::mutex> lock(*gCacheMutex);
     return uhash_count(fHashtable) - fNumValuesInUse;
 }
 
 int64_t UnifiedCache::autoEvictedCount() const {
-    std::lock_guard<std::mutex> lock(gCacheMutex());
+    std::lock_guard<std::mutex> lock(*gCacheMutex);
     return fAutoEvictedCount;
 }
 
 int32_t UnifiedCache::keyCount() const {
-    std::lock_guard<std::mutex> lock(gCacheMutex());
+    std::lock_guard<std::mutex> lock(*gCacheMutex);
     return uhash_count(fHashtable);
 }
 
 void UnifiedCache::flush() const {
-    std::lock_guard<std::mutex> lock(gCacheMutex());
+    std::lock_guard<std::mutex> lock(*gCacheMutex);
 
     // Use a loop in case cache items that are flushed held hard references to
     // other cache items making those additional cache items eligible for
@@ -167,7 +165,7 @@ void UnifiedCache::flush() const {
 }
 
 void UnifiedCache::handleUnreferencedObject() const {
-    std::lock_guard<std::mutex> lock(gCacheMutex());
+    std::lock_guard<std::mutex> lock(*gCacheMutex);
     --fNumValuesInUse;
     _runEvictionSlice();
 }
@@ -186,7 +184,7 @@ void UnifiedCache::dump() {
 }
 
 void UnifiedCache::dumpContents() const {
-    std::lock_guard<std::mutex> lock(gCacheMutex());
+    std::lock_guard<std::mutex> lock(*gCacheMutex);
     _dumpContents();
 }
 
@@ -226,7 +224,7 @@ UnifiedCache::~UnifiedCache() {
         // Now all that should be left in the cache are entries that refer to
         // each other and entries with hard references from outside the cache.
         // Nothing we can do about these so proceed to wipe out the cache.
-        std::lock_guard<std::mutex> lock(gCacheMutex());
+        std::lock_guard<std::mutex> lock(*gCacheMutex);
         _flush(TRUE);
     }
     uhash_close(fHashtable);
@@ -327,7 +325,7 @@ void UnifiedCache::_putIfAbsentAndGet(
         const CacheKeyBase &key,
         const SharedObject *&value,
         UErrorCode &status) const {
-    std::lock_guard<std::mutex> lock(gCacheMutex());
+    std::lock_guard<std::mutex> lock(*gCacheMutex);
     const UHashElement *element = uhash_find(fHashtable, &key);
     if (element != NULL && !_inProgress(element)) {
         _fetch(element, value, status);
@@ -352,15 +350,15 @@ UBool UnifiedCache::_poll(
         UErrorCode &status) const {
     U_ASSERT(value == NULL);
     U_ASSERT(status == U_ZERO_ERROR);
-    std::unique_lock<std::mutex> lock(gCacheMutex());
+    std::unique_lock<std::mutex> lock(*gCacheMutex);
     const UHashElement *element = uhash_find(fHashtable, &key);
 
     // If the hash table contains an inProgress placeholder entry for this key,
     // this means that another thread is currently constructing the value object.
     // Loop, waiting for that construction to complete.
-    while (element != NULL && _inProgress(element)) {
-        gInProgressValueAddedCond().wait(lock);
-        element = uhash_find(fHashtable, &key);
+     while (element != NULL && _inProgress(element)) {
+         gInProgressValueAddedCond->wait(lock);
+         element = uhash_find(fHashtable, &key);
     }
 
     // If the hash table contains an entry for the key,
@@ -432,7 +430,7 @@ void UnifiedCache::_put(
 
     // Tell waiting threads that we replace in-progress status with
     // an error.
-    gInProgressValueAddedCond().notify_all();
+    gInProgressValueAddedCond->notify_all();
 }
 
 void UnifiedCache::_fetch(