]> granicus.if.org Git - icu/commitdiff
ICU-20488 mutex static constructor fixes.
authorAndy Heninger <andy.heninger@gmail.com>
Mon, 11 Mar 2019 23:36:33 +0000 (16:36 -0700)
committerAndy Heninger <andy.heninger@gmail.com>
Tue, 12 Mar 2019 16:52:16 +0000 (09:52 -0700)
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.

38 files changed:
icu4c/source/common/brkeng.cpp
icu4c/source/common/characterproperties.cpp
icu4c/source/common/locdspnm.cpp
icu4c/source/common/locid.cpp
icu4c/source/common/putil.cpp
icu4c/source/common/resbund.cpp
icu4c/source/common/serv.cpp
icu4c/source/common/servls.cpp
icu4c/source/common/servnotf.cpp
icu4c/source/common/ucnv_bld.cpp
icu4c/source/common/ucurr.cpp
icu4c/source/common/umutex.cpp
icu4c/source/common/unifiedcache.cpp
icu4c/source/common/uresbund.cpp
icu4c/source/common/usprep.cpp
icu4c/source/i18n/astro.cpp
icu4c/source/i18n/chnsecal.cpp
icu4c/source/i18n/dtfmtsym.cpp
icu4c/source/i18n/dtitvfmt.cpp
icu4c/source/i18n/gender.cpp
icu4c/source/i18n/islamcal.cpp
icu4c/source/i18n/listformatter.cpp
icu4c/source/i18n/numfmt.cpp
icu4c/source/i18n/rbt.cpp
icu4c/source/i18n/rbtz.cpp
icu4c/source/i18n/reldatefmt.cpp
icu4c/source/i18n/simpletz.cpp
icu4c/source/i18n/smpdtfmt.cpp
icu4c/source/i18n/translit.cpp
icu4c/source/i18n/tridpars.cpp
icu4c/source/i18n/tzfmt.cpp
icu4c/source/i18n/tzgnames.cpp
icu4c/source/i18n/tznames.cpp
icu4c/source/i18n/tznames_impl.cpp
icu4c/source/i18n/zonemeta.cpp
icu4c/source/io/locbund.cpp
icu4c/source/test/intltest/intltest.cpp
icu4c/source/test/intltest/tsmthred.cpp

index 7144af60b2406eb0aed9f6362f013b84cf7840e7..19467dc2526d8a2d1cfa01d2f33855a27cb00c88 100644 (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) {
index 96186e6418192eb2e68073112b91538a4fdb9c94..5a57364375b372269b2b83320b59760b13e7fc8a 100644 (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);
index 2d9389e910a2ab93c3de2b5d2acfe99d71fedf2c..da35be9e766e504246b99ad6b5bff2fb6e6fcefa 100644 (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);
     }
index a6a518201c24f87e3c15d335fc0bb637827f3aef..06986b636adc31ed6b1ac510095b28a99df9965d 100644 (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;
         }
