Index: source/common/locid.cpp |
diff --git a/source/common/locid.cpp b/source/common/locid.cpp |
index 54d5cdbf3f54fb52c50f68cbb679b1e50a4f7352..f073aadedc89a11ad9c98eaedbfda39c5462d978 100644 |
--- a/source/common/locid.cpp |
+++ b/source/common/locid.cpp |
@@ -1,6 +1,6 @@ |
/* |
********************************************************************** |
- * Copyright (C) 1997-2012, International Business Machines |
+ * Copyright (C) 1997-2014, International Business Machines |
* Corporation and others. All Rights Reserved. |
********************************************************************** |
* |
@@ -42,15 +42,14 @@ |
#include "ucln_cmn.h" |
#include "ustr_imp.h" |
-#define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0])) |
- |
U_CDECL_BEGIN |
static UBool U_CALLCONV locale_cleanup(void); |
U_CDECL_END |
U_NAMESPACE_BEGIN |
-static Locale *gLocaleCache = NULL; |
+static Locale *gLocaleCache = NULL; |
+static UInitOnce gLocaleCacheInitOnce = U_INITONCE_INITIALIZER; |
// gDefaultLocaleMutex protects all access to gDefaultLocalesHashT and gDefaultLocale. |
static UMutex gDefaultLocaleMutex = U_MUTEX_INITIALIZER; |
@@ -106,19 +105,50 @@ static UBool U_CALLCONV locale_cleanup(void) |
{ |
U_NAMESPACE_USE |
- if (gLocaleCache) { |
- delete [] gLocaleCache; |
- gLocaleCache = NULL; |
- } |
+ delete [] gLocaleCache; |
+ gLocaleCache = NULL; |
+ gLocaleCacheInitOnce.reset(); |
if (gDefaultLocalesHashT) { |
uhash_close(gDefaultLocalesHashT); // Automatically deletes all elements, using deleter func. |
gDefaultLocalesHashT = NULL; |
- gDefaultLocale = NULL; |
} |
- |
+ gDefaultLocale = NULL; |
return TRUE; |
} |
+ |
+ |
+static void U_CALLCONV locale_init(UErrorCode &status) { |
+ U_NAMESPACE_USE |
+ |
+ U_ASSERT(gLocaleCache == NULL); |
+ gLocaleCache = new Locale[(int)eMAX_LOCALES]; |
+ if (gLocaleCache == NULL) { |
+ status = U_MEMORY_ALLOCATION_ERROR; |
+ return; |
+ } |
+ ucln_common_registerCleanup(UCLN_COMMON_LOCALE, locale_cleanup); |
+ gLocaleCache[eROOT] = Locale(""); |
+ gLocaleCache[eENGLISH] = Locale("en"); |
+ gLocaleCache[eFRENCH] = Locale("fr"); |
+ gLocaleCache[eGERMAN] = Locale("de"); |
+ gLocaleCache[eITALIAN] = Locale("it"); |
+ gLocaleCache[eJAPANESE] = Locale("ja"); |
+ gLocaleCache[eKOREAN] = Locale("ko"); |
+ gLocaleCache[eCHINESE] = Locale("zh"); |
+ gLocaleCache[eFRANCE] = Locale("fr", "FR"); |
+ gLocaleCache[eGERMANY] = Locale("de", "DE"); |
+ gLocaleCache[eITALY] = Locale("it", "IT"); |
+ gLocaleCache[eJAPAN] = Locale("ja", "JP"); |
+ gLocaleCache[eKOREA] = Locale("ko", "KR"); |
+ gLocaleCache[eCHINA] = Locale("zh", "CN"); |
+ gLocaleCache[eTAIWAN] = Locale("zh", "TW"); |
+ gLocaleCache[eUK] = Locale("en", "GB"); |
+ gLocaleCache[eUS] = Locale("en", "US"); |
+ gLocaleCache[eCANADA] = Locale("en", "CA"); |
+ gLocaleCache[eCANADA_FRENCH] = Locale("fr", "CA"); |
+} |
+ |
U_CDECL_END |
U_NAMESPACE_BEGIN |
@@ -126,7 +156,7 @@ U_NAMESPACE_BEGIN |
Locale *locale_set_default_internal(const char *id, UErrorCode& status) { |
// Synchronize this entire function. |
Mutex lock(&gDefaultLocaleMutex); |
- |
+ |
UBool canonicalize = FALSE; |
// If given a NULL string for the locale id, grab the default |
@@ -390,11 +420,6 @@ Locale &Locale::operator=(const Locale &other) |
return *this; |
} |
- if (&other == NULL) { |
- this->setToBogus(); |
- return *this; |
- } |
- |
/* Free our current storage */ |
if(fullName != fullNameBuffer) { |
uprv_free(fullName); |
@@ -484,13 +509,6 @@ Locale& Locale::init(const char* localeID, UBool canonicalize) |
/* preset all fields to empty */ |
language[0] = script[0] = country[0] = 0; |
- // Need to reset baseName. Otherwise, when a Locale object created with |
- // the default constructor is changed with setFromPOSIXID() later |
- // (e.g. locales obtained with getAvailableLocales()), |
- // baseName will be still that of the default locale instead of one |
- // corresponding to localeID. |
- baseName = NULL; |
- |
// "canonicalize" the locale ID to ICU/Java format |
err = U_ZERO_ERROR; |
length = canonicalize ? |
@@ -849,46 +867,8 @@ initialization and static destruction. |
Locale * |
Locale::getLocaleCache(void) |
{ |
- umtx_lock(NULL); |
- UBool needInit = (gLocaleCache == NULL); |
- umtx_unlock(NULL); |
- |
- if (needInit) { |
- Locale *tLocaleCache = new Locale[(int)eMAX_LOCALES]; |
- if (tLocaleCache == NULL) { |
- return NULL; |
- } |
- tLocaleCache[eROOT] = Locale(""); |
- tLocaleCache[eENGLISH] = Locale("en"); |
- tLocaleCache[eFRENCH] = Locale("fr"); |
- tLocaleCache[eGERMAN] = Locale("de"); |
- tLocaleCache[eITALIAN] = Locale("it"); |
- tLocaleCache[eJAPANESE] = Locale("ja"); |
- tLocaleCache[eKOREAN] = Locale("ko"); |
- tLocaleCache[eCHINESE] = Locale("zh"); |
- tLocaleCache[eFRANCE] = Locale("fr", "FR"); |
- tLocaleCache[eGERMANY] = Locale("de", "DE"); |
- tLocaleCache[eITALY] = Locale("it", "IT"); |
- tLocaleCache[eJAPAN] = Locale("ja", "JP"); |
- tLocaleCache[eKOREA] = Locale("ko", "KR"); |
- tLocaleCache[eCHINA] = Locale("zh", "CN"); |
- tLocaleCache[eTAIWAN] = Locale("zh", "TW"); |
- tLocaleCache[eUK] = Locale("en", "GB"); |
- tLocaleCache[eUS] = Locale("en", "US"); |
- tLocaleCache[eCANADA] = Locale("en", "CA"); |
- tLocaleCache[eCANADA_FRENCH] = Locale("fr", "CA"); |
- |
- umtx_lock(NULL); |
- if (gLocaleCache == NULL) { |
- gLocaleCache = tLocaleCache; |
- tLocaleCache = NULL; |
- ucln_common_registerCleanup(UCLN_COMMON_LOCALE, locale_cleanup); |
- } |
- umtx_unlock(NULL); |
- if (tLocaleCache) { |
- delete [] tLocaleCache; // Fancy array delete will destruct each member. |
- } |
- } |
+ UErrorCode status = U_ZERO_ERROR; |
+ umtx_initOnce(gLocaleCacheInitOnce, locale_init, status); |
return gLocaleCache; |
} |