#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;
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
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;
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
}
void UnifiedCache::handleUnreferencedObject() const {
- std::lock_guard<std::mutex> lock(gCacheMutex());
+ std::lock_guard<std::mutex> lock(*gCacheMutex);
--fNumValuesInUse;
_runEvictionSlice();
}
}
void UnifiedCache::dumpContents() const {
- std::lock_guard<std::mutex> lock(gCacheMutex());
+ std::lock_guard<std::mutex> lock(*gCacheMutex);
_dumpContents();
}
// 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);
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);
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,
// Tell waiting threads that we replace in-progress status with
// an error.
- gInProgressValueAddedCond().notify_all();
+ gInProgressValueAddedCond->notify_all();
}
void UnifiedCache::_fetch(