ICU-2152 minimize code within mutexes

X-SVN-Rev: 10566
This commit is contained in:
Alan Liu 2002-12-09 22:58:27 +00:00
parent 78a9b0d37e
commit c65df17156
2 changed files with 58 additions and 30 deletions

View file

@ -1317,18 +1317,19 @@ UChar Transliterator::filteredCharAt(const Replaceable& text, int32_t i) const {
#endif
void Transliterator::initializeRegistry(void) {
// Lock first, check registry pointer second
Mutex lock(&registryMutex);
void Transliterator::initializeRegistry(void) {
if (registry != 0) {
// We were blocked by another thread in initializeRegistry()
return;
}
UErrorCode status = U_ZERO_ERROR;
registry = new TransliteratorRegistry(status);
if (registry == 0 || U_FAILURE(status)) {
TransliteratorRegistry* _registry = new TransliteratorRegistry(status);
if (_registry == 0 || U_FAILURE(status)) {
return; // out of memory, no recovery
}
@ -1385,12 +1386,12 @@ void Transliterator::initializeRegistry(void) {
(ures_getUnicodeStringByIndex(colBund, 3, &status).charAt(0) ==
0x0046 /*F*/) ?
UTRANS_FORWARD : UTRANS_REVERSE;
registry->put(id, resString, dir, visible);
_registry->put(id, resString, dir, visible);
}
break;
case 0x61: // 'a'
// 'alias'; row[2]=createInstance argument
registry->put(id, resString, TRUE);
_registry->put(id, resString, TRUE);
break;
}
}
@ -1403,26 +1404,38 @@ void Transliterator::initializeRegistry(void) {
ures_close(transIDs);
ures_close(bundle);
_registerSpecialInverse(NullTransliterator::SHORT_ID,
NullTransliterator::SHORT_ID, FALSE);
// Manually add prototypes that the system knows about to the
// cache. This is how new non-rule-based transliterators are
// added to the system.
registry->put(new NullTransliterator(), TRUE);
registry->put(new LowercaseTransliterator(), TRUE);
registry->put(new UppercaseTransliterator(), TRUE);
registry->put(new TitlecaseTransliterator(), TRUE);
_registry->put(new NullTransliterator(), TRUE);
_registry->put(new LowercaseTransliterator(), TRUE);
_registry->put(new UppercaseTransliterator(), TRUE);
_registry->put(new TitlecaseTransliterator(), TRUE);
_registry->put(new UnicodeNameTransliterator(), TRUE);
_registry->put(new NameUnicodeTransliterator(), TRUE);
// Keep the number of operations within the mutex to a minimum.
// The SUBCLASS::registerIDs() calls must occur within the mutex.
umtx_lock(&registryMutex);
if (registry == NULL) {
registry = _registry;
_registry = NULL;
RemoveTransliterator::registerIDs(); // Must be within mutex
EscapeTransliterator::registerIDs();
UnescapeTransliterator::registerIDs();
NormalizationTransliterator::registerIDs();
AnyTransliterator::registerIDs();
}
umtx_unlock(&registryMutex);
delete _registry;
_registerSpecialInverse(NullTransliterator::SHORT_ID,
NullTransliterator::SHORT_ID, FALSE);
_registerSpecialInverse("Upper", "Lower", TRUE);
_registerSpecialInverse("Title", "Lower", FALSE);
registry->put(new UnicodeNameTransliterator(), TRUE);
registry->put(new NameUnicodeTransliterator(), TRUE);
RemoveTransliterator::registerIDs();
EscapeTransliterator::registerIDs();
UnescapeTransliterator::registerIDs();
NormalizationTransliterator::registerIDs();
AnyTransliterator::registerIDs();
ucln_i18n_registerCleanup();
}

View file

@ -632,11 +632,17 @@ void TransliteratorIDParser::registerSpecialInverse(const UnicodeString& target,
const UnicodeString& inverseTarget,
UBool bidirectional) {
init();
// If target == inverseTarget then force bidirectional => FALSE
if (bidirectional && 0==target.caseCompare(inverseTarget, U_FOLD_CASE_DEFAULT)) {
bidirectional = FALSE;
}
Mutex lock(&LOCK);
UErrorCode ec = U_ZERO_ERROR;
SPECIAL_INVERSES->put(target, new UnicodeString(inverseTarget), ec);
if (bidirectional && 0!=target.caseCompare(inverseTarget, U_FOLD_CASE_DEFAULT)) {
if (bidirectional) {
SPECIAL_INVERSES->put(inverseTarget, new UnicodeString(target), ec);
}
}
@ -821,9 +827,13 @@ TransliteratorIDParser::specsToSpecialInverse(const Specs& specs) {
return NULL;
}
init();
Mutex lock(&LOCK);
UnicodeString* inverseTarget = (UnicodeString*) SPECIAL_INVERSES->get(
specs.target);
UnicodeString* inverseTarget;
umtx_lock(&LOCK);
inverseTarget = (UnicodeString*) SPECIAL_INVERSES->get(specs.target);
umtx_unlock(&LOCK);
if (inverseTarget != NULL) {
// If the original ID contained "Any-" then make the
// special inverse "Any-Foo"; otherwise make it "Foo".
@ -862,15 +872,20 @@ Transliterator* TransliteratorIDParser::createBasicInstance(const UnicodeString&
* Initialize static memory.
*/
void TransliteratorIDParser::init() {
// Lock first, check static pointer second
Mutex lock(&LOCK);
if (SPECIAL_INVERSES != 0) {
// We were blocked by another thread in this method
if (SPECIAL_INVERSES != NULL) {
return;
}
SPECIAL_INVERSES = new Hashtable(TRUE);
SPECIAL_INVERSES->setValueDeleter(uhash_deleteUnicodeString);
Hashtable* special_inverses = new Hashtable(TRUE);
special_inverses->setValueDeleter(uhash_deleteUnicodeString);
umtx_lock(&LOCK);
if (SPECIAL_INVERSES == NULL) {
SPECIAL_INVERSES = special_inverses;
special_inverses = NULL;
}
umtx_unlock(&LOCK);
delete special_inverses;
ucln_i18n_registerCleanup();
}