mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-08 06:53:45 +00:00
ICU-12393 better error checking for udata_getHashTable().
X-SVN-Rev: 38585
This commit is contained in:
parent
691dc350e1
commit
ff017c9924
1 changed files with 29 additions and 28 deletions
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
******************************************************************************
|
||||
*
|
||||
* Copyright (C) 1999-2015, International Business Machines
|
||||
* Copyright (C) 1999-2016, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
*
|
||||
******************************************************************************
|
||||
|
@ -77,7 +77,7 @@ U_NAMESPACE_USE
|
|||
/*
|
||||
* Forward declarations
|
||||
*/
|
||||
static UDataMemory *udata_findCachedData(const char *path);
|
||||
static UDataMemory *udata_findCachedData(const char *path, UErrorCode &err);
|
||||
|
||||
/***********************************************************************
|
||||
*
|
||||
|
@ -132,13 +132,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 +268,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 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 +324,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 +357,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 +394,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 +715,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 +757,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 +835,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. */
|
||||
|
|
Loading…
Add table
Reference in a new issue