Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(206)

Side by Side Diff: source/common/locutil.cpp

Issue 845603002: Update ICU to 54.1 step 1 (Closed) Base URL: https://chromium.googlesource.com/chromium/deps/icu.git@master
Patch Set: remove unusued directories Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « source/common/locmap.c ('k') | source/common/norm2_nfc_data.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 ******************************************************************************* 2 *******************************************************************************
3 * Copyright (C) 2002-2011, International Business Machines Corporation and 3 * Copyright (C) 2002-2014, International Business Machines Corporation and
4 * others. All Rights Reserved. 4 * others. All Rights Reserved.
5 ******************************************************************************* 5 *******************************************************************************
6 */ 6 */
7 #include "unicode/utypes.h" 7 #include "unicode/utypes.h"
8 8
9 #if !UCONFIG_NO_SERVICE || !UCONFIG_NO_TRANSLITERATION 9 #if !UCONFIG_NO_SERVICE || !UCONFIG_NO_TRANSLITERATION
10 10
11 #include "unicode/resbund.h" 11 #include "unicode/resbund.h"
12 #include "cmemory.h" 12 #include "cmemory.h"
13 #include "ustrfmt.h" 13 #include "ustrfmt.h"
14 #include "locutil.h" 14 #include "locutil.h"
15 #include "charstr.h" 15 #include "charstr.h"
16 #include "ucln_cmn.h" 16 #include "ucln_cmn.h"
17 #include "uassert.h" 17 #include "uassert.h"
18 #include "umutex.h" 18 #include "umutex.h"
19 19
20 // see LocaleUtility::getAvailableLocaleNames 20 // see LocaleUtility::getAvailableLocaleNames
21 static icu::UInitOnce LocaleUtilityInitOnce = U_INITONCE_INITIALIZER;
21 static icu::Hashtable * LocaleUtility_cache = NULL; 22 static icu::Hashtable * LocaleUtility_cache = NULL;
22 23
23 #define UNDERSCORE_CHAR ((UChar)0x005f) 24 #define UNDERSCORE_CHAR ((UChar)0x005f)
24 #define AT_SIGN_CHAR ((UChar)64) 25 #define AT_SIGN_CHAR ((UChar)64)
25 #define PERIOD_CHAR ((UChar)46) 26 #define PERIOD_CHAR ((UChar)46)
26 27
27 /* 28 /*
28 ****************************************************************** 29 ******************************************************************
29 */ 30 */
30 31
31 /** 32 /**
32 * Release all static memory held by Locale Utility. 33 * Release all static memory held by Locale Utility.
33 */ 34 */
34 U_CDECL_BEGIN 35 U_CDECL_BEGIN
35 static UBool U_CALLCONV service_cleanup(void) { 36 static UBool U_CALLCONV service_cleanup(void) {
36 if (LocaleUtility_cache) { 37 if (LocaleUtility_cache) {
37 delete LocaleUtility_cache; 38 delete LocaleUtility_cache;
38 LocaleUtility_cache = NULL; 39 LocaleUtility_cache = NULL;
39 } 40 }
40 return TRUE; 41 return TRUE;
41 } 42 }
43
44
45 static void U_CALLCONV locale_utility_init(UErrorCode &status) {
46 using namespace icu;
47 U_ASSERT(LocaleUtility_cache == NULL);
48 ucln_common_registerCleanup(UCLN_COMMON_SERVICE, service_cleanup);
49 LocaleUtility_cache = new Hashtable(status);
50 if (U_FAILURE(status)) {
51 delete LocaleUtility_cache;
52 LocaleUtility_cache = NULL;
53 return;
54 }
55 if (LocaleUtility_cache == NULL) {
56 status = U_MEMORY_ALLOCATION_ERROR;
57 return;
58 }
59 LocaleUtility_cache->setValueDeleter(uhash_deleteHashtable);
60 }
61
42 U_CDECL_END 62 U_CDECL_END
43 63
44 U_NAMESPACE_BEGIN 64 U_NAMESPACE_BEGIN
45 65
46 UnicodeString& 66 UnicodeString&
47 LocaleUtility::canonicalLocaleString(const UnicodeString* id, UnicodeString& res ult) 67 LocaleUtility::canonicalLocaleString(const UnicodeString* id, UnicodeString& res ult)
48 { 68 {
49 if (id == NULL) { 69 if (id == NULL) {
50 result.setToBogus(); 70 result.setToBogus();
51 } else { 71 } else {
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 LocaleUtility::getAvailableLocaleNames(const UnicodeString& bundleID) 202 LocaleUtility::getAvailableLocaleNames(const UnicodeString& bundleID)
183 { 203 {
184 // LocaleUtility_cache is a hash-of-hashes. The top-level keys 204 // LocaleUtility_cache is a hash-of-hashes. The top-level keys
185 // are path strings ('bundleID') passed to 205 // are path strings ('bundleID') passed to
186 // ures_openAvailableLocales. The top-level values are 206 // ures_openAvailableLocales. The top-level values are
187 // second-level hashes. The second-level keys are result strings 207 // second-level hashes. The second-level keys are result strings
188 // from ures_openAvailableLocales. The second-level values are 208 // from ures_openAvailableLocales. The second-level values are
189 // garbage ((void*)1 or other random pointer). 209 // garbage ((void*)1 or other random pointer).
190 210
191 UErrorCode status = U_ZERO_ERROR; 211 UErrorCode status = U_ZERO_ERROR;
192 Hashtable* cache; 212 umtx_initOnce(LocaleUtilityInitOnce, locale_utility_init, status);
193 umtx_lock(NULL); 213 Hashtable *cache = LocaleUtility_cache;
194 cache = LocaleUtility_cache;
195 umtx_unlock(NULL);
196
197 if (cache == NULL) { 214 if (cache == NULL) {
198 cache = new Hashtable(status); 215 // Catastrophic failure.
199 if (cache == NULL || U_FAILURE(status)) { 216 return NULL;
200 return NULL; // catastrophic failure; e.g. out of memory
201 }
202 cache->setValueDeleter(uhash_deleteHashtable);
203 Hashtable* h; // set this to final LocaleUtility_cache value
204 umtx_lock(NULL);
205 h = LocaleUtility_cache;
206 if (h == NULL) {
207 LocaleUtility_cache = h = cache;
208 cache = NULL;
209 ucln_common_registerCleanup(UCLN_COMMON_SERVICE, service_cleanup);
210 }
211 umtx_unlock(NULL);
212 if(cache != NULL) {
213 delete cache;
214 }
215 cache = h;
216 } 217 }
217 218
218 U_ASSERT(cache != NULL);
219
220 Hashtable* htp; 219 Hashtable* htp;
221 umtx_lock(NULL); 220 umtx_lock(NULL);
222 htp = (Hashtable*) cache->get(bundleID); 221 htp = (Hashtable*) cache->get(bundleID);
223 umtx_unlock(NULL); 222 umtx_unlock(NULL);
224 223
225 if (htp == NULL) { 224 if (htp == NULL) {
226 htp = new Hashtable(status); 225 htp = new Hashtable(status);
227 if (htp && U_SUCCESS(status)) { 226 if (htp && U_SUCCESS(status)) {
228 CharString cbundleID; 227 CharString cbundleID;
229 cbundleID.appendInvariantChars(bundleID, status); 228 cbundleID.appendInvariantChars(bundleID, status);
230 const char* path = cbundleID.isEmpty() ? NULL : cbundleID.data(); 229 const char* path = cbundleID.isEmpty() ? NULL : cbundleID.data();
231 UEnumeration *uenum = ures_openAvailableLocales(path, &status); 230 UEnumeration *uenum = ures_openAvailableLocales(path, &status);
232 for (;;) { 231 for (;;) {
233 const UChar* id = uenum_unext(uenum, NULL, &status); 232 const UChar* id = uenum_unext(uenum, NULL, &status);
234 if (id == NULL) { 233 if (id == NULL) {
235 break; 234 break;
236 } 235 }
237 htp->put(UnicodeString(id), (void*)htp, status); 236 htp->put(UnicodeString(id), (void*)htp, status);
238 } 237 }
239 uenum_close(uenum); 238 uenum_close(uenum);
240 if (U_FAILURE(status)) { 239 if (U_FAILURE(status)) {
241 delete htp; 240 delete htp;
242 return NULL; 241 return NULL;
243 } 242 }
244 umtx_lock(NULL); 243 umtx_lock(NULL);
245 cache->put(bundleID, (void*)htp, status); 244 Hashtable *t = static_cast<Hashtable *>(cache->get(bundleID));
246 umtx_unlock(NULL); 245 if (t != NULL) {
246 // Another thread raced through this code, creating the cache en try first.
247 // Discard ours and return theirs.
248 umtx_unlock(NULL);
249 delete htp;
250 htp = t;
251 } else {
252 cache->put(bundleID, (void*)htp, status);
253 umtx_unlock(NULL);
254 }
247 } 255 }
248 } 256 }
249 return htp; 257 return htp;
250 } 258 }
251 259
252 UBool 260 UBool
253 LocaleUtility::isFallbackOf(const UnicodeString& root, const UnicodeString& chil d) 261 LocaleUtility::isFallbackOf(const UnicodeString& root, const UnicodeString& chil d)
254 { 262 {
255 return child.indexOf(root) == 0 && 263 return child.indexOf(root) == 0 &&
256 (child.length() == root.length() || 264 (child.length() == root.length() ||
257 child.charAt(root.length()) == UNDERSCORE_CHAR); 265 child.charAt(root.length()) == UNDERSCORE_CHAR);
258 } 266 }
259 267
260 U_NAMESPACE_END 268 U_NAMESPACE_END
261 269
262 /* !UCONFIG_NO_SERVICE */ 270 /* !UCONFIG_NO_SERVICE */
263 #endif 271 #endif
264 272
265 273
OLDNEW
« no previous file with comments | « source/common/locmap.c ('k') | source/common/norm2_nfc_data.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698