mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-07 22:44:49 +00:00
ICU-2152 minimize code within mutexes
X-SVN-Rev: 10566
This commit is contained in:
parent
78a9b0d37e
commit
c65df17156
2 changed files with 58 additions and 30 deletions
|
@ -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(®istryMutex);
|
||||
|
||||
|
||||
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(®istryMutex);
|
||||
if (registry == NULL) {
|
||||
registry = _registry;
|
||||
_registry = NULL;
|
||||
|
||||
RemoveTransliterator::registerIDs(); // Must be within mutex
|
||||
EscapeTransliterator::registerIDs();
|
||||
UnescapeTransliterator::registerIDs();
|
||||
NormalizationTransliterator::registerIDs();
|
||||
AnyTransliterator::registerIDs();
|
||||
}
|
||||
umtx_unlock(®istryMutex);
|
||||
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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue