ICU-11776 Thread safety fixes in data loading.
X-SVN-Rev: 37670
This commit is contained in:
parent
9dbf370b21
commit
87da174aa0
@ -1,7 +1,7 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
*
|
||||
* Copyright (C) 1999-2014, International Business Machines
|
||||
* Copyright (C) 1999-2015, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
*
|
||||
******************************************************************************
|
||||
@ -29,6 +29,7 @@ might have to #include some other header
|
||||
#include "charstr.h"
|
||||
#include "cmemory.h"
|
||||
#include "cstring.h"
|
||||
#include "mutex.h"
|
||||
#include "putilimp.h"
|
||||
#include "uassert.h"
|
||||
#include "ucln_cmn.h"
|
||||
@ -100,14 +101,15 @@ static UDataMemory *udata_findCachedData(const char *path);
|
||||
* that they really need, reducing the size of binaries that take advantage
|
||||
* of this.
|
||||
*/
|
||||
static UDataMemory *gCommonICUDataArray[10] = { NULL };
|
||||
static UDataMemory *gCommonICUDataArray[10] = { NULL }; // Access protected by icu global mutex.
|
||||
|
||||
static UBool gHaveTriedToLoadCommonData = FALSE; /* See extendICUData(). */
|
||||
static u_atomic_int32_t gHaveTriedToLoadCommonData = ATOMIC_INT32_T_INITIALIZER(0); // See extendICUData().
|
||||
|
||||
static UHashtable *gCommonDataCache = NULL; /* Global hash table of opened ICU data files. */
|
||||
static icu::UInitOnce gCommonDataCacheInitOnce = U_INITONCE_INITIALIZER;
|
||||
|
||||
static UDataFileAccess gDataFileAccess = UDATA_DEFAULT_ACCESS;
|
||||
static UDataFileAccess gDataFileAccess = UDATA_DEFAULT_ACCESS; // Access not synchronized.
|
||||
// Modifying is documented as thread-unsafe.
|
||||
|
||||
static UBool U_CALLCONV
|
||||
udata_cleanup(void)
|
||||
@ -124,7 +126,7 @@ udata_cleanup(void)
|
||||
udata_close(gCommonICUDataArray[i]);
|
||||
gCommonICUDataArray[i] = NULL;
|
||||
}
|
||||
gHaveTriedToLoadCommonData = FALSE;
|
||||
gHaveTriedToLoadCommonData = 0;
|
||||
|
||||
return TRUE; /* Everything was cleaned up */
|
||||
}
|
||||
@ -139,6 +141,8 @@ findCommonICUDataByName(const char *inBasename)
|
||||
if (pData == NULL)
|
||||
return FALSE;
|
||||
|
||||
{
|
||||
Mutex lock;
|
||||
for (i = 0; i < UPRV_LENGTHOF(gCommonICUDataArray); ++i) {
|
||||
if ((gCommonICUDataArray[i] != NULL) && (gCommonICUDataArray[i]->pHeader == pData->pHeader)) {
|
||||
/* The data pointer is already in the array. */
|
||||
@ -146,7 +150,7 @@ findCommonICUDataByName(const char *inBasename)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
@ -663,7 +667,11 @@ openCommonData(const char *path, /* Path from OpenChoice? */
|
||||
if(commonDataIndex >= UPRV_LENGTHOF(gCommonICUDataArray)) {
|
||||
return NULL;
|
||||
}
|
||||
if(gCommonICUDataArray[commonDataIndex] == NULL) {
|
||||
{
|
||||
Mutex lock;
|
||||
if(gCommonICUDataArray[commonDataIndex] != NULL) {
|
||||
return gCommonICUDataArray[commonDataIndex];
|
||||
}
|
||||
int32_t i;
|
||||
for(i = 0; i < commonDataIndex; ++i) {
|
||||
if(gCommonICUDataArray[i]->pHeader == &U_ICUDATA_ENTRY_POINT) {
|
||||
@ -671,6 +679,7 @@ openCommonData(const char *path, /* Path from OpenChoice? */
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Add the linked-in data to the list. */
|
||||
/*
|
||||
@ -686,9 +695,11 @@ openCommonData(const char *path, /* Path from OpenChoice? */
|
||||
}
|
||||
*/
|
||||
setCommonICUDataPointer(&U_ICUDATA_ENTRY_POINT, FALSE, pErrorCode);
|
||||
}
|
||||
{
|
||||
Mutex lock;
|
||||
return gCommonICUDataArray[commonDataIndex];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* request is NOT for ICU Data. */
|
||||
@ -795,7 +806,7 @@ static UBool extendICUData(UErrorCode *pErr)
|
||||
static UMutex extendICUDataMutex = U_MUTEX_INITIALIZER;
|
||||
umtx_lock(&extendICUDataMutex);
|
||||
#endif
|
||||
if(!gHaveTriedToLoadCommonData) {
|
||||
if(!umtx_loadAcquire(gHaveTriedToLoadCommonData)) {
|
||||
/* See if we can explicitly open a .dat file for the ICUData. */
|
||||
pData = openCommonData(
|
||||
U_ICUDATA_NAME, /* "icudt20l" , for example. */
|
||||
@ -820,7 +831,7 @@ static UBool extendICUData(UErrorCode *pErr)
|
||||
pErr); /* setCommonICUData honors errors; NOP if error set */
|
||||
}
|
||||
|
||||
gHaveTriedToLoadCommonData = TRUE;
|
||||
umtx_storeRelease(gHaveTriedToLoadCommonData, 1);
|
||||
}
|
||||
|
||||
didUpdate = findCommonICUDataByName(U_ICUDATA_NAME); /* Return 'true' when a racing writes out the extended */
|
||||
@ -1398,5 +1409,6 @@ udata_getInfo(UDataMemory *pData, UDataInfo *pInfo) {
|
||||
|
||||
U_CAPI void U_EXPORT2 udata_setFileAccess(UDataFileAccess access, UErrorCode * /*status*/)
|
||||
{
|
||||
// Note: this function is documented as not thread safe.
|
||||
gDataFileAccess = access;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user