index 9ed85c00a05bb48325e0ce3f52f7a7afed98fa2e..42db744c774d74718106a7accb9c76708ec97cc0 100644 (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();
index 512bd531f231eba754b0f26de6cf631a99d9989c..08cda3a97b5345bc2a3855d305dccea9705e94bb 100644 (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;
index 619e8c7c8bd38c9049b3de85f1323f5e4f529fe5..555c0555dfb341440016a8d127acf280befa8573 100644 (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();
     }
index f4579d0eecde60f5e1c8a50b3037d7cdd6f6c057..90874d11c1443ecfcbf30cfcc71053f61d2e84de 100644 (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) {
index dc77c7b857d290288ffe6b89bf74ab701567895d..1e65a147d856d14f1e404c4007d6b587d0622757 100644 (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);
index 18e46e169556f7de28a75f2e89a7bbc3c6bb66b6..b71be8fdad317d04c9dd6bb244207bd790cf01d2 100644 (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) {
index 802eafba166f6aaf6491f14fc1f8a04dce7a9310..444adc09e0922ff7b50b31709d64d62f203d33c4 100644 (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
index 7873314f1a48f4b57fde9a0658e8e7d5b8754b80..20b03d6cd3e41694af014e4d334a185f0ac5feb3 100644 (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
index 6ad8c3d1c7bf219b059e9b4ed245a338bcc03923..641f4ec6594e12003497fc65bc0ef1dfb911b6a2 100644 (file)
 #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(
index 45bb92b804de102d2d2531d410936261f48b4f9c..af6d1a1f7c1c8f4c1ce15a4f0577dedb491970f2 100644 (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());
 }
 
 /*
index 01238b35f5bb06775373d6752d730d55a4823cd0..a05fae1c68dcb14c888d68e4c77e2172460db0be 100644 (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());
     
 }
 
index bb3701652085feee021e9911247d5d4d8bc57d05..e6dcfe895bb85c0a04c6ba23510b8273f24ed5b3 100644 (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) {
index 69c9040bd3d36c1a9b3004a6f14ba94af6101c52..2472870f7feb36bebcd31d337d419444921cce95 100644 (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;
index ae7d2928ae3429b498464aa5ccf79153138ae7df..42cf5c5e621d096fbde90ecbd34c37df3bc0011e 100644 (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) {
index 1de7652335ba49e8734062a46cafe202cb7ac4da..93ceff3b5acad305de3ef323cff9eeb113d50d03 100644 (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.
index 1456d86276f9152ec08f9c3e60daeda4a7057a03..50161e1468d050f22a864726f7a2f49d9a8fa18d 100644 (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();
   {
index a002262971acd3fb4fb8cd0d2321316c887681e6..a024f4cbfa2b51ffb049b4587f2c2004f7c78cc4 100644 (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();
index ab8ef14311ea6545bf004ac75a83b7b8601d045a..802ab0ef782a1e4b360bc7ca892ecae6f0873eb0 100644 (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) {
index 4b2eaac614785181096058a0dd40d8b63a12dd20..7adf902df4718d89f1e433716adf6584e6a82e23 100644 (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) {
index 9cb1b0e9a70f20f7266305e8c894a6f0e7a40bdd..b4407930d86c9eed0b6233906f9dd0cc73eeff2b 100644 (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;
index d98613fe99ad677bd1ca6a6dfc2b627922d12547..4aa143c706b5b15ad36f572a0419d1a14b7aa051 100644 (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;
     }
index 4f6f7233ddb4450112aa706679813a3a3d4eda37..2b58e47c2578a51d7e11e47e4d68a3b2115695bd 100644 (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(),
index 57a7ba8ed75d219bbe38fead5fcd476f51b2b1d5..cacfa187cfc95e8414d74ef6a11f951031759718 100644 (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);
index 9ab765791fb54477534ae1d494274386145a60d3..be0ced53987f64c388d153ccaf45b580631e39cb 100644 (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;
 }
index 59025be17bd49f8382a521a74aa4af99998eb313..7d9c7192e29df3af934a8f6ec1b9e9e27cfa6b48 100644 (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);
index b27663649ad257b587fb694f4d37e36ef6174157..f54393b6fa531cf000c5d17275633aa3ec33dece 100644 (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
index 4730455ac4eb8113910d7af16578a73b8ed9a82c..5aa7af5b3294fa173059884dc11bf7711993f017 100644 (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;
 }
index 5f5b7db30227cccdc928122302359d1f763fb2d1..4e3ecb4c6073b8c37c9e7106aec740ef5c9a6a12 100644 (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;
 }
index 5a79c22aacf8f970e421aac80c01edeee2e2b320..36d27ca699b1a2713b7d7eb2bf79711695e25731 100644 (file)
 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;
 }
index 7bfbc04e180051243471bcde5fee1536442a0fde..5e3b478c28f4511cc770af70dadc04347b90b56f 100644 (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);
index ddc8e296221593b59ecf223c0c5b40b9e25c483e..0e3ee8931611225f4ea3898f9b5388864bc93073 100644 (file)
 #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;
 }
index b239be6508713e82a54b5f6b26bbd7291313985b..c4ef1952e5fc24caa0d35d7b0cf5ac8acfe39e71 100644 (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) {
index 0cbf12ee4168fa51ad78331d06d5776e1cc58b6a..201c5460ec6705bc516272819662b99588a15ddc 100644 (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
index 9126100d11c627ec3960893e36992e20af411962..2c7528feab955fc7f3e3c175545c44afe9667b2a 100644 (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;
 }