X-Git-Url: https://git.saurik.com/apple/icu.git/blobdiff_plain/a01113dcd0f39d5da295ef82785beff9ed86fe38..refs/heads/master:/icuSources/common/unifiedcache.cpp?ds=sidebyside diff --git a/icuSources/common/unifiedcache.cpp b/icuSources/common/unifiedcache.cpp index 58abcfdd..f2dd9165 100644 --- a/icuSources/common/unifiedcache.cpp +++ b/icuSources/common/unifiedcache.cpp @@ -20,14 +20,8 @@ #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 lock(gCacheMutex()); + std::lock_guard lock(*gCacheMutex); fMaxUnused = count; fMaxPercentageOfInUse = percentageOfInUseItems; } int32_t UnifiedCache::unusedCount() const { - std::lock_guard lock(gCacheMutex()); + std::lock_guard lock(*gCacheMutex); return uhash_count(fHashtable) - fNumValuesInUse; } int64_t UnifiedCache::autoEvictedCount() const { - std::lock_guard lock(gCacheMutex()); + std::lock_guard lock(*gCacheMutex); return fAutoEvictedCount; } int32_t UnifiedCache::keyCount() const { - std::lock_guard lock(gCacheMutex()); + std::lock_guard lock(*gCacheMutex); return uhash_count(fHashtable); } void UnifiedCache::flush() const { - std::lock_guard lock(gCacheMutex()); + std::lock_guard 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 lock(gCacheMutex()); + std::lock_guard lock(*gCacheMutex); --fNumValuesInUse; _runEvictionSlice(); } @@ -186,7 +184,7 @@ void UnifiedCache::dump() { } void UnifiedCache::dumpContents() const { - std::lock_guard lock(gCacheMutex()); + std::lock_guard 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 lock(gCacheMutex()); + std::lock_guard 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 lock(gCacheMutex()); + std::lock_guard 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 lock(gCacheMutex()); + std::unique_lock 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(