Index: source/common/udata.cpp |
diff --git a/source/common/udata.cpp b/source/common/udata.cpp |
index 80bea0631ef7dc21b69a4a3dc61fa6b5b5b5edcf..94607468f4582c83d795b78214bded50142c6cc2 100644 |
--- a/source/common/udata.cpp |
+++ b/source/common/udata.cpp |
@@ -1,7 +1,9 @@ |
+// Copyright (C) 2016 and later: Unicode, Inc. and others. |
+// License & terms of use: http://www.unicode.org/copyright.html |
/* |
****************************************************************************** |
* |
-* Copyright (C) 1999-2015, International Business Machines |
+* Copyright (C) 1999-2016, International Business Machines |
* Corporation and others. All Rights Reserved. |
* |
****************************************************************************** |
@@ -77,7 +79,7 @@ U_NAMESPACE_USE |
/* |
* Forward declarations |
*/ |
-static UDataMemory *udata_findCachedData(const char *path); |
+static UDataMemory *udata_findCachedData(const char *path, UErrorCode &err); |
/*********************************************************************** |
* |
@@ -132,13 +134,13 @@ udata_cleanup(void) |
} |
static UBool U_CALLCONV |
-findCommonICUDataByName(const char *inBasename) |
+findCommonICUDataByName(const char *inBasename, UErrorCode &err) |
{ |
UBool found = FALSE; |
int32_t i; |
- UDataMemory *pData = udata_findCachedData(inBasename); |
- if (pData == NULL) |
+ UDataMemory *pData = udata_findCachedData(inBasename, err); |
+ if (U_FAILURE(err) || pData == NULL) |
return FALSE; |
{ |
@@ -268,40 +270,41 @@ static void U_CALLCONV DataCacheElement_deleter(void *pDCEl) { |
uprv_free(pDCEl); /* delete 'this' */ |
} |
-static void udata_initHashTable() { |
- UErrorCode err = U_ZERO_ERROR; |
+static void U_CALLCONV udata_initHashTable(UErrorCode &err) { |
U_ASSERT(gCommonDataCache == NULL); |
gCommonDataCache = uhash_open(uhash_hashChars, uhash_compareChars, NULL, &err); |
if (U_FAILURE(err)) { |
- // TODO: handle errors better. |
- gCommonDataCache = NULL; |
- } |
- if (gCommonDataCache != NULL) { |
- uhash_setValueDeleter(gCommonDataCache, DataCacheElement_deleter); |
- ucln_common_registerCleanup(UCLN_COMMON_UDATA, udata_cleanup); |
+ return; |
} |
+ U_ASSERT(gCommonDataCache != NULL); |
+ uhash_setValueDeleter(gCommonDataCache, DataCacheElement_deleter); |
+ ucln_common_registerCleanup(UCLN_COMMON_UDATA, udata_cleanup); |
} |
/* udata_getCacheHashTable() |
* Get the hash table used to store the data cache entries. |
* Lazy create it if it doesn't yet exist. |
*/ |
-static UHashtable *udata_getHashTable() { |
- umtx_initOnce(gCommonDataCacheInitOnce, &udata_initHashTable); |
+static UHashtable *udata_getHashTable(UErrorCode &err) { |
+ umtx_initOnce(gCommonDataCacheInitOnce, &udata_initHashTable, err); |
return gCommonDataCache; |
} |
-static UDataMemory *udata_findCachedData(const char *path) |
+static UDataMemory *udata_findCachedData(const char *path, UErrorCode &err) |
{ |
UHashtable *htable; |
UDataMemory *retVal = NULL; |
DataCacheElement *el; |
const char *baseName; |
+ htable = udata_getHashTable(err); |
+ if (U_FAILURE(err)) { |
+ return NULL; |
+ } |
+ |
baseName = findBasename(path); /* Cache remembers only the base name, not the full path. */ |
- htable = udata_getHashTable(); |
umtx_lock(NULL); |
el = (DataCacheElement *)uhash_get(htable, baseName); |
umtx_unlock(NULL); |
@@ -323,6 +326,7 @@ static UDataMemory *udata_cacheDataItem(const char *path, UDataMemory *item, UEr |
DataCacheElement *oldValue = NULL; |
UErrorCode subErr = U_ZERO_ERROR; |
+ htable = udata_getHashTable(*pErr); |
if (U_FAILURE(*pErr)) { |
return NULL; |
} |
@@ -355,7 +359,6 @@ static UDataMemory *udata_cacheDataItem(const char *path, UDataMemory *item, UEr |
/* Stick the new DataCacheElement into the hash table. |
*/ |
- htable = udata_getHashTable(); |
umtx_lock(NULL); |
oldValue = (DataCacheElement *)uhash_get(htable, path); |
if (oldValue != NULL) { |
@@ -393,9 +396,6 @@ static UDataMemory *udata_cacheDataItem(const char *path, UDataMemory *item, UEr |
* * |
*----------------------------------------------------------------------*/ |
-#define U_DATA_PATHITER_BUFSIZ 128 /* Size of local buffer for paths */ |
- /* Overflow causes malloc of larger buf */ |
- |
U_NAMESPACE_BEGIN |
class UDataPathIterator |
@@ -717,18 +717,18 @@ openCommonData(const char *path, /* Path from OpenChoice? */ |
#ifdef UDATA_DEBUG |
fprintf(stderr, "ocd: no basename in %s, bailing.\n", path); |
#endif |
- *pErrorCode=U_FILE_ACCESS_ERROR; |
+ if (U_SUCCESS(*pErrorCode)) { |
+ *pErrorCode=U_FILE_ACCESS_ERROR; |
+ } |
return NULL; |
} |
/* Is the requested common data file already open and cached? */ |
/* Note that the cache is keyed by the base name only. The rest of the path, */ |
/* if any, is not considered. */ |
- { |
- UDataMemory *dataToReturn = udata_findCachedData(inBasename); |
- if (dataToReturn != NULL) { |
- return dataToReturn; |
- } |
+ UDataMemory *dataToReturn = udata_findCachedData(inBasename, *pErrorCode); |
+ if (dataToReturn != NULL || U_FAILURE(*pErrorCode)) { |
+ return dataToReturn; |
} |
/* Requested item is not in the cache. |
@@ -759,6 +759,9 @@ openCommonData(const char *path, /* Path from OpenChoice? */ |
} |
#endif |
+ if (U_FAILURE(*pErrorCode)) { |
+ return NULL; |
+ } |
if (!UDataMemory_isLoaded(&tData)) { |
/* no common data */ |
*pErrorCode=U_FILE_ACCESS_ERROR; |
@@ -834,7 +837,7 @@ static UBool extendICUData(UErrorCode *pErr) |
umtx_storeRelease(gHaveTriedToLoadCommonData, 1); |
} |
- didUpdate = findCommonICUDataByName(U_ICUDATA_NAME); /* Return 'true' when a racing writes out the extended */ |
+ didUpdate = findCommonICUDataByName(U_ICUDATA_NAME, *pErr); /* Return 'true' when a racing writes out the extended */ |
/* data after another thread has failed to see it (in openCommonData), so */ |
/* extended data can be examined. */ |
/* Also handles a race through here before gHaveTriedToLoadCommonData is set. */ |
@@ -1255,7 +1258,7 @@ doOpenChoice(const char *path, const char *type, const char *name, |
dataPath = u_getDataDirectory(); |
/**** Time zone individual files override */ |
- if (isTimeZoneFile(name, type) && isICUData) { |
+ if (isICUData && isTimeZoneFile(name, type)) { |
const char *tzFilesDir = u_getTimeZoneFilesDirectory(pErrorCode); |
if (tzFilesDir[0] != 0) { |
#ifdef UDATA_DEBUG |