ICU-20488 mutex static constructor fixes.

Remove the dependencies from the ICU library code on static constructors
that were introduced by using std::mutex and condition variables. The
mutexes are lazily initialized by embedding them as local static variables
in getter functions, and relying on the C++ compiler/runtime to do thread
safe initialization of them.
This commit is contained in:
Andy Heninger 2019-03-11 16:36:33 -07:00
parent ffd8baf16d
commit bc4bb89af2
38 changed files with 345 additions and 255 deletions

View File

@ -124,13 +124,12 @@ static void U_CALLCONV _deleteEngine(void *obj) {
U_CDECL_END
U_NAMESPACE_BEGIN
static UMutex gBreakEngineMutex = U_MUTEX_INITIALIZER;
const LanguageBreakEngine *
ICULanguageBreakFactory::getEngineFor(UChar32 c) {
const LanguageBreakEngine *lbe = NULL;
UErrorCode status = U_ZERO_ERROR;
static UMutex gBreakEngineMutex = U_MUTEX_INITIALIZER;
Mutex m(&gBreakEngineMutex);
if (fEngines == NULL) {

View File

@ -47,7 +47,10 @@ UnicodeSet *sets[UCHAR_BINARY_LIMIT] = {};
UCPMap *maps[UCHAR_INT_LIMIT - UCHAR_INT_START] = {};
icu::UMutex cpMutex = U_MUTEX_INITIALIZER;
icu::UMutex *cpMutex() {
static icu::UMutex m = U_MUTEX_INITIALIZER;
return &m;
}
//----------------------------------------------------------------
// Inclusions list
@ -358,7 +361,7 @@ u_getBinaryPropertySet(UProperty property, UErrorCode *pErrorCode) {
*pErrorCode = U_ILLEGAL_ARGUMENT_ERROR;
return nullptr;
}
Mutex m(&cpMutex);
Mutex m(cpMutex());
UnicodeSet *set = sets[property];
if (set == nullptr) {
sets[property] = set = makeSet(property, *pErrorCode);
@ -374,7 +377,7 @@ u_getIntPropertyMap(UProperty property, UErrorCode *pErrorCode) {
*pErrorCode = U_ILLEGAL_ARGUMENT_ERROR;
return nullptr;
}
Mutex m(&cpMutex);
Mutex m(cpMutex());
UCPMap *map = maps[property - UCHAR_INT_START];
if (map == nullptr) {
maps[property - UCHAR_INT_START] = map = makeMap(property, *pErrorCode);

View File

@ -286,7 +286,6 @@ class LocaleDisplayNamesImpl : public LocaleDisplayNames {
#else
UObject* capitalizationBrkIter;
#endif
static UMutex capitalizationBrkIterLock;
UnicodeString formatOpenParen;
UnicodeString formatReplaceOpenParen;
UnicodeString formatCloseParen;
@ -352,8 +351,6 @@ private:
struct CapitalizationContextSink;
};
UMutex LocaleDisplayNamesImpl::capitalizationBrkIterLock = U_MUTEX_INITIALIZER;
LocaleDisplayNamesImpl::LocaleDisplayNamesImpl(const Locale& locale,
UDialectHandling dialectHandling)
: dialectHandling(dialectHandling)
@ -552,6 +549,7 @@ LocaleDisplayNamesImpl::adjustForUsageAndContext(CapContextUsage usage,
if ( result.length() > 0 && u_islower(result.char32At(0)) && capitalizationBrkIter!= NULL &&
( capitalizationContext==UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE || fCapitalization[usage] ) ) {
// note fCapitalization[usage] won't be set unless capitalizationContext is UI_LIST_OR_MENU or STANDALONE
static UMutex capitalizationBrkIterLock = U_MUTEX_INITIALIZER;
Mutex lock(&capitalizationBrkIterLock);
result.toTitle(capitalizationBrkIter, locale, U_TITLECASE_NO_LOWERCASE | U_TITLECASE_NO_BREAK_ADJUSTMENT);
}

View File

@ -62,7 +62,10 @@ static Locale *gLocaleCache = NULL;
static UInitOnce gLocaleCacheInitOnce = U_INITONCE_INITIALIZER;
// gDefaultLocaleMutex protects all access to gDefaultLocalesHashT and gDefaultLocale.
static UMutex gDefaultLocaleMutex = U_MUTEX_INITIALIZER;
static UMutex *gDefaultLocaleMutex() {
static UMutex m = U_MUTEX_INITIALIZER;
return &m;
}
static UHashtable *gDefaultLocalesHashT = NULL;
static Locale *gDefaultLocale = NULL;
@ -171,7 +174,7 @@ U_NAMESPACE_BEGIN
Locale *locale_set_default_internal(const char *id, UErrorCode& status) {
// Synchronize this entire function.
Mutex lock(&gDefaultLocaleMutex);
Mutex lock(gDefaultLocaleMutex());
UBool canonicalize = FALSE;
@ -708,7 +711,7 @@ const Locale& U_EXPORT2
Locale::getDefault()
{
{
Mutex lock(&gDefaultLocaleMutex);
Mutex lock(gDefaultLocaleMutex());
if (gDefaultLocale != NULL) {
return *gDefaultLocale;
}

View File

@ -241,7 +241,6 @@ u_signBit(double d) {
UDate fakeClock_t0 = 0; /** Time to start the clock from **/
UDate fakeClock_dt = 0; /** Offset (fake time - real time) **/
UBool fakeClock_set = FALSE; /** True if fake clock has spun up **/
static UMutex fakeClockMutex = U_MUTEX_INTIALIZER;
static UDate getUTCtime_real() {
struct timeval posixTime;
@ -250,6 +249,7 @@ static UDate getUTCtime_real() {
}
static UDate getUTCtime_fake() {
static UMutex fakeClockMutex = U_MUTEX_INTIALIZER;
umtx_lock(&fakeClockMutex);
if(!fakeClock_set) {
UDate real = getUTCtime_real();

View File

@ -376,8 +376,8 @@ void ResourceBundle::getVersion(UVersionInfo versionInfo) const {
ures_getVersion(fResource, versionInfo);
}
static UMutex gLocaleLock = U_MUTEX_INITIALIZER;
const Locale &ResourceBundle::getLocale(void) const {
static UMutex gLocaleLock = U_MUTEX_INITIALIZER;
Mutex lock(&gLocaleLock);
if (fLocale != NULL) {
return *fLocale;

View File

@ -333,7 +333,10 @@ U_CDECL_END
******************************************************************
*/
static UMutex lock = U_MUTEX_INITIALIZER;
static UMutex *lock() {
static UMutex m = U_MUTEX_INITIALIZER;
return &m;
}
ICUService::ICUService()
: name()
@ -358,7 +361,7 @@ ICUService::ICUService(const UnicodeString& newName)
ICUService::~ICUService()
{
{
Mutex mutex(&lock);
Mutex mutex(lock());
clearCaches();
delete factories;
factories = NULL;
@ -449,7 +452,7 @@ ICUService::getKey(ICUServiceKey& key, UnicodeString* actualReturn, const ICUSer
// if factory is not null, we're calling from within the mutex,
// and since some unix machines don't have reentrant mutexes we
// need to make sure not to try to lock it again.
XMutex mutex(&lock, factory != NULL);
XMutex mutex(lock(), factory != NULL);
if (serviceCache == NULL) {
ncthis->serviceCache = new Hashtable(status);
@ -615,7 +618,7 @@ ICUService::getVisibleIDs(UVector& result, const UnicodeString* matchID, UErrorC
}
{
Mutex mutex(&lock);
Mutex mutex(lock());
const Hashtable* map = getVisibleIDMap(status);
if (map != NULL) {
ICUServiceKey* fallbackKey = createKey(matchID, status);
@ -692,7 +695,7 @@ ICUService::getDisplayName(const UnicodeString& id, UnicodeString& result, const
{
{
UErrorCode status = U_ZERO_ERROR;
Mutex mutex(&lock);
Mutex mutex(lock());
const Hashtable* map = getVisibleIDMap(status);
if (map != NULL) {
ICUServiceFactory* f = (ICUServiceFactory*)map->get(id);
@ -744,7 +747,7 @@ ICUService::getDisplayNames(UVector& result,
result.setDeleter(userv_deleteStringPair);
if (U_SUCCESS(status)) {
ICUService* ncthis = (ICUService*)this; // cast away semantic const
Mutex mutex(&lock);
Mutex mutex(lock());
if (dnCache != NULL && dnCache->locale != locale) {
delete dnCache;
@ -849,7 +852,7 @@ URegistryKey
ICUService::registerFactory(ICUServiceFactory* factoryToAdopt, UErrorCode& status)
{
if (U_SUCCESS(status) && factoryToAdopt != NULL) {
Mutex mutex(&lock);
Mutex mutex(lock());
if (factories == NULL) {
factories = new UVector(deleteUObject, NULL, status);
@ -880,7 +883,7 @@ ICUService::unregister(URegistryKey rkey, UErrorCode& status)
ICUServiceFactory *factory = (ICUServiceFactory*)rkey;
UBool result = FALSE;
if (factory != NULL && factories != NULL) {
Mutex mutex(&lock);
Mutex mutex(lock());
if (factories->removeElement(factory)) {
clearCaches();
@ -900,7 +903,7 @@ void
ICUService::reset()
{
{
Mutex mutex(&lock);
Mutex mutex(lock());
reInitializeFactories();
clearCaches();
}

View File

@ -26,7 +26,6 @@
U_NAMESPACE_BEGIN
static UMutex llock = U_MUTEX_INITIALIZER;
ICULocaleService::ICULocaleService()
: fallbackLocale(Locale::getDefault())
{
@ -264,6 +263,7 @@ ICULocaleService::validateFallbackLocale() const
{
const Locale& loc = Locale::getDefault();
ICULocaleService* ncThis = (ICULocaleService*)this;
static UMutex llock = U_MUTEX_INITIALIZER;
{
Mutex mutex(&llock);
if (loc != fallbackLocale) {

View File

@ -21,7 +21,10 @@ U_NAMESPACE_BEGIN
EventListener::~EventListener() {}
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(EventListener)
static UMutex notifyLock = U_MUTEX_INITIALIZER;
static UMutex *notifyLock() {
static UMutex m = U_MUTEX_INITIALIZER;
return &m;
}
ICUNotifier::ICUNotifier(void)
: listeners(NULL)
@ -30,7 +33,7 @@ ICUNotifier::ICUNotifier(void)
ICUNotifier::~ICUNotifier(void) {
{
Mutex lmx(&notifyLock);
Mutex lmx(notifyLock());
delete listeners;
listeners = NULL;
}
@ -47,7 +50,7 @@ ICUNotifier::addListener(const EventListener* l, UErrorCode& status)
}
if (acceptsListener(*l)) {
Mutex lmx(&notifyLock);
Mutex lmx(notifyLock());
if (listeners == NULL) {
listeners = new UVector(5, status);
} else {
@ -80,7 +83,7 @@ ICUNotifier::removeListener(const EventListener *l, UErrorCode& status)
}
{
Mutex lmx(&notifyLock);
Mutex lmx(notifyLock());
if (listeners != NULL) {
// identity equality check
for (int i = 0, e = listeners->size(); i < e; ++i) {
@ -103,7 +106,7 @@ void
ICUNotifier::notifyChanged(void)
{
if (listeners != NULL) {
Mutex lmx(&notifyLock);
Mutex lmx(notifyLock());
if (listeners != NULL) {
for (int i = 0, e = listeners->size(); i < e; ++i) {
EventListener* el = (EventListener*)listeners->elementAt(i);

View File

@ -194,9 +194,12 @@ static struct {
/*initializes some global variables */
static UHashtable *SHARED_DATA_HASHTABLE = NULL;
static icu::UMutex cnvCacheMutex = U_MUTEX_INITIALIZER; /* Mutex for synchronizing cnv cache access. */
/* Note: the global mutex is used for */
/* reference count updates. */
static icu::UMutex *cnvCacheMutex() { /* Mutex for synchronizing cnv cache access. */
static icu::UMutex m = U_MUTEX_INITIALIZER;
return &m;
}
/* Note: the global mutex is used for */
/* reference count updates. */
static const char **gAvailableConverters = NULL;
static uint16_t gAvailableConverterCount = 0;
@ -599,9 +602,9 @@ U_CFUNC void
ucnv_unloadSharedDataIfReady(UConverterSharedData *sharedData)
{
if(sharedData != NULL && sharedData->isReferenceCounted) {
umtx_lock(&cnvCacheMutex);
umtx_lock(cnvCacheMutex());
ucnv_unload(sharedData);
umtx_unlock(&cnvCacheMutex);
umtx_unlock(cnvCacheMutex());
}
}
@ -609,9 +612,9 @@ U_CFUNC void
ucnv_incrementRefCount(UConverterSharedData *sharedData)
{
if(sharedData != NULL && sharedData->isReferenceCounted) {
umtx_lock(&cnvCacheMutex);
umtx_lock(cnvCacheMutex());
sharedData->referenceCounter++;
umtx_unlock(&cnvCacheMutex);
umtx_unlock(cnvCacheMutex());
}
}
@ -812,9 +815,9 @@ ucnv_loadSharedData(const char *converterName,
pArgs->nestedLoads=1;
pArgs->pkg=NULL;
umtx_lock(&cnvCacheMutex);
umtx_lock(cnvCacheMutex());
mySharedConverterData = ucnv_load(pArgs, err);
umtx_unlock(&cnvCacheMutex);
umtx_unlock(cnvCacheMutex());
if (U_FAILURE (*err) || (mySharedConverterData == NULL))
{
return NULL;
@ -1061,7 +1064,7 @@ ucnv_flushCache ()
* because the sequence of looking up in the cache + incrementing
* is protected by cnvCacheMutex.
*/
umtx_lock(&cnvCacheMutex);
umtx_lock(cnvCacheMutex());
/*
* double loop: A delta/extension-only converter has a pointer to its base table's
* shared data; the first iteration of the outer loop may see the delta converter
@ -1090,7 +1093,7 @@ ucnv_flushCache ()
}
}
} while(++i == 1 && remaining > 0);
umtx_unlock(&cnvCacheMutex);
umtx_unlock(cnvCacheMutex());
UTRACE_DATA1(UTRACE_INFO, "ucnv_flushCache() exits with %d converters remaining", remaining);
@ -1196,7 +1199,7 @@ internalSetName(const char *name, UErrorCode *status) {
}
algorithmicSharedData = getAlgorithmicTypeFromName(stackArgs.name);
umtx_lock(&cnvCacheMutex);
umtx_lock(cnvCacheMutex());
gDefaultAlgorithmicSharedData = algorithmicSharedData;
gDefaultConverterContainsOption = containsOption;
@ -1212,7 +1215,7 @@ internalSetName(const char *name, UErrorCode *status) {
ucnv_enableCleanup();
umtx_unlock(&cnvCacheMutex);
umtx_unlock(cnvCacheMutex());
}
#endif
@ -1237,7 +1240,7 @@ ucnv_getDefaultName() {
but ucnv_setDefaultName is not thread safe.
*/
{
icu::Mutex lock(&cnvCacheMutex);
icu::Mutex lock(cnvCacheMutex());
name = gDefaultConverterName;
}
if(name==NULL) {

View File

@ -365,7 +365,10 @@ U_CDECL_END
#if !UCONFIG_NO_SERVICE
struct CReg;
static UMutex gCRegLock = U_MUTEX_INITIALIZER;
static UMutex *gCRegLock() {
static UMutex m = U_MUTEX_INITIALIZER;
return &m;
}
static CReg* gCRegHead = 0;
struct CReg : public icu::UMemory {
@ -391,14 +394,14 @@ struct CReg : public icu::UMemory {
if (status && U_SUCCESS(*status) && _iso && _id) {
CReg* n = new CReg(_iso, _id);
if (n) {
umtx_lock(&gCRegLock);
umtx_lock(gCRegLock());
if (!gCRegHead) {
/* register for the first time */
ucln_common_registerCleanup(UCLN_COMMON_CURRENCY, currency_cleanup);
}
n->next = gCRegHead;
gCRegHead = n;
umtx_unlock(&gCRegLock);
umtx_unlock(gCRegLock());
return n;
}
*status = U_MEMORY_ALLOCATION_ERROR;
@ -408,7 +411,7 @@ struct CReg : public icu::UMemory {
static UBool unreg(UCurrRegistryKey key) {
UBool found = FALSE;
umtx_lock(&gCRegLock);
umtx_lock(gCRegLock());
CReg** p = &gCRegHead;
while (*p) {
@ -421,13 +424,13 @@ struct CReg : public icu::UMemory {
p = &((*p)->next);
}
umtx_unlock(&gCRegLock);
umtx_unlock(gCRegLock());
return found;
}
static const UChar* get(const char* id) {
const UChar* result = NULL;
umtx_lock(&gCRegLock);
umtx_lock(gCRegLock());
CReg* p = gCRegHead;
/* register cleanup of the mutex */
@ -439,7 +442,7 @@ struct CReg : public icu::UMemory {
}
p = p->next;
}
umtx_unlock(&gCRegLock);
umtx_unlock(gCRegLock());
return result;
}
@ -1353,7 +1356,10 @@ static CurrencyNameCacheEntry* currCache[CURRENCY_NAME_CACHE_NUM] = {NULL};
// It is a simple round-robin replacement strategy.
static int8_t currentCacheEntryIndex = 0;
static UMutex gCurrencyCacheMutex = U_MUTEX_INITIALIZER;
static UMutex *gCurrencyCacheMutex() {
static UMutex m = U_MUTEX_INITIALIZER;
return &m;
}
// Cache deletion
static void
@ -1402,7 +1408,7 @@ getCacheEntry(const char* locale, UErrorCode& ec) {
CurrencyNameStruct* currencySymbols = NULL;
CurrencyNameCacheEntry* cacheEntry = NULL;
umtx_lock(&gCurrencyCacheMutex);
umtx_lock(gCurrencyCacheMutex());
// in order to handle racing correctly,
// not putting 'search' in a separate function.
int8_t found = -1;
@ -1417,13 +1423,13 @@ getCacheEntry(const char* locale, UErrorCode& ec) {
cacheEntry = currCache[found];
++(cacheEntry->refCount);
}
umtx_unlock(&gCurrencyCacheMutex);
umtx_unlock(gCurrencyCacheMutex());
if (found == -1) {
collectCurrencyNames(locale, &currencyNames, &total_currency_name_count, &currencySymbols, &total_currency_symbol_count, ec);
if (U_FAILURE(ec)) {
return NULL;
}
umtx_lock(&gCurrencyCacheMutex);
umtx_lock(gCurrencyCacheMutex());
// check again.
for (int8_t i = 0; i < CURRENCY_NAME_CACHE_NUM; ++i) {
if (currCache[i]!= NULL &&
@ -1462,19 +1468,19 @@ getCacheEntry(const char* locale, UErrorCode& ec) {
cacheEntry = currCache[found];
++(cacheEntry->refCount);
}
umtx_unlock(&gCurrencyCacheMutex);
umtx_unlock(gCurrencyCacheMutex());
}
return cacheEntry;
}
static void releaseCacheEntry(CurrencyNameCacheEntry* cacheEntry) {
umtx_lock(&gCurrencyCacheMutex);
umtx_lock(gCurrencyCacheMutex());
--(cacheEntry->refCount);
if (cacheEntry->refCount == 0) { // remove
deleteCacheEntry(cacheEntry);
}
umtx_unlock(&gCurrencyCacheMutex);
umtx_unlock(gCurrencyCacheMutex());
}
U_CAPI void

View File

@ -42,12 +42,15 @@ U_NAMESPACE_BEGIN
*************************************************************************************************/
// The ICU global mutex. Used when ICU implementation code passes NULL for the mutex pointer.
static UMutex globalMutex = U_MUTEX_INITIALIZER;
static UMutex *globalMutex() {
static UMutex m = U_MUTEX_INITIALIZER;
return &m;
}
U_CAPI void U_EXPORT2
umtx_lock(UMutex *mutex) {
if (mutex == nullptr) {
mutex = &globalMutex;
mutex = globalMutex();
}
mutex->fMutex.lock();
}
@ -57,7 +60,7 @@ U_CAPI void U_EXPORT2
umtx_unlock(UMutex* mutex)
{
if (mutex == nullptr) {
mutex = &globalMutex;
mutex = globalMutex();
}
mutex->fMutex.unlock();
}
@ -71,7 +74,7 @@ UConditionVar::~UConditionVar() {
U_CAPI void U_EXPORT2
umtx_condWait(UConditionVar *cond, UMutex *mutex) {
if (mutex == nullptr) {
mutex = &globalMutex;
mutex = globalMutex();
}
cond->fCV.wait(mutex->fMutex);
}
@ -95,8 +98,15 @@ umtx_condSignal(UConditionVar *cond) {
*
*************************************************************************************************/
static std::mutex initMutex;
static std::condition_variable initCondition;
static std::mutex &initMutex() {
static std::mutex m;
return m;
}
static std::condition_variable &initCondition() {
static std::condition_variable cv;
return cv;
}
// This function is called when a test of a UInitOnce::fState reveals that
@ -109,7 +119,7 @@ static std::condition_variable initCondition;
//
U_COMMON_API UBool U_EXPORT2
umtx_initImplPreInit(UInitOnce &uio) {
std::unique_lock<std::mutex> lock(initMutex);
std::unique_lock<std::mutex> lock(initMutex());
if (umtx_loadAcquire(uio.fState) == 0) {
umtx_storeRelease(uio.fState, 1);
@ -118,7 +128,7 @@ umtx_initImplPreInit(UInitOnce &uio) {
while (umtx_loadAcquire(uio.fState) == 1) {
// Another thread is currently running the initialization.
// Wait until it completes.
initCondition.wait(lock);
initCondition().wait(lock);
}
U_ASSERT(uio.fState == 2);
return false;
@ -135,10 +145,10 @@ umtx_initImplPreInit(UInitOnce &uio) {
U_COMMON_API void U_EXPORT2
umtx_initImplPostInit(UInitOnce &uio) {
{
std::unique_lock<std::mutex> lock(initMutex);
std::unique_lock<std::mutex> lock(initMutex());
umtx_storeRelease(uio.fState, 2);
}
initCondition.notify_all();
initCondition().notify_all();
}
U_NAMESPACE_END

View File

@ -21,8 +21,14 @@
#include "umutex.h"
static icu::UnifiedCache *gCache = NULL;
static icu::UMutex gCacheMutex = U_MUTEX_INITIALIZER;
static icu::UConditionVar gInProgressValueAddedCond = U_CONDITION_INITIALIZER;
static icu::UMutex *gCacheMutex() {
static icu::UMutex m = U_MUTEX_INITIALIZER;
return &m;
}
static icu::UConditionVar *gInProgressValueAddedCond() {
static icu::UConditionVar cv = U_CONDITION_INITIALIZER;
return &cv;
}
static icu::UInitOnce gCacheInitOnce = U_INITONCE_INITIALIZER;
static const int32_t MAX_EVICT_ITERATIONS = 10;
@ -132,28 +138,28 @@ void UnifiedCache::setEvictionPolicy(
status = U_ILLEGAL_ARGUMENT_ERROR;
return;
}
Mutex lock(&gCacheMutex);
Mutex lock(gCacheMutex());
fMaxUnused = count;
fMaxPercentageOfInUse = percentageOfInUseItems;
}
int32_t UnifiedCache::unusedCount() const {
Mutex lock(&gCacheMutex);
Mutex lock(gCacheMutex());
return uhash_count(fHashtable) - fNumValuesInUse;
}
int64_t UnifiedCache::autoEvictedCount() const {
Mutex lock(&gCacheMutex);
Mutex lock(gCacheMutex());
return fAutoEvictedCount;
}
int32_t UnifiedCache::keyCount() const {
Mutex lock(&gCacheMutex);
Mutex lock(gCacheMutex());
return uhash_count(fHashtable);
}
void UnifiedCache::flush() const {
Mutex lock(&gCacheMutex);
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
@ -162,7 +168,7 @@ void UnifiedCache::flush() const {
}
void UnifiedCache::handleUnreferencedObject() const {
Mutex lock(&gCacheMutex);
Mutex lock(gCacheMutex());
--fNumValuesInUse;
_runEvictionSlice();
}
@ -181,7 +187,7 @@ void UnifiedCache::dump() {
}
void UnifiedCache::dumpContents() const {
Mutex lock(&gCacheMutex);
Mutex lock(gCacheMutex());
_dumpContents();
}
@ -221,7 +227,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.
Mutex lock(&gCacheMutex);
Mutex lock(gCacheMutex());
_flush(TRUE);
}
uhash_close(fHashtable);
@ -322,7 +328,7 @@ void UnifiedCache::_putIfAbsentAndGet(
const CacheKeyBase &key,
const SharedObject *&value,
UErrorCode &status) const {
Mutex lock(&gCacheMutex);
Mutex lock(gCacheMutex());
const UHashElement *element = uhash_find(fHashtable, &key);
if (element != NULL && !_inProgress(element)) {
_fetch(element, value, status);
@ -347,14 +353,14 @@ UBool UnifiedCache::_poll(
UErrorCode &status) const {
U_ASSERT(value == NULL);
U_ASSERT(status == U_ZERO_ERROR);
Mutex lock(&gCacheMutex);
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)) {
umtx_condWait(&gInProgressValueAddedCond, &gCacheMutex);
umtx_condWait(gInProgressValueAddedCond(), gCacheMutex());
element = uhash_find(fHashtable, &key);
}
@ -427,7 +433,7 @@ void UnifiedCache::_put(
// Tell waiting threads that we replace in-progress status with
// an error.
umtx_condBroadcast(&gInProgressValueAddedCond);
umtx_condBroadcast(gInProgressValueAddedCond());
}
void UnifiedCache::_fetch(

View File

@ -49,7 +49,10 @@ TODO: This cache should probably be removed when the deprecated code is
static UHashtable *cache = NULL;
static icu::UInitOnce gCacheInitOnce;
static UMutex resbMutex = U_MUTEX_INITIALIZER;
static UMutex *resbMutex() {
static UMutex m = U_MUTEX_INITIALIZER;
return &m;
}
/* INTERNAL: hashes an entry */
static int32_t U_CALLCONV hashEntry(const UHashTok parm) {
@ -93,13 +96,13 @@ static UBool chopLocale(char *name) {
* Internal function
*/
static void entryIncrease(UResourceDataEntry *entry) {
umtx_lock(&resbMutex);
umtx_lock(resbMutex());
entry->fCountExisting++;
while(entry->fParent != NULL) {
entry = entry->fParent;
entry->fCountExisting++;
}
umtx_unlock(&resbMutex);
umtx_unlock(resbMutex());
}
/**
@ -181,9 +184,9 @@ static int32_t ures_flushCache()
/*if shared data hasn't even been lazy evaluated yet
* return 0
*/
umtx_lock(&resbMutex);
umtx_lock(resbMutex());
if (cache == NULL) {
umtx_unlock(&resbMutex);
umtx_unlock(resbMutex());
return 0;
}
@ -215,7 +218,7 @@ static int32_t ures_flushCache()
* got decremented by free_entry().
*/
} while(deletedMore);
umtx_unlock(&resbMutex);
umtx_unlock(resbMutex());
return rbDeletedNum;
}
@ -229,9 +232,9 @@ U_CAPI UBool U_EXPORT2 ures_dumpCacheContents(void) {
const UHashElement *e;
UResourceDataEntry *resB;
umtx_lock(&resbMutex);
umtx_lock(resbMutex());
if (cache == NULL) {
umtx_unlock(&resbMutex);
umtx_unlock(resbMutex());
fprintf(stderr,"%s:%d: RB Cache is NULL.\n", __FILE__, __LINE__);
return FALSE;
}
@ -251,7 +254,7 @@ U_CAPI UBool U_EXPORT2 ures_dumpCacheContents(void) {
fprintf(stderr,"%s:%d: RB Cache still contains %d items.\n", __FILE__, __LINE__, uhash_count(cache));
umtx_unlock(&resbMutex);
umtx_unlock(resbMutex());
return cacheNotEmpty;
}
@ -663,7 +666,7 @@ static UResourceDataEntry *entryOpen(const char* path, const char* localeID,
}
}
umtx_lock(&resbMutex);
umtx_lock(resbMutex());
{ /* umtx_lock */
/* We're going to skip all the locales that do not have any data */
r = findFirstExisting(path, name, &isRoot, &hasChopped, &isDefault, &intStatus);
@ -762,7 +765,7 @@ static UResourceDataEntry *entryOpen(const char* path, const char* localeID,
}
} /* umtx_lock */
finishUnlock:
umtx_unlock(&resbMutex);
umtx_unlock(resbMutex());
if(U_SUCCESS(*status)) {
if(intStatus != U_ZERO_ERROR) {
@ -787,7 +790,7 @@ entryOpenDirect(const char* path, const char* localeID, UErrorCode* status) {
return NULL;
}
umtx_lock(&resbMutex);
umtx_lock(resbMutex());
// findFirstExisting() without fallbacks.
UResourceDataEntry *r = init_entry(localeID, path, status);
if(U_SUCCESS(*status)) {
@ -825,7 +828,7 @@ entryOpenDirect(const char* path, const char* localeID, UErrorCode* status) {
t1 = t1->fParent;
}
}
umtx_unlock(&resbMutex);
umtx_unlock(resbMutex());
return r;
}
@ -868,9 +871,9 @@ static void entryCloseInt(UResourceDataEntry *resB) {
*/
static void entryClose(UResourceDataEntry *resB) {
umtx_lock(&resbMutex);
umtx_lock(resbMutex());
entryCloseInt(resB);
umtx_unlock(&resbMutex);
umtx_unlock(resbMutex());
}
/*

View File

@ -47,7 +47,10 @@ Static cache for already opened StringPrep profiles
static UHashtable *SHARED_DATA_HASHTABLE = NULL;
static icu::UInitOnce gSharedDataInitOnce;
static UMutex usprepMutex = U_MUTEX_INITIALIZER;
static UMutex *usprepMutex() {
static UMutex m = U_MUTEX_INITIALIZER;
return &m;
}
/* format version of spp file */
//static uint8_t formatVersion[4]={ 0, 0, 0, 0 };
@ -148,9 +151,9 @@ usprep_internal_flushCache(UBool noRefCount){
* if shared data hasn't even been lazy evaluated yet
* return 0
*/
umtx_lock(&usprepMutex);
umtx_lock(usprepMutex());
if (SHARED_DATA_HASHTABLE == NULL) {
umtx_unlock(&usprepMutex);
umtx_unlock(usprepMutex());
return 0;
}
@ -181,7 +184,7 @@ usprep_internal_flushCache(UBool noRefCount){
}
}
umtx_unlock(&usprepMutex);
umtx_unlock(usprepMutex());
return deletedNum;
}
@ -259,7 +262,7 @@ loadData(UStringPrepProfile* profile,
}
/* in the mutex block, set the data for this process */
umtx_lock(&usprepMutex);
umtx_lock(usprepMutex());
if(profile->sprepData==NULL) {
profile->sprepData=dataMemory;
dataMemory=NULL;
@ -268,7 +271,7 @@ loadData(UStringPrepProfile* profile,
} else {
p=(const int32_t *)udata_getMemory(profile->sprepData);
}
umtx_unlock(&usprepMutex);
umtx_unlock(usprepMutex());
/* initialize some variables */
profile->mappingData=(uint16_t *)((uint8_t *)(p+_SPREP_INDEX_TOP)+profile->indexes[_SPREP_INDEX_TRIE_SIZE]);
@ -325,12 +328,12 @@ usprep_getProfile(const char* path,
stackKey.path = (char*) path;
/* fetch the data from the cache */
umtx_lock(&usprepMutex);
umtx_lock(usprepMutex());
profile = (UStringPrepProfile*) (uhash_get(SHARED_DATA_HASHTABLE,&stackKey));
if(profile != NULL) {
profile->refCount++;
}
umtx_unlock(&usprepMutex);
umtx_unlock(usprepMutex());
if(profile == NULL) {
/* else load the data and put the data in the cache */
@ -362,7 +365,7 @@ usprep_getProfile(const char* path,
return NULL;
}
umtx_lock(&usprepMutex);
umtx_lock(usprepMutex());
// If another thread already inserted the same key/value, refcount and cleanup our thread data
profile = (UStringPrepProfile*) (uhash_get(SHARED_DATA_HASHTABLE,&stackKey));
if(profile != NULL) {
@ -383,7 +386,7 @@ usprep_getProfile(const char* path,
profile->refCount = 1;
uhash_put(SHARED_DATA_HASHTABLE, key.orphan(), profile, status);
}
umtx_unlock(&usprepMutex);
umtx_unlock(usprepMutex());
}
return profile;
@ -422,12 +425,12 @@ usprep_close(UStringPrepProfile* profile){
return;
}
umtx_lock(&usprepMutex);
umtx_lock(usprepMutex());
/* decrement the ref count*/
if(profile->refCount > 0){
profile->refCount--;
}
umtx_unlock(&usprepMutex);
umtx_unlock(usprepMutex());
}

View File

@ -65,7 +65,10 @@ static inline UBool isINVALID(double d) {
return(uprv_isNaN(d));
}
static icu::UMutex ccLock = U_MUTEX_INITIALIZER;
static icu::UMutex *ccLock() {
static icu::UMutex m = U_MUTEX_INITIALIZER;
return &m;
}
U_CDECL_BEGIN
static UBool calendar_astro_cleanup(void) {
@ -1549,12 +1552,12 @@ int32_t CalendarCache::get(CalendarCache** cache, int32_t key, UErrorCode &statu
if(U_FAILURE(status)) {
return 0;
}
umtx_lock(&ccLock);
umtx_lock(ccLock());
if(*cache == NULL) {
createCache(cache, status);
if(U_FAILURE(status)) {
umtx_unlock(&ccLock);
umtx_unlock(ccLock());
return 0;
}
}
@ -1562,7 +1565,7 @@ int32_t CalendarCache::get(CalendarCache** cache, int32_t key, UErrorCode &statu
res = uhash_igeti((*cache)->fTable, key);
U_DEBUG_ASTRO_MSG(("%p: GET: [%d] == %d\n", (*cache)->fTable, key, res));
umtx_unlock(&ccLock);
umtx_unlock(ccLock());
return res;
}
@ -1570,12 +1573,12 @@ void CalendarCache::put(CalendarCache** cache, int32_t key, int32_t value, UErro
if(U_FAILURE(status)) {
return;
}
umtx_lock(&ccLock);
umtx_lock(ccLock());
if(*cache == NULL) {
createCache(cache, status);
if(U_FAILURE(status)) {
umtx_unlock(&ccLock);
umtx_unlock(ccLock());
return;
}
}
@ -1583,7 +1586,7 @@ void CalendarCache::put(CalendarCache** cache, int32_t key, int32_t value, UErro
uhash_iputi((*cache)->fTable, key, value, &status);
U_DEBUG_ASTRO_MSG(("%p: PUT: [%d] := %d\n", (*cache)->fTable, key, value));
umtx_unlock(&ccLock);
umtx_unlock(ccLock());
}
CalendarCache::CalendarCache(int32_t size, UErrorCode &status) {

View File

@ -51,7 +51,10 @@ static void debug_chnsecal_msg(const char *pat, ...)
// --- The cache --
static icu::UMutex astroLock = U_MUTEX_INITIALIZER; // Protects access to gChineseCalendarAstro.
static icu::UMutex *astroLock() { // Protects access to gChineseCalendarAstro.
static icu::UMutex m = U_MUTEX_INITIALIZER;
return &m;
}
static icu::CalendarAstronomer *gChineseCalendarAstro = NULL;
// Lazy Creation & Access synchronized by class CalendarCache with a mutex.
@ -535,14 +538,14 @@ int32_t ChineseCalendar::winterSolstice(int32_t gyear) const {
// PST 1298 with a final result of Dec 14 10:31:59 PST 1299.
double ms = daysToMillis(Grego::fieldsToDay(gyear, UCAL_DECEMBER, 1));
umtx_lock(&astroLock);
umtx_lock(astroLock());
if(gChineseCalendarAstro == NULL) {
gChineseCalendarAstro = new CalendarAstronomer();
ucln_i18n_registerCleanup(UCLN_I18N_CHINESE_CALENDAR, calendar_chinese_cleanup);
}
gChineseCalendarAstro->setTime(ms);
UDate solarLong = gChineseCalendarAstro->getSunTime(CalendarAstronomer::WINTER_SOLSTICE(), TRUE);
umtx_unlock(&astroLock);
umtx_unlock(astroLock());
// Winter solstice is 270 degrees solar longitude aka Dongzhi
cacheValue = (int32_t)millisToDays(solarLong);
@ -565,14 +568,14 @@ int32_t ChineseCalendar::winterSolstice(int32_t gyear) const {
*/
int32_t ChineseCalendar::newMoonNear(double days, UBool after) const {
umtx_lock(&astroLock);
umtx_lock(astroLock());
if(gChineseCalendarAstro == NULL) {
gChineseCalendarAstro = new CalendarAstronomer();
ucln_i18n_registerCleanup(UCLN_I18N_CHINESE_CALENDAR, calendar_chinese_cleanup);
}
gChineseCalendarAstro->setTime(daysToMillis(days));
UDate newMoon = gChineseCalendarAstro->getMoonTime(CalendarAstronomer::NEW_MOON(), after);
umtx_unlock(&astroLock);
umtx_unlock(astroLock());
return (int32_t) millisToDays(newMoon);
}
@ -597,14 +600,14 @@ int32_t ChineseCalendar::synodicMonthsBetween(int32_t day1, int32_t day2) const
*/
int32_t ChineseCalendar::majorSolarTerm(int32_t days) const {
umtx_lock(&astroLock);
umtx_lock(astroLock());
if(gChineseCalendarAstro == NULL) {
gChineseCalendarAstro = new CalendarAstronomer();
ucln_i18n_registerCleanup(UCLN_I18N_CHINESE_CALENDAR, calendar_chinese_cleanup);
}
gChineseCalendarAstro->setTime(daysToMillis(days));
UDate solarLongitude = gChineseCalendarAstro->getSunLongitude();
umtx_unlock(&astroLock);
umtx_unlock(astroLock());
// Compute (floor(solarLongitude / (pi/6)) + 2) % 12
int32_t term = ( ((int32_t)(6 * solarLongitude / CalendarAstronomer::PI)) + 2 ) % 12;

View File

@ -235,8 +235,6 @@ static const char gDayPeriodTag[]="dayPeriod";
static const char gContextTransformsTag[]="contextTransforms";
static UMutex LOCK = U_MUTEX_INITIALIZER;
/**
* Jitterbug 2974: MSVC has a bug whereby new X[0] behaves badly.
* Work around this.
@ -1248,6 +1246,7 @@ const UnicodeString**
DateFormatSymbols::getZoneStrings(int32_t& rowCount, int32_t& columnCount) const
{
const UnicodeString **result = NULL;
static UMutex LOCK = U_MUTEX_INITIALIZER;
umtx_lock(&LOCK);
if (fZoneStrings == NULL) {

View File

@ -82,7 +82,10 @@ UOBJECT_DEFINE_RTTI_IMPLEMENTATION(DateIntervalFormat)
// Mutex, protects access to fDateFormat, fFromCalendar and fToCalendar.
// Needed because these data members are modified by const methods of DateIntervalFormat.
static UMutex gFormatterMutex = U_MUTEX_INITIALIZER;
static UMutex *gFormatterMutex() {
static UMutex m = U_MUTEX_INITIALIZER;
return &m;
}
DateIntervalFormat* U_EXPORT2
DateIntervalFormat::createInstance(const UnicodeString& skeleton,
@ -168,7 +171,7 @@ DateIntervalFormat::operator=(const DateIntervalFormat& itvfmt) {
delete fTimePattern;
delete fDateTimeFormat;
{
Mutex lock(&gFormatterMutex);
Mutex lock(gFormatterMutex());
if ( itvfmt.fDateFormat ) {
fDateFormat = (SimpleDateFormat*)itvfmt.fDateFormat->clone();
} else {
@ -230,7 +233,7 @@ DateIntervalFormat::operator==(const Format& other) const {
if ((fInfo != fmt->fInfo) && (fInfo == NULL || fmt->fInfo == NULL)) {return FALSE;}
if (fInfo && fmt->fInfo && (*fInfo != *fmt->fInfo )) {return FALSE;}
{
Mutex lock(&gFormatterMutex);
Mutex lock(gFormatterMutex());
if (fDateFormat != fmt->fDateFormat && (fDateFormat == NULL || fmt->fDateFormat == NULL)) {return FALSE;}
if (fDateFormat && fmt->fDateFormat && (*fDateFormat != *fmt->fDateFormat)) {return FALSE;}
}
@ -292,7 +295,7 @@ DateIntervalFormat::format(const DateInterval* dtInterval,
handler.setAcceptFirstOnly(TRUE);
int8_t ignore;
Mutex lock(&gFormatterMutex);
Mutex lock(gFormatterMutex());
return formatIntervalImpl(*dtInterval, appendTo, ignore, handler, status);
}
@ -309,7 +312,7 @@ FormattedDateInterval DateIntervalFormat::formatToValue(
auto handler = result->getHandler(status);
handler.setCategory(UFIELD_CATEGORY_DATE);
{
Mutex lock(&gFormatterMutex);
Mutex lock(gFormatterMutex());
formatIntervalImpl(dtInterval, string, firstIndex, handler, status);
}
handler.getError(status);
@ -341,7 +344,7 @@ DateIntervalFormat::format(Calendar& fromCalendar,
handler.setAcceptFirstOnly(TRUE);
int8_t ignore;
Mutex lock(&gFormatterMutex);
Mutex lock(gFormatterMutex());
return formatImpl(fromCalendar, toCalendar, appendTo, ignore, handler, status);
}
@ -359,7 +362,7 @@ FormattedDateInterval DateIntervalFormat::formatToValue(
auto handler = result->getHandler(status);
handler.setCategory(UFIELD_CATEGORY_DATE);
{
Mutex lock(&gFormatterMutex);
Mutex lock(gFormatterMutex());
formatImpl(fromCalendar, toCalendar, string, firstIndex, handler, status);
}
handler.getError(status);
@ -597,7 +600,7 @@ const TimeZone&
DateIntervalFormat::getTimeZone() const
{
if (fDateFormat != NULL) {
Mutex lock(&gFormatterMutex);
Mutex lock(gFormatterMutex());
return fDateFormat->getTimeZone();
}
// If fDateFormat is NULL (unexpected), create default timezone.

View File

@ -32,7 +32,7 @@
#include "uhash.h"
static UHashtable* gGenderInfoCache = NULL;
static icu::UMutex gGenderMetaLock = U_MUTEX_INITIALIZER;
static const char* gNeutralStr = "neutral";
static const char* gMailTaintsStr = "maleTaints";
static const char* gMixedNeutralStr = "mixedNeutral";
@ -98,6 +98,7 @@ const GenderInfo* GenderInfo::getInstance(const Locale& locale, UErrorCode& stat
return NULL;
}
static UMutex gGenderMetaLock = U_MUTEX_INITIALIZER;
const GenderInfo* result = NULL;
const char* key = locale.getName();
{

View File

@ -54,7 +54,6 @@ static void debug_islamcal_msg(const char *pat, ...)
// --- The cache --
// cache of months
static icu::UMutex astroLock = U_MUTEX_INITIALIZER; // pod bay door lock
static icu::CalendarCache *gMonthCache = NULL;
static icu::CalendarAstronomer *gIslamicCalendarAstro = NULL;
@ -471,6 +470,7 @@ double IslamicCalendar::moonAge(UDate time, UErrorCode &status)
{
double age = 0;
static UMutex astroLock = U_MUTEX_INITIALIZER; // pod bay door lock
umtx_lock(&astroLock);
if(gIslamicCalendarAstro == NULL) {
gIslamicCalendarAstro = new CalendarAstronomer();

View File

@ -80,7 +80,6 @@ UPRV_FORMATTED_VALUE_SUBCLASS_AUTO_IMPL(FormattedList)
static Hashtable* listPatternHash = nullptr;
static UMutex listFormatterMutex = U_MUTEX_INITIALIZER;
static const char STANDARD_STYLE[] = "standard";
U_CDECL_BEGIN
@ -145,6 +144,7 @@ const ListFormatInternal* ListFormatter::getListFormatInternal(
keyBuffer.append(':', errorCode).append(style, errorCode);
UnicodeString key(keyBuffer.data(), -1, US_INV);
ListFormatInternal* result = nullptr;
static UMutex listFormatterMutex = U_MUTEX_INITIALIZER;
{
Mutex m(&listFormatterMutex);
if (listPatternHash == nullptr) {

View File

@ -156,7 +156,6 @@ static const icu::number::impl::CldrPatternStyle gFormatCldrStyles[UNUM_FORMAT_S
// Static hashtable cache of NumberingSystem objects used by NumberFormat
static UHashtable * NumberingSystem_cache = NULL;
static icu::UMutex nscacheMutex = U_MUTEX_INITIALIZER;
static icu::UInitOnce gNSCacheInitOnce = U_INITONCE_INITIALIZER;
#if !UCONFIG_NO_SERVICE
@ -1363,6 +1362,7 @@ NumberFormat::makeInstance(const Locale& desiredLocale,
// TODO: Bad hash key usage, see ticket #8504.
int32_t hashKey = desiredLocale.hashCode();
static icu::UMutex nscacheMutex = U_MUTEX_INITIALIZER;
Mutex lock(&nscacheMutex);
ns = (NumberingSystem *)uhash_iget(NumberingSystem_cache, hashKey);
if (ns == NULL) {

View File

@ -27,7 +27,6 @@ U_NAMESPACE_BEGIN
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(RuleBasedTransliterator)
static UMutex transliteratorDataMutex = U_MUTEX_INITIALIZER;
static Replaceable *gLockedText = NULL;
void RuleBasedTransliterator::_construct(const UnicodeString& rules,
@ -253,6 +252,8 @@ RuleBasedTransliterator::handleTransliterate(Replaceable& text, UTransPosition&
// Shared RBT data protected by transliteratorDataMutex.
//
// TODO(andy): Need a better scheme for handling this.
static UMutex transliteratorDataMutex = U_MUTEX_INITIALIZER;
UBool needToLock;
{
Mutex m;

View File

@ -146,10 +146,10 @@ RuleBasedTimeZone::addTransitionRule(TimeZoneRule* rule, UErrorCode& status) {
fUpToDate = FALSE;
}
static UMutex gLock = U_MUTEX_INITIALIZER;
void
RuleBasedTimeZone::completeConst(UErrorCode& status) const {
static UMutex gLock = U_MUTEX_INITIALIZER;
if (U_FAILURE(status)) {
return;
}

View File

@ -51,8 +51,6 @@
// Copied from uscript_props.cpp
static icu::UMutex gBrkIterMutex = U_MUTEX_INITIALIZER;
U_NAMESPACE_BEGIN
// RelativeDateTimeFormatter specific data for a single locale
@ -1186,6 +1184,7 @@ UnicodeString& RelativeDateTimeFormatter::adjustForContext(UnicodeString &str) c
// Must guarantee that one thread at a time accesses the shared break
// iterator.
static icu::UMutex gBrkIterMutex = U_MUTEX_INITIALIZER;
Mutex lock(&gBrkIterMutex);
str.toTitle(
fOptBreakIterator->get(),

View File

@ -1077,13 +1077,13 @@ SimpleTimeZone::deleteTransitionRules(void) {
* allocate it in the constructors. This would be a more intrusive change, but doable
* if performance turns out to be an issue.
*/
static UMutex gLock = U_MUTEX_INITIALIZER;
void
SimpleTimeZone::checkTransitionRules(UErrorCode& status) const {
if (U_FAILURE(status)) {
return;
}
static UMutex gLock = U_MUTEX_INITIALIZER;
umtx_lock(&gLock);
if (!transitionRulesInitialized) {
SimpleTimeZone *ncThis = const_cast<SimpleTimeZone*>(this);

View File

@ -230,7 +230,10 @@ static const int32_t gFieldRangeBias[] = {
static const int32_t HEBREW_CAL_CUR_MILLENIUM_START_YEAR = 5000;
static const int32_t HEBREW_CAL_CUR_MILLENIUM_END_YEAR = 6000;
static UMutex LOCK = U_MUTEX_INITIALIZER;
static UMutex *LOCK() {
static UMutex m = U_MUTEX_INITIALIZER;
return &m;
}
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(SimpleDateFormat)
@ -1263,14 +1266,14 @@ SimpleDateFormat::initNumberFormatters(const Locale &locale,UErrorCode &status)
if ( fDateOverride.isBogus() && fTimeOverride.isBogus() ) {
return;
}
umtx_lock(&LOCK);
umtx_lock(LOCK());
if (fSharedNumberFormatters == NULL) {
fSharedNumberFormatters = allocSharedNumberFormatters();
if (fSharedNumberFormatters == NULL) {
status = U_MEMORY_ALLOCATION_ERROR;
}
}
umtx_unlock(&LOCK);
umtx_unlock(LOCK());
if (U_FAILURE(status)) {
return;
@ -4198,7 +4201,7 @@ SimpleDateFormat::skipUWhiteSpace(const UnicodeString& text, int32_t pos) const
TimeZoneFormat *
SimpleDateFormat::tzFormat(UErrorCode &status) const {
if (fTimeZoneFormat == NULL) {
umtx_lock(&LOCK);
umtx_lock(LOCK());
{
if (fTimeZoneFormat == NULL) {
TimeZoneFormat *tzfmt = TimeZoneFormat::createInstance(fLocale, status);
@ -4209,7 +4212,7 @@ SimpleDateFormat::tzFormat(UErrorCode &status) const {
const_cast<SimpleDateFormat *>(this)->fTimeZoneFormat = tzfmt;
}
}
umtx_unlock(&LOCK);
umtx_unlock(LOCK());
}
return fTimeZoneFormat;
}

View File

@ -91,7 +91,10 @@ static const char RB_RULE_BASED_IDS[] = "RuleBasedTransliteratorIDs";
/**
* The mutex controlling access to registry object.
*/
static icu::UMutex registryMutex = U_MUTEX_INITIALIZER;
static icu::UMutex *registryMutex() {
static icu::UMutex m = U_MUTEX_INITIALIZER;
return &m;
}
/**
* System transliterator registry; non-null when initialized.
@ -978,11 +981,11 @@ Transliterator* Transliterator::createBasicInstance(const UnicodeString& id,
TransliteratorAlias* alias = 0;
Transliterator* t = 0;
umtx_lock(&registryMutex);
umtx_lock(registryMutex());
if (HAVE_REGISTRY(ec)) {
t = registry->get(id, alias, ec);
}
umtx_unlock(&registryMutex);
umtx_unlock(registryMutex());
if (U_FAILURE(ec)) {
delete t;
@ -1010,11 +1013,11 @@ Transliterator* Transliterator::createBasicInstance(const UnicodeString& id,
alias = 0;
// Step 2. reget
umtx_lock(&registryMutex);
umtx_lock(registryMutex());
if (HAVE_REGISTRY(ec)) {
t = registry->reget(id, parser, alias, ec);
}
umtx_unlock(&registryMutex);
umtx_unlock(registryMutex());
// Step 3. Loop back around!
} else {
@ -1212,7 +1215,7 @@ UnicodeSet& Transliterator::getTargetSet(UnicodeSet& result) const {
void U_EXPORT2 Transliterator::registerFactory(const UnicodeString& id,
Transliterator::Factory factory,
Transliterator::Token context) {
Mutex lock(&registryMutex);
Mutex lock(registryMutex());
UErrorCode ec = U_ZERO_ERROR;
if (HAVE_REGISTRY(ec)) {
_registerFactory(id, factory, context);
@ -1251,7 +1254,7 @@ void Transliterator::_registerSpecialInverse(const UnicodeString& target,
* @see #unregister
*/
void U_EXPORT2 Transliterator::registerInstance(Transliterator* adoptedPrototype) {
Mutex lock(&registryMutex);
Mutex lock(registryMutex());
UErrorCode ec = U_ZERO_ERROR;
if (HAVE_REGISTRY(ec)) {
_registerInstance(adoptedPrototype);
@ -1265,7 +1268,7 @@ void Transliterator::_registerInstance(Transliterator* adoptedPrototype) {
void U_EXPORT2 Transliterator::registerAlias(const UnicodeString& aliasID,
const UnicodeString& realID) {
Mutex lock(&registryMutex);
Mutex lock(registryMutex());
UErrorCode ec = U_ZERO_ERROR;
if (HAVE_REGISTRY(ec)) {
_registerAlias(aliasID, realID);
@ -1287,7 +1290,7 @@ void Transliterator::_registerAlias(const UnicodeString& aliasID,
*/
void U_EXPORT2 Transliterator::unregister(const UnicodeString& ID) {
Mutex lock(&registryMutex);
Mutex lock(registryMutex());
UErrorCode ec = U_ZERO_ERROR;
if (HAVE_REGISTRY(ec)) {
registry->remove(ID);
@ -1302,7 +1305,7 @@ void U_EXPORT2 Transliterator::unregister(const UnicodeString& ID) {
*/
int32_t U_EXPORT2 Transliterator::countAvailableIDs(void) {
int32_t retVal = 0;
Mutex lock(&registryMutex);
Mutex lock(registryMutex());
UErrorCode ec = U_ZERO_ERROR;
if (HAVE_REGISTRY(ec)) {
retVal = registry->countAvailableIDs();
@ -1318,12 +1321,12 @@ int32_t U_EXPORT2 Transliterator::countAvailableIDs(void) {
*/
const UnicodeString& U_EXPORT2 Transliterator::getAvailableID(int32_t index) {
const UnicodeString* result = NULL;
umtx_lock(&registryMutex);
umtx_lock(registryMutex());
UErrorCode ec = U_ZERO_ERROR;
if (HAVE_REGISTRY(ec)) {
result = &registry->getAvailableID(index);
}
umtx_unlock(&registryMutex);
umtx_unlock(registryMutex());
U_ASSERT(result != NULL); // fail if no registry
return *result;
}
@ -1331,11 +1334,11 @@ const UnicodeString& U_EXPORT2 Transliterator::getAvailableID(int32_t index) {
StringEnumeration* U_EXPORT2 Transliterator::getAvailableIDs(UErrorCode& ec) {
if (U_FAILURE(ec)) return NULL;
StringEnumeration* result = NULL;
umtx_lock(&registryMutex);
umtx_lock(registryMutex());
if (HAVE_REGISTRY(ec)) {
result = registry->getAvailableIDs();
}
umtx_unlock(&registryMutex);
umtx_unlock(registryMutex());
if (result == NULL) {
ec = U_INTERNAL_TRANSLITERATOR_ERROR;
}
@ -1343,14 +1346,14 @@ StringEnumeration* U_EXPORT2 Transliterator::getAvailableIDs(UErrorCode& ec) {
}
int32_t U_EXPORT2 Transliterator::countAvailableSources(void) {
Mutex lock(&registryMutex);
Mutex lock(registryMutex());
UErrorCode ec = U_ZERO_ERROR;
return HAVE_REGISTRY(ec) ? _countAvailableSources() : 0;
}
UnicodeString& U_EXPORT2 Transliterator::getAvailableSource(int32_t index,
UnicodeString& result) {
Mutex lock(&registryMutex);
Mutex lock(registryMutex());
UErrorCode ec = U_ZERO_ERROR;
if (HAVE_REGISTRY(ec)) {
_getAvailableSource(index, result);
@ -1359,7 +1362,7 @@ UnicodeString& U_EXPORT2 Transliterator::getAvailableSource(int32_t index,
}
int32_t U_EXPORT2 Transliterator::countAvailableTargets(const UnicodeString& source) {
Mutex lock(&registryMutex);
Mutex lock(registryMutex());
UErrorCode ec = U_ZERO_ERROR;
return HAVE_REGISTRY(ec) ? _countAvailableTargets(source) : 0;
}
@ -1367,7 +1370,7 @@ int32_t U_EXPORT2 Transliterator::countAvailableTargets(const UnicodeString& sou
UnicodeString& U_EXPORT2 Transliterator::getAvailableTarget(int32_t index,
const UnicodeString& source,
UnicodeString& result) {
Mutex lock(&registryMutex);
Mutex lock(registryMutex());
UErrorCode ec = U_ZERO_ERROR;
if (HAVE_REGISTRY(ec)) {
_getAvailableTarget(index, source, result);
@ -1377,7 +1380,7 @@ UnicodeString& U_EXPORT2 Transliterator::getAvailableTarget(int32_t index,
int32_t U_EXPORT2 Transliterator::countAvailableVariants(const UnicodeString& source,
const UnicodeString& target) {
Mutex lock(&registryMutex);
Mutex lock(registryMutex());
UErrorCode ec = U_ZERO_ERROR;
return HAVE_REGISTRY(ec) ? _countAvailableVariants(source, target) : 0;
}
@ -1386,7 +1389,7 @@ UnicodeString& U_EXPORT2 Transliterator::getAvailableVariant(int32_t index,
const UnicodeString& source,
const UnicodeString& target,
UnicodeString& result) {
Mutex lock(&registryMutex);
Mutex lock(registryMutex());
UErrorCode ec = U_ZERO_ERROR;
if (HAVE_REGISTRY(ec)) {
_getAvailableVariant(index, source, target, result);

View File

@ -50,7 +50,10 @@ static UInitOnce gSpecialInversesInitOnce = U_INITONCE_INITIALIZER;
/**
* The mutex controlling access to SPECIAL_INVERSES
*/
static UMutex LOCK = U_MUTEX_INITIALIZER;
static UMutex *LOCK() {
static UMutex m = U_MUTEX_INITIALIZER;
return &m;
}
TransliteratorIDParser::Specs::Specs(const UnicodeString& s, const UnicodeString& t,
const UnicodeString& v, UBool sawS,
@ -659,7 +662,7 @@ void TransliteratorIDParser::registerSpecialInverse(const UnicodeString& target,
bidirectional = FALSE;
}
Mutex lock(&LOCK);
Mutex lock(LOCK());
UnicodeString *tempus = new UnicodeString(inverseTarget); // Used for null pointer check before usage.
if (tempus == NULL) {
@ -863,9 +866,9 @@ TransliteratorIDParser::specsToSpecialInverse(const Specs& specs, UErrorCode &st
UnicodeString* inverseTarget;
umtx_lock(&LOCK);
umtx_lock(LOCK());
inverseTarget = (UnicodeString*) SPECIAL_INVERSES->get(specs.target);
umtx_unlock(&LOCK);
umtx_unlock(LOCK());
if (inverseTarget != NULL) {
// If the original ID contained "Any-" then make the

View File

@ -147,7 +147,10 @@ static icu::UInitOnce gZoneIdTrieInitOnce = U_INITONCE_INITIALIZER;
static TextTrieMap *gShortZoneIdTrie = NULL;
static icu::UInitOnce gShortZoneIdTrieInitOnce = U_INITONCE_INITIALIZER;
static UMutex gLock = U_MUTEX_INITIALIZER;
static UMutex *gLock() {
static UMutex m = U_MUTEX_INITIALIZER;
return &m;
}
U_CDECL_BEGIN
/**
@ -1382,12 +1385,12 @@ TimeZoneFormat::getTimeZoneGenericNames(UErrorCode& status) const {
return NULL;
}
umtx_lock(&gLock);
umtx_lock(gLock());
if (fTimeZoneGenericNames == NULL) {
TimeZoneFormat *nonConstThis = const_cast<TimeZoneFormat *>(this);
nonConstThis->fTimeZoneGenericNames = TimeZoneGenericNames::createInstance(fLocale, status);
}
umtx_unlock(&gLock);
umtx_unlock(gLock());
return fTimeZoneGenericNames;
}
@ -1398,7 +1401,7 @@ TimeZoneFormat::getTZDBTimeZoneNames(UErrorCode& status) const {
return NULL;
}
umtx_lock(&gLock);
umtx_lock(gLock());
if (fTZDBTimeZoneNames == NULL) {
TZDBTimeZoneNames *tzdbNames = new TZDBTimeZoneNames(fLocale);
if (tzdbNames == NULL) {
@ -1408,7 +1411,7 @@ TimeZoneFormat::getTZDBTimeZoneNames(UErrorCode& status) const {
nonConstThis->fTZDBTimeZoneNames = tzdbNames;
}
}
umtx_unlock(&gLock);
umtx_unlock(gLock());
return fTZDBTimeZoneNames;
}

View File

@ -269,7 +269,10 @@ GNameSearchHandler::getMatches(int32_t& maxMatchLen) {
return results;
}
static UMutex gLock = U_MUTEX_INITIALIZER;
static UMutex *gLock() {
static UMutex m = U_MUTEX_INITIALIZER;
return &m;
}
class TZGNCore : public UMemory {
public:
@ -485,11 +488,11 @@ TZGNCore::getGenericLocationName(const UnicodeString& tzCanonicalID, UnicodeStri
const UChar *locname = NULL;
TZGNCore *nonConstThis = const_cast<TZGNCore *>(this);
umtx_lock(&gLock);
umtx_lock(gLock());
{
locname = nonConstThis->getGenericLocationName(tzCanonicalID);
}
umtx_unlock(&gLock);
umtx_unlock(gLock());
if (locname == NULL) {
name.setToBogus();
@ -740,11 +743,11 @@ TZGNCore::getPartialLocationName(const UnicodeString& tzCanonicalID,
const UChar *uplname = NULL;
TZGNCore *nonConstThis = const_cast<TZGNCore *>(this);
umtx_lock(&gLock);
umtx_lock(gLock());
{
uplname = nonConstThis->getPartialLocationName(tzCanonicalID, mzID, isLong, mzDisplayName);
}
umtx_unlock(&gLock);
umtx_unlock(gLock());
if (uplname == NULL) {
name.setToBogus();
@ -1007,11 +1010,11 @@ TZGNCore::findLocal(const UnicodeString& text, int32_t start, uint32_t types, UE
TZGNCore *nonConstThis = const_cast<TZGNCore *>(this);
umtx_lock(&gLock);
umtx_lock(gLock());
{
fGNamesTrie.search(text, start, (TextTrieMapSearchResultHandler *)&handler, status);
}
umtx_unlock(&gLock);
umtx_unlock(gLock());
if (U_FAILURE(status)) {
return NULL;
@ -1038,7 +1041,7 @@ TZGNCore::findLocal(const UnicodeString& text, int32_t start, uint32_t types, UE
// All names are not yet loaded into the local trie.
// Load all available names into the trie. This could be very heavy.
umtx_lock(&gLock);
umtx_lock(gLock());
{
if (!fGNamesTrieFullyLoaded) {
StringEnumeration *tzIDs = TimeZone::createTimeZoneIDEnumeration(UCAL_ZONE_TYPE_CANONICAL, NULL, NULL, status);
@ -1060,18 +1063,18 @@ TZGNCore::findLocal(const UnicodeString& text, int32_t start, uint32_t types, UE
}
}
}
umtx_unlock(&gLock);
umtx_unlock(gLock());
if (U_FAILURE(status)) {
return NULL;
}
umtx_lock(&gLock);
umtx_lock(gLock());
{
// now try it again
fGNamesTrie.search(text, start, (TextTrieMapSearchResultHandler *)&handler, status);
}
umtx_unlock(&gLock);
umtx_unlock(gLock());
results = handler.getMatches(maxLen);
if (results != NULL && maxLen > 0) {
@ -1112,7 +1115,10 @@ typedef struct TZGNCoreRef {
} TZGNCoreRef;
// TZGNCore object cache handling
static UMutex gTZGNLock = U_MUTEX_INITIALIZER;
static UMutex *gTZGNLock() {
static UMutex m = U_MUTEX_INITIALIZER;
return &m;
}
static UHashtable *gTZGNCoreCache = NULL;
static UBool gTZGNCoreCacheInitialized = FALSE;
@ -1178,13 +1184,13 @@ TimeZoneGenericNames::TimeZoneGenericNames()
}
TimeZoneGenericNames::~TimeZoneGenericNames() {
umtx_lock(&gTZGNLock);
umtx_lock(gTZGNLock());
{
U_ASSERT(fRef->refCount > 0);
// Just decrement the reference count
fRef->refCount--;
}
umtx_unlock(&gTZGNLock);
umtx_unlock(gTZGNLock());
}
TimeZoneGenericNames*
@ -1200,7 +1206,7 @@ TimeZoneGenericNames::createInstance(const Locale& locale, UErrorCode& status) {
TZGNCoreRef *cacheEntry = NULL;
{
Mutex lock(&gTZGNLock);
Mutex lock(gTZGNLock());
if (!gTZGNCoreCacheInitialized) {
// Create empty hashtable
@ -1292,13 +1298,13 @@ TimeZoneGenericNames*
TimeZoneGenericNames::clone() const {
TimeZoneGenericNames* other = new TimeZoneGenericNames();
if (other) {
umtx_lock(&gTZGNLock);
umtx_lock(gTZGNLock());
{
// Just increments the reference count
fRef->refCount++;
other->fRef = fRef;
}
umtx_unlock(&gTZGNLock);
umtx_unlock(gTZGNLock());
}
return other;
}

View File

@ -29,7 +29,10 @@
U_NAMESPACE_BEGIN
// TimeZoneNames object cache handling
static UMutex gTimeZoneNamesLock = U_MUTEX_INITIALIZER;
static UMutex *gTimeZoneNamesLock() {
static UMutex m = U_MUTEX_INITIALIZER;
return &m;
}
static UHashtable *gTimeZoneNamesCache = NULL;
static UBool gTimeZoneNamesCacheInitialized = FALSE;
@ -132,7 +135,7 @@ TimeZoneNamesDelegate::TimeZoneNamesDelegate()
}
TimeZoneNamesDelegate::TimeZoneNamesDelegate(const Locale& locale, UErrorCode& status) {
Mutex lock(&gTimeZoneNamesLock);
Mutex lock(gTimeZoneNamesLock());
if (!gTimeZoneNamesCacheInitialized) {
// Create empty hashtable if it is not already initialized.
gTimeZoneNamesCache = uhash_open(uhash_hashChars, uhash_compareChars, NULL, &status);
@ -208,7 +211,7 @@ TimeZoneNamesDelegate::TimeZoneNamesDelegate(const Locale& locale, UErrorCode& s
}
TimeZoneNamesDelegate::~TimeZoneNamesDelegate() {
umtx_lock(&gTimeZoneNamesLock);
umtx_lock(gTimeZoneNamesLock());
{
if (fTZnamesCacheEntry) {
U_ASSERT(fTZnamesCacheEntry->refCount > 0);
@ -216,7 +219,7 @@ TimeZoneNamesDelegate::~TimeZoneNamesDelegate() {
fTZnamesCacheEntry->refCount--;
}
}
umtx_unlock(&gTimeZoneNamesLock);
umtx_unlock(gTimeZoneNamesLock());
}
UBool
@ -237,13 +240,13 @@ TimeZoneNames*
TimeZoneNamesDelegate::clone() const {
TimeZoneNamesDelegate* other = new TimeZoneNamesDelegate();
if (other != NULL) {
umtx_lock(&gTimeZoneNamesLock);
umtx_lock(gTimeZoneNamesLock());
{
// Just increment the reference count
fTZnamesCacheEntry->refCount++;
other->fTZnamesCacheEntry = fTZnamesCacheEntry;
}
umtx_unlock(&gTimeZoneNamesLock);
umtx_unlock(gTimeZoneNamesLock());
}
return other;
}

View File

@ -49,8 +49,10 @@ static const UChar NO_NAME[] = { 0 }; // for empty no-fallback time
static const char* TZDBNAMES_KEYS[] = {"ss", "sd"};
static const int32_t TZDBNAMES_KEYS_SIZE = UPRV_LENGTHOF(TZDBNAMES_KEYS);
static UMutex gTZDBNamesMapLock = U_MUTEX_INITIALIZER;
static UMutex gDataMutex = U_MUTEX_INITIALIZER;
static UMutex *gDataMutex() {
static UMutex m = U_MUTEX_INITIALIZER;
return &m;
}
static UHashtable* gTZDBNamesMap = NULL;
static icu::UInitOnce gTZDBNamesMapInitOnce = U_INITONCE_INITIALIZER;
@ -357,8 +359,6 @@ TextTrieMap::getChildNode(CharacterNode *parent, UChar c) const {
return NULL;
}
// Mutex for protecting the lazy creation of the Trie node structure on the first call to search().
static UMutex TextTrieMutex = U_MUTEX_INITIALIZER;
// buildTrie() - The Trie node structure is needed. Create it from the data that was
// saved at the time the ZoneStringFormatter was created. The Trie is only
@ -386,6 +386,10 @@ TextTrieMap::search(const UnicodeString &text, int32_t start,
// the ICU atomic safe functions for assigning and testing.
// Don't test the pointer fLazyContents.
// Don't do unless it's really required.
// Mutex for protecting the lazy creation of the Trie node structure on the first call to search().
static UMutex TextTrieMutex = U_MUTEX_INITIALIZER;
Mutex lock(&TextTrieMutex);
if (fLazyContents != NULL) {
TextTrieMap *nonConstThis = const_cast<TextTrieMap *>(this);
@ -1210,7 +1214,7 @@ TimeZoneNamesImpl::getMetaZoneDisplayName(const UnicodeString& mzID,
TimeZoneNamesImpl *nonConstThis = const_cast<TimeZoneNamesImpl *>(this);
{
Mutex lock(&gDataMutex);
Mutex lock(gDataMutex());
UErrorCode status = U_ZERO_ERROR;
znames = nonConstThis->loadMetaZoneNames(mzID, status);
if (U_FAILURE(status)) { return name; }
@ -1236,7 +1240,7 @@ TimeZoneNamesImpl::getTimeZoneDisplayName(const UnicodeString& tzID, UTimeZoneNa
TimeZoneNamesImpl *nonConstThis = const_cast<TimeZoneNamesImpl *>(this);
{
Mutex lock(&gDataMutex);
Mutex lock(gDataMutex());
UErrorCode status = U_ZERO_ERROR;
tznames = nonConstThis->loadTimeZoneNames(tzID, status);
if (U_FAILURE(status)) { return name; }
@ -1259,7 +1263,7 @@ TimeZoneNamesImpl::getExemplarLocationName(const UnicodeString& tzID, UnicodeStr
TimeZoneNamesImpl *nonConstThis = const_cast<TimeZoneNamesImpl *>(this);
{
Mutex lock(&gDataMutex);
Mutex lock(gDataMutex());
UErrorCode status = U_ZERO_ERROR;
tznames = nonConstThis->loadTimeZoneNames(tzID, status);
if (U_FAILURE(status)) { return name; }
@ -1354,7 +1358,7 @@ TimeZoneNamesImpl::find(const UnicodeString& text, int32_t start, uint32_t types
// Synchronize so that data is not loaded multiple times.
// TODO: Consider more fine-grained synchronization.
{
Mutex lock(&gDataMutex);
Mutex lock(gDataMutex());
// First try of lookup.
matches = doFind(handler, text, start, status);
@ -1581,7 +1585,7 @@ void TimeZoneNamesImpl::loadAllDisplayNames(UErrorCode& status) {
if (U_FAILURE(status)) return;
{
Mutex lock(&gDataMutex);
Mutex lock(gDataMutex());
internalLoadAllDisplayNames(status);
}
}
@ -1598,7 +1602,7 @@ void TimeZoneNamesImpl::getDisplayNames(const UnicodeString& tzID,
// Load the time zone strings
{
Mutex lock(&gDataMutex);
Mutex lock(gDataMutex());
tznames = (void*) nonConstThis->loadTimeZoneNames(tzID, status);
if (U_FAILURE(status)) { return; }
}
@ -1618,7 +1622,7 @@ void TimeZoneNamesImpl::getDisplayNames(const UnicodeString& tzID,
} else {
// Load the meta zone strings
// Mutex is scoped to the "else" statement
Mutex lock(&gDataMutex);
Mutex lock(gDataMutex());
mznames = (void*) nonConstThis->loadMetaZoneNames(mzID, status);
if (U_FAILURE(status)) { return; }
// Note: when the metazone doesn't exist, in Java, loadMetaZoneNames returns
@ -2243,6 +2247,7 @@ TZDBTimeZoneNames::getMetaZoneNames(const UnicodeString& mzID, UErrorCode& statu
U_ASSERT(status == U_ZERO_ERROR); // already checked length above
mzIDKey[mzID.length()] = 0;
static UMutex gTZDBNamesMapLock = U_MUTEX_INITIALIZER;
umtx_lock(&gTZDBNamesMapLock);
{
void *cacheVal = uhash_get(gTZDBNamesMap, mzIDKey);

View File

@ -30,7 +30,10 @@
#include "olsontz.h"
#include "uinvchar.h"
static icu::UMutex gZoneMetaLock = U_MUTEX_INITIALIZER;
static icu::UMutex *gZoneMetaLock() {
static icu::UMutex m = U_MUTEX_INITIALIZER;
return &m;
}
// CLDR Canonical ID mapping table
static UHashtable *gCanonicalIDCache = NULL;
@ -263,11 +266,11 @@ ZoneMeta::getCanonicalCLDRID(const UnicodeString &tzid, UErrorCode& status) {
}
// Check if it was already cached
umtx_lock(&gZoneMetaLock);
umtx_lock(gZoneMetaLock());
{
canonicalID = (const UChar *)uhash_get(gCanonicalIDCache, utzid);
}
umtx_unlock(&gZoneMetaLock);
umtx_unlock(gZoneMetaLock());
if (canonicalID != NULL) {
return canonicalID;
@ -348,7 +351,7 @@ ZoneMeta::getCanonicalCLDRID(const UnicodeString &tzid, UErrorCode& status) {
U_ASSERT(canonicalID != NULL); // canocanilD must be non-NULL here
// Put the resolved canonical ID to the cache
umtx_lock(&gZoneMetaLock);
umtx_lock(gZoneMetaLock());
{
const UChar* idInCache = (const UChar *)uhash_get(gCanonicalIDCache, utzid);
if (idInCache == NULL) {
@ -368,7 +371,7 @@ ZoneMeta::getCanonicalCLDRID(const UnicodeString &tzid, UErrorCode& status) {
}
}
}
umtx_unlock(&gZoneMetaLock);
umtx_unlock(gZoneMetaLock());
}
return canonicalID;
@ -446,14 +449,14 @@ ZoneMeta::getCanonicalCountry(const UnicodeString &tzid, UnicodeString &country,
// Check if it was already cached
UBool cached = FALSE;
UBool singleZone = FALSE;
umtx_lock(&gZoneMetaLock);
umtx_lock(gZoneMetaLock());
{
singleZone = cached = gSingleZoneCountries->contains((void*)region);
if (!cached) {
cached = gMultiZonesCountries->contains((void*)region);
}
}
umtx_unlock(&gZoneMetaLock);
umtx_unlock(gZoneMetaLock());
if (!cached) {
// We need to go through all zones associated with the region.
@ -472,7 +475,7 @@ ZoneMeta::getCanonicalCountry(const UnicodeString &tzid, UnicodeString &country,
delete ids;
// Cache the result
umtx_lock(&gZoneMetaLock);
umtx_lock(gZoneMetaLock());
{
UErrorCode ec = U_ZERO_ERROR;
if (singleZone) {
@ -485,7 +488,7 @@ ZoneMeta::getCanonicalCountry(const UnicodeString &tzid, UnicodeString &country,
}
}
}
umtx_unlock(&gZoneMetaLock);
umtx_unlock(gZoneMetaLock());
}
if (singleZone) {
@ -572,11 +575,11 @@ ZoneMeta::getMetazoneMappings(const UnicodeString &tzid) {
// get the mapping from cache
const UVector *result = NULL;
umtx_lock(&gZoneMetaLock);
umtx_lock(gZoneMetaLock());
{
result = (UVector*) uhash_get(gOlsonToMeta, tzidUChars);
}
umtx_unlock(&gZoneMetaLock);
umtx_unlock(gZoneMetaLock());
if (result != NULL) {
return result;
@ -590,7 +593,7 @@ ZoneMeta::getMetazoneMappings(const UnicodeString &tzid) {
}
// put the new one into the cache
umtx_lock(&gZoneMetaLock);
umtx_lock(gZoneMetaLock());
{
// make sure it's already created
result = (UVector*) uhash_get(gOlsonToMeta, tzidUChars);
@ -618,7 +621,7 @@ ZoneMeta::getMetazoneMappings(const UnicodeString &tzid) {
delete tmpResult;
}
}
umtx_unlock(&gZoneMetaLock);
umtx_unlock(gZoneMetaLock());
return result;
}

View File

@ -45,9 +45,9 @@ static UBool U_CALLCONV locbund_cleanup(void) {
}
U_CDECL_END
static icu::UMutex gLock = U_MUTEX_INITIALIZER;
static inline UNumberFormat * copyInvariantFormatter(ULocaleBundle *result, UNumberFormatStyle style) {
U_NAMESPACE_USE
static UMutex gLock = U_MUTEX_INITIALIZER;
Mutex lock(&gLock);
if (result->fNumberFormat[style-1] == NULL) {
if (gPosixNumberFormat[style-1] == NULL) {

View File

@ -1109,7 +1109,6 @@ UBool IntlTest::printKnownIssues()
}
}
static UMutex messageMutex = U_MUTEX_INITIALIZER;
void IntlTest::LL_message( UnicodeString message, UBool newline )
{
@ -1117,6 +1116,7 @@ void IntlTest::LL_message( UnicodeString message, UBool newline )
// All error messages generated by tests funnel through here.
// Multithreaded tests can concurrently generate errors, requiring synchronization
// to keep each message together.
static UMutex messageMutex = U_MUTEX_INITIALIZER;
Mutex lock(&messageMutex);
// string that starts with a LineFeed character and continues

View File

@ -240,8 +240,14 @@ void MultithreadTest::TestArabicShapingThreads()
// platform's mutex support is at least superficially there.
//
//----------------------------------------------------------------------
static UMutex gTestMutexA = U_MUTEX_INITIALIZER;
static UConditionVar gThreadsCountChanged = U_CONDITION_INITIALIZER;
static UMutex *gTestMutexA() {
static UMutex m = U_MUTEX_INITIALIZER;
return &m;
}
static UConditionVar *gThreadsCountChanged() {
static UConditionVar cv = U_CONDITION_INITIALIZER;
return &cv;
}
static int gThreadsStarted = 0;
static int gThreadsInMiddle = 0;
@ -256,35 +262,35 @@ public:
// This is the code that each of the spawned threads runs.
// All threads move together throught the started - middle - done sequence together,
// waiting for all other threads to reach each point before advancing.
umtx_lock(&gTestMutexA);
umtx_lock(gTestMutexA());
gThreadsStarted += 1;
umtx_condBroadcast(&gThreadsCountChanged);
umtx_condBroadcast(gThreadsCountChanged());
while (gThreadsStarted < TESTMUTEX_THREAD_COUNT) {
if (gThreadsInMiddle != 0) {
IntlTest::gTest->errln(
"%s:%d gThreadsInMiddle = %d. Expected 0.", __FILE__, __LINE__, gThreadsInMiddle);
return;
}
umtx_condWait(&gThreadsCountChanged, &gTestMutexA);
umtx_condWait(gThreadsCountChanged(), gTestMutexA());
}
gThreadsInMiddle += 1;
umtx_condBroadcast(&gThreadsCountChanged);
umtx_condBroadcast(gThreadsCountChanged());
while (gThreadsInMiddle < TESTMUTEX_THREAD_COUNT) {
if (gThreadsDone != 0) {
IntlTest::gTest->errln(
"%s:%d gThreadsDone = %d. Expected 0.", __FILE__, __LINE__, gThreadsDone);
return;
}
umtx_condWait(&gThreadsCountChanged, &gTestMutexA);
umtx_condWait(gThreadsCountChanged(), gTestMutexA());
}
gThreadsDone += 1;
umtx_condBroadcast(&gThreadsCountChanged);
umtx_condBroadcast(gThreadsCountChanged());
while (gThreadsDone < TESTMUTEX_THREAD_COUNT) {
umtx_condWait(&gThreadsCountChanged, &gTestMutexA);
umtx_condWait(gThreadsCountChanged(), gTestMutexA());
}
umtx_unlock(&gTestMutexA);
umtx_unlock(gTestMutexA());
}
};
@ -295,7 +301,7 @@ void MultithreadTest::TestMutex()
gThreadsDone = 0;
int32_t i = 0;
TestMutexThread threads[TESTMUTEX_THREAD_COUNT];
umtx_lock(&gTestMutexA);
umtx_lock(gTestMutexA());
for (i=0; i<TESTMUTEX_THREAD_COUNT; i++) {
if (threads[i].start() != 0) {
errln("%s:%d Error starting thread %d", __FILE__, __LINE__, i);
@ -315,13 +321,13 @@ void MultithreadTest::TestMutex()
errln("%s:%d gThreadsDone=%d. Expected 0.", __FILE__, __LINE__, gThreadsStarted);
return;
}
umtx_condWait(&gThreadsCountChanged, &gTestMutexA);
umtx_condWait(gThreadsCountChanged(), gTestMutexA());
}
while (gThreadsDone < TESTMUTEX_THREAD_COUNT) {
umtx_condWait(&gThreadsCountChanged, &gTestMutexA);
umtx_condWait(gThreadsCountChanged(), gTestMutexA());
}
umtx_unlock(&gTestMutexA);
umtx_unlock(gTestMutexA());
for (i=0; i<TESTMUTEX_THREAD_COUNT; i++) {
threads[i].join();
@ -1166,8 +1172,14 @@ class CondThread: public SimpleThread {
bool fFinished;
};
static UMutex gCTMutex = U_MUTEX_INITIALIZER;
static UConditionVar gCTConditionVar = U_CONDITION_INITIALIZER;
static UMutex *gCTMutex() {
static UMutex m = U_MUTEX_INITIALIZER;
return &m;
}
static UConditionVar *gCTConditionVar() {
static UConditionVar cv = U_CONDITION_INITIALIZER;
return &cv;
}
int gConditionTestOne = 1; // Value one. Non-const, extern linkage to inhibit
// compiler assuming a known value.
int gStartedThreads;
@ -1177,26 +1189,26 @@ static const int NUMTHREADS = 10;
// Worker thread function.
void CondThread::run() {
umtx_lock(&gCTMutex);
umtx_lock(gCTMutex());
gStartedThreads += gConditionTestOne;
umtx_condBroadcast(&gCTConditionVar);
umtx_condBroadcast(gCTConditionVar());
while (gStartedThreads < NUMTHREADS) {
if (gFinishedThreads != 0) {
IntlTest::gTest->errln("File %s, Line %d: Error, gStartedThreads = %d, gFinishedThreads = %d",
__FILE__, __LINE__, gStartedThreads, gFinishedThreads);
}
umtx_condWait(&gCTConditionVar, &gCTMutex);
umtx_condWait(gCTConditionVar(), gCTMutex());
}
gFinishedThreads += gConditionTestOne;
fFinished = true;
umtx_condBroadcast(&gCTConditionVar);
umtx_condBroadcast(gCTConditionVar());
while (gFinishedThreads < NUMTHREADS) {
umtx_condWait(&gCTConditionVar, &gCTMutex);
umtx_condWait(gCTConditionVar(), gCTMutex());
}
umtx_unlock(&gCTMutex);
umtx_unlock(gCTMutex());
}
void MultithreadTest::TestConditionVariables() {
@ -1204,7 +1216,7 @@ void MultithreadTest::TestConditionVariables() {
gFinishedThreads = 0;
int i;
umtx_lock(&gCTMutex);
umtx_lock(gCTMutex());
CondThread *threads[NUMTHREADS];
for (i=0; i<NUMTHREADS; ++i) {
threads[i] = new CondThread;
@ -1212,14 +1224,14 @@ void MultithreadTest::TestConditionVariables() {
}
while (gStartedThreads < NUMTHREADS) {
umtx_condWait(&gCTConditionVar, &gCTMutex);
umtx_condWait(gCTConditionVar(), gCTMutex());
}
while (gFinishedThreads < NUMTHREADS) {
umtx_condWait(&gCTConditionVar, &gCTMutex);
umtx_condWait(gCTConditionVar(), gCTMutex());
}
umtx_unlock(&gCTMutex);
umtx_unlock(gCTMutex());
for (i=0; i<NUMTHREADS; ++i) {
assertTrue(WHERE, threads[i]->fFinished);
@ -1280,7 +1292,7 @@ const UCTMultiThreadItem *LocaleCacheKey<UCTMultiThreadItem>::createObject(
return result;
}
umtx_lock(&gCTMutex);
umtx_lock(gCTMutex());
bool firstObject = (gObjectsCreated == 0);
if (firstObject) {
// Force the first object creation that comes through to wait
@ -1291,10 +1303,10 @@ const UCTMultiThreadItem *LocaleCacheKey<UCTMultiThreadItem>::createObject(
// early, to keep subsequent threads from entering this path.
gObjectsCreated = 1;
while (gObjectsCreated < 3) {
umtx_condWait(&gCTConditionVar, &gCTMutex);
umtx_condWait(gCTConditionVar(), gCTMutex());
}
}
umtx_unlock(&gCTMutex);
umtx_unlock(gCTMutex());
const UCTMultiThreadItem *result =
new UCTMultiThreadItem(fLoc.getLanguage());
@ -1306,12 +1318,12 @@ const UCTMultiThreadItem *LocaleCacheKey<UCTMultiThreadItem>::createObject(
// Log that we created an object. The first object was already counted,
// don't do it again.
umtx_lock(&gCTMutex);
umtx_lock(gCTMutex());
if (!firstObject) {
gObjectsCreated += 1;
}
umtx_condBroadcast(&gCTConditionVar);
umtx_unlock(&gCTMutex);
umtx_condBroadcast(gCTConditionVar());
umtx_unlock(gCTMutex());
return result;
}