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:
parent
ffd8baf16d
commit
bc4bb89af2
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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(¬ifyLock);
|
||||
Mutex lmx(notifyLock());
|
||||
delete listeners;
|
||||
listeners = NULL;
|
||||
}
|
||||
@ -47,7 +50,7 @@ ICUNotifier::addListener(const EventListener* l, UErrorCode& status)
|
||||
}
|
||||
|
||||
if (acceptsListener(*l)) {
|
||||
Mutex lmx(¬ifyLock);
|
||||
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(¬ifyLock);
|
||||
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(¬ifyLock);
|
||||
Mutex lmx(notifyLock());
|
||||
if (listeners != NULL) {
|
||||
for (int i = 0, e = listeners->size(); i < e; ++i) {
|
||||
EventListener* el = (EventListener*)listeners->elementAt(i);
|
||||
|
@ -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) {
|
||||
|
@ -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, ¤cyNames, &total_currency_name_count, ¤cySymbols, &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
|
||||
|
@ -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
|
||||
|
@ -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(
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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());
|
||||
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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.
|
||||
|
@ -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();
|
||||
{
|
||||
|
@ -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();
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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(),
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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(®istryMutex);
|
||||
umtx_lock(registryMutex());
|
||||
if (HAVE_REGISTRY(ec)) {
|
||||
t = registry->get(id, alias, ec);
|
||||
}
|
||||
umtx_unlock(®istryMutex);
|
||||
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(®istryMutex);
|
||||
umtx_lock(registryMutex());
|
||||
if (HAVE_REGISTRY(ec)) {
|
||||
t = registry->reget(id, parser, alias, ec);
|
||||
}
|
||||
umtx_unlock(®istryMutex);
|
||||
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(®istryMutex);
|
||||
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(®istryMutex);
|
||||
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(®istryMutex);
|
||||
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(®istryMutex);
|
||||
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(®istryMutex);
|
||||
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(®istryMutex);
|
||||
umtx_lock(registryMutex());
|
||||
UErrorCode ec = U_ZERO_ERROR;
|
||||
if (HAVE_REGISTRY(ec)) {
|
||||
result = ®istry->getAvailableID(index);
|
||||
}
|
||||
umtx_unlock(®istryMutex);
|
||||
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(®istryMutex);
|
||||
umtx_lock(registryMutex());
|
||||
if (HAVE_REGISTRY(ec)) {
|
||||
result = registry->getAvailableIDs();
|
||||
}
|
||||
umtx_unlock(®istryMutex);
|
||||
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(®istryMutex);
|
||||
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(®istryMutex);
|
||||
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(®istryMutex);
|
||||
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(®istryMutex);
|
||||
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(®istryMutex);
|
||||
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(®istryMutex);
|
||||
Mutex lock(registryMutex());
|
||||
UErrorCode ec = U_ZERO_ERROR;
|
||||
if (HAVE_REGISTRY(ec)) {
|
||||
_getAvailableVariant(index, source, target, result);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user