ICU-5349 Use UMTX_CHECK for double check locking.

X-SVN-Rev: 20176
This commit is contained in:
George Rhoten 2006-08-29 04:57:05 +00:00
parent a981e196f5
commit dbc0d1d9ee
19 changed files with 49 additions and 76 deletions

View file

@ -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);

View file

@ -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();

View file

@ -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;

View file

@ -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);

View file

@ -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);

View file

@ -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;

View file

@ -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;

View file

@ -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

View file

@ -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

View file

@ -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,

View file

@ -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)) {

View file

@ -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)) {

View file

@ -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[] = {

View file

@ -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);
}

View file

@ -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;

View file

@ -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)) {

View file

@ -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();
}

View file

@ -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);

View file

@ -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);