mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-10 07:39:16 +00:00
ICU-5349 Use UMTX_CHECK for double check locking.
X-SVN-Rev: 20176
This commit is contained in:
parent
a981e196f5
commit
dbc0d1d9ee
19 changed files with 49 additions and 76 deletions
|
@ -138,9 +138,7 @@ const LanguageBreakEngine *
|
|||
ICULanguageBreakFactory::getEngineFor(UChar32 c, int32_t breakType) {
|
||||
UBool needsInit;
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
umtx_lock(NULL);
|
||||
needsInit = (UBool)(fEngines == NULL);
|
||||
umtx_unlock(NULL);
|
||||
UMTX_CHECK(NULL, (UBool)(fEngines == NULL), needsInit);
|
||||
|
||||
if (needsInit) {
|
||||
UStack *engines = new UStack(_deleteEngine, NULL, status);
|
||||
|
|
|
@ -303,9 +303,7 @@ static ICULocaleService*
|
|||
getService(void)
|
||||
{
|
||||
UBool needsInit;
|
||||
umtx_lock(NULL);
|
||||
needsInit = (UBool)(gService == NULL);
|
||||
umtx_unlock(NULL);
|
||||
UMTX_CHECK(NULL, (UBool)(gService == NULL), needsInit);
|
||||
|
||||
if (needsInit) {
|
||||
ICULocaleService *tService = new ICUBreakIteratorService();
|
||||
|
|
|
@ -781,9 +781,7 @@ u_getDataDirectory(void) {
|
|||
const char *path = NULL;
|
||||
|
||||
/* if we have the directory, then return it immediately */
|
||||
umtx_lock(NULL);
|
||||
path = gDataDirectory;
|
||||
umtx_unlock(NULL);
|
||||
UMTX_CHECK(NULL, gDataDirectory, path);
|
||||
|
||||
if(path) {
|
||||
return path;
|
||||
|
|
|
@ -1705,9 +1705,7 @@ getLanguageBreakEngineFromFactory(UChar32 c, int32_t breakType)
|
|||
{
|
||||
UBool needsInit;
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
umtx_lock(NULL);
|
||||
needsInit = (UBool)(gLanguageBreakFactories == NULL);
|
||||
umtx_unlock(NULL);
|
||||
UMTX_CHECK(NULL, (UBool)(gLanguageBreakFactories == NULL), needsInit);
|
||||
|
||||
if (needsInit) {
|
||||
UStack *factories = new UStack(_deleteFactory, NULL, status);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
**********************************************************************
|
||||
* Copyright (C) 1997-2004, International Business Machines
|
||||
* Copyright (C) 1997-2006, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
**********************************************************************
|
||||
*
|
||||
|
@ -370,9 +370,7 @@ void ResourceBundle::getVersion(UVersionInfo versionInfo) const {
|
|||
const Locale &ResourceBundle::getLocale(void) const
|
||||
{
|
||||
UBool needInit;
|
||||
umtx_lock(NULL);
|
||||
needInit = (fLocale == NULL);
|
||||
umtx_unlock(NULL);
|
||||
UMTX_CHECK(NULL, (fLocale == NULL), needInit);
|
||||
if(needInit) {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
const char *localeName = ures_getLocale(fResource, &status);
|
||||
|
|
|
@ -209,9 +209,7 @@ static UHashtable *udata_getHashTable() {
|
|||
UBool cacheIsInitialized;
|
||||
UHashtable *tHT = NULL;
|
||||
|
||||
umtx_lock(NULL);
|
||||
cacheIsInitialized = (gCommonDataCache != NULL);
|
||||
umtx_unlock(NULL);
|
||||
UMTX_CHECK(NULL, (gCommonDataCache != NULL), cacheIsInitialized);
|
||||
|
||||
if (cacheIsInitialized) {
|
||||
return gCommonDataCache;
|
||||
|
|
|
@ -2621,9 +2621,7 @@ static void _load_installedLocales()
|
|||
{
|
||||
UBool localesLoaded;
|
||||
|
||||
umtx_lock(NULL);
|
||||
localesLoaded = _installedLocales != NULL;
|
||||
umtx_unlock(NULL);
|
||||
UMTX_CHECK(NULL, _installedLocales != NULL, localesLoaded);
|
||||
|
||||
if (localesLoaded == FALSE) {
|
||||
UResourceBundle *index = NULL;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
**********************************************************************
|
||||
* Copyright (C) 1997-2005, International Business Machines
|
||||
* Copyright (C) 1997-2006, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
**********************************************************************
|
||||
*
|
||||
|
@ -57,14 +57,14 @@
|
|||
#if UMTX_STRONG_MEMORY_MODEL
|
||||
|
||||
#define UMTX_CHECK(pMutex, expression, result) \
|
||||
(result)=(expression);
|
||||
(result)=(expression)
|
||||
|
||||
#else
|
||||
|
||||
#define UMTX_CHECK(pMutex, expression, result) \
|
||||
umtx_lock(pMutex); \
|
||||
(result)=(expression); \
|
||||
umtx_unlock(pMutex);
|
||||
umtx_unlock(pMutex)
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -169,6 +169,11 @@ typedef unsigned int uint32_t;
|
|||
/* 1 or 0 to enable or disable threads. If undefined, default is: enable threads. */
|
||||
#define ICU_USE_THREADS @ICU_USE_THREADS@
|
||||
|
||||
/* On strong memory model CPUs (e.g. x86 CPUs), we use a safe & quick double check lock. */
|
||||
#if defined(__GNUC__) && (defined(__i386__) || defined(__amd64__))
|
||||
#define UMTX_STRONG_MEMORY_MODEL 1
|
||||
#endif
|
||||
|
||||
#ifndef U_DEBUG
|
||||
#define U_DEBUG @ENABLE_DEBUG@
|
||||
#endif
|
||||
|
|
|
@ -1207,10 +1207,9 @@ static UBool U_CALLCONV uset_cleanup(void) {
|
|||
U_CDECL_END
|
||||
|
||||
const UnicodeSet* UnicodeSet::getInclusions(int32_t src, UErrorCode &status) {
|
||||
umtx_lock(NULL);
|
||||
UBool f = (INCLUSIONS[src] == NULL);
|
||||
umtx_unlock(NULL);
|
||||
if (f) {
|
||||
UBool needInit;
|
||||
UMTX_CHECK(NULL, (INCLUSIONS[src] == NULL), needInit);
|
||||
if (needInit) {
|
||||
UnicodeSet* incl = new UnicodeSet();
|
||||
USetAdder sa = {
|
||||
(USet *)incl,
|
||||
|
|
|
@ -210,9 +210,7 @@ static UBool U_CALLCONV ures_cleanup(void)
|
|||
/** INTERNAL: Initializes the cache for resources */
|
||||
static void initCache(UErrorCode *status) {
|
||||
UBool makeCache = FALSE;
|
||||
umtx_lock(&resbMutex);
|
||||
makeCache = (cache == NULL);
|
||||
umtx_unlock(&resbMutex);
|
||||
UMTX_CHECK(&resbMutex, (cache == NULL), makeCache);
|
||||
if(makeCache) {
|
||||
UHashtable *newCache = uhash_open(hashEntry, compareEntries, NULL, status);
|
||||
if (U_FAILURE(*status)) {
|
||||
|
|
|
@ -192,10 +192,8 @@ usprep_init() {
|
|||
/** Initializes the cache for resources */
|
||||
static void
|
||||
initCache(UErrorCode *status) {
|
||||
UBool makeCache = FALSE;
|
||||
umtx_lock(&usprepMutex);
|
||||
makeCache = (SHARED_DATA_HASHTABLE == NULL);
|
||||
umtx_unlock(&usprepMutex);
|
||||
UBool makeCache;
|
||||
UMTX_CHECK(&usprepMutex, (SHARED_DATA_HASHTABLE == NULL), makeCache);
|
||||
if(makeCache) {
|
||||
UHashtable *newCache = uhash_open(hashEntry, compareEntries, NULL, status);
|
||||
if (U_SUCCESS(*status)) {
|
||||
|
|
|
@ -76,9 +76,7 @@ void CharsetDetector::setRecognizers(UErrorCode &status)
|
|||
return;
|
||||
}
|
||||
|
||||
umtx_lock(NULL);
|
||||
needsInit = (UBool) (fCSRecognizers == NULL);
|
||||
umtx_unlock(NULL);
|
||||
UMTX_CHECK(NULL, (UBool) (fCSRecognizers == NULL), needsInit);
|
||||
|
||||
if (needsInit) {
|
||||
CharsetRecognizer *tempArray[] = {
|
||||
|
|
|
@ -585,26 +585,22 @@ static ICULocaleService*
|
|||
getNumberFormatService(void)
|
||||
{
|
||||
UBool needInit;
|
||||
{
|
||||
Mutex mutex;
|
||||
needInit = (UBool)(gService == NULL);
|
||||
}
|
||||
UMTX_CHECK(NULL, (UBool)(gService == NULL), needInit);
|
||||
if (needInit) {
|
||||
ICULocaleService * newservice = new ICUNumberFormatService();
|
||||
if (newservice) {
|
||||
Mutex mutex;
|
||||
umtx_lock(NULL);
|
||||
if (gService == NULL) {
|
||||
gService = newservice;
|
||||
newservice = NULL;
|
||||
}
|
||||
umtx_unlock(NULL);
|
||||
}
|
||||
if (newservice) {
|
||||
delete newservice;
|
||||
} else {
|
||||
// we won the contention, this thread can register cleanup.
|
||||
#if !UCONFIG_NO_SERVICE
|
||||
ucln_i18n_registerCleanup(UCLN_I18N_NUMFMT, numfmt_cleanup);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return gService;
|
||||
|
@ -629,9 +625,8 @@ UBool U_EXPORT2
|
|||
NumberFormat::unregister(URegistryKey key, UErrorCode& status)
|
||||
{
|
||||
if (U_SUCCESS(status)) {
|
||||
umtx_lock(NULL);
|
||||
UBool haveService = gService != NULL;
|
||||
umtx_unlock(NULL);
|
||||
UBool haveService;
|
||||
UMTX_CHECK(NULL, gService != NULL, haveService);
|
||||
if (haveService) {
|
||||
return gService->unregister(key, status);
|
||||
}
|
||||
|
@ -657,9 +652,8 @@ NumberFormat* U_EXPORT2
|
|||
NumberFormat::createInstance(const Locale& loc, EStyles kind, UErrorCode& status)
|
||||
{
|
||||
#if !UCONFIG_NO_SERVICE
|
||||
umtx_lock(NULL);
|
||||
UBool haveService = gService != NULL;
|
||||
umtx_unlock(NULL);
|
||||
UBool haveService;
|
||||
UMTX_CHECK(NULL, gService != NULL, haveService);
|
||||
if (haveService) {
|
||||
return (NumberFormat*)gService->get(loc, kind, status);
|
||||
}
|
||||
|
|
|
@ -244,13 +244,12 @@ RuleBasedTransliterator::handleTransliterate(Replaceable& text, UTransPosition&
|
|||
// so no concurrent access from multiple threads is possible.
|
||||
UBool lockedMutexAtThisLevel = FALSE;
|
||||
if (isDataOwned == FALSE) {
|
||||
umtx_lock(NULL);
|
||||
// Test whether this request is operating on the same text string as some
|
||||
// some other transliteration that is still in progress and holding the
|
||||
// transliteration mutex. If so, do not lock the transliteration
|
||||
// mutex again.
|
||||
UBool needToLock = (&text != gLockedText);
|
||||
umtx_unlock(NULL);
|
||||
// Test whether this request is operating on the same text string as some
|
||||
// some other transliteration that is still in progress and holding the
|
||||
// transliteration mutex. If so, do not lock the transliteration
|
||||
// mutex again.
|
||||
UBool needToLock;
|
||||
UMTX_CHECK(NULL, (&text != gLockedText), needToLock);
|
||||
if (needToLock) {
|
||||
umtx_lock(&transliteratorDataMutex);
|
||||
gLockedText = &text;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//
|
||||
// regexst.h
|
||||
//
|
||||
// Copyright (C) 2004, International Business Machines Corporation and others.
|
||||
// Copyright (C) 2004-2006, International Business Machines Corporation and others.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// This file contains class RegexStaticSets
|
||||
|
@ -262,9 +262,8 @@ regex_cleanup(void) {
|
|||
U_CDECL_END
|
||||
|
||||
void RegexStaticSets::initGlobals(UErrorCode *status) {
|
||||
umtx_lock(NULL);
|
||||
RegexStaticSets *p = gStaticSets;
|
||||
umtx_unlock(NULL);
|
||||
RegexStaticSets *p;
|
||||
UMTX_CHECK(NULL, gStaticSets, p);
|
||||
if (p == NULL) {
|
||||
p = new RegexStaticSets(status);
|
||||
if (U_FAILURE(*status)) {
|
||||
|
|
|
@ -605,11 +605,10 @@ TimeZone::initDefault()
|
|||
TimeZone* U_EXPORT2
|
||||
TimeZone::createDefault()
|
||||
{
|
||||
umtx_init(&LOCK); /* This is here to prevent race conditions. */
|
||||
umtx_lock(&LOCK);
|
||||
UBool f = (DEFAULT_ZONE != 0);
|
||||
umtx_unlock(&LOCK);
|
||||
if (!f) {
|
||||
/* This is here to prevent race conditions. */
|
||||
UBool needsInit;
|
||||
UMTX_CHECK(&LOCK, (DEFAULT_ZONE == 0), needsInit);
|
||||
if (needsInit) {
|
||||
initDefault();
|
||||
}
|
||||
|
||||
|
|
|
@ -1159,11 +1159,10 @@ ucol_initUCA(UErrorCode *status) {
|
|||
if(U_FAILURE(*status)) {
|
||||
return NULL;
|
||||
}
|
||||
umtx_lock(NULL);
|
||||
UBool f = (_staticUCA == NULL);
|
||||
umtx_unlock(NULL);
|
||||
UBool needsInit;
|
||||
UMTX_CHECK(NULL, (_staticUCA == NULL), needsInit);
|
||||
|
||||
if(f) {
|
||||
if(needsInit) {
|
||||
UCollator *newUCA = NULL;
|
||||
UDataMemory *result = udata_openChoice(NULL, UCA_DATA_TYPE, UCA_DATA_NAME, isAcceptableUCA, NULL, status);
|
||||
|
||||
|
|
|
@ -1235,11 +1235,10 @@ ucol_initInverseUCA(UErrorCode *status)
|
|||
{
|
||||
if(U_FAILURE(*status)) return NULL;
|
||||
|
||||
umtx_lock(NULL);
|
||||
UBool f = (_staticInvUCA == NULL);
|
||||
umtx_unlock(NULL);
|
||||
UBool needsInit;
|
||||
UMTX_CHECK(NULL, (_staticInvUCA == NULL), needsInit);
|
||||
|
||||
if(f) {
|
||||
if(needsInit) {
|
||||
InverseUCATableHeader *newInvUCA = NULL;
|
||||
UDataMemory *result = udata_openChoice(NULL, INVC_DATA_TYPE, INVC_DATA_NAME, isAcceptableInvUCA, NULL, status);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue