| OLD | NEW |
| 1 /* | 1 /* |
| 2 ********************************************************************** | 2 ********************************************************************** |
| 3 * Copyright (C) 1999-2013, International Business Machines | 3 * Copyright (C) 1999-2015, International Business Machines |
| 4 * Corporation and others. All Rights Reserved. | 4 * Corporation and others. All Rights Reserved. |
| 5 ********************************************************************** | 5 ********************************************************************** |
| 6 * Date Name Description | 6 * Date Name Description |
| 7 * 11/17/99 aliu Creation. | 7 * 11/17/99 aliu Creation. |
| 8 ********************************************************************** | 8 ********************************************************************** |
| 9 */ | 9 */ |
| 10 | 10 |
| 11 #include "unicode/utypes.h" | 11 #include "unicode/utypes.h" |
| 12 | 12 |
| 13 #if !UCONFIG_NO_TRANSLITERATION | 13 #if !UCONFIG_NO_TRANSLITERATION |
| 14 | 14 |
| 15 #include "unicode/rep.h" | 15 #include "unicode/rep.h" |
| 16 #include "unicode/uniset.h" | 16 #include "unicode/uniset.h" |
| 17 #include "rbt_pars.h" | 17 #include "rbt_pars.h" |
| 18 #include "rbt_data.h" | 18 #include "rbt_data.h" |
| 19 #include "rbt_rule.h" | 19 #include "rbt_rule.h" |
| 20 #include "rbt.h" | 20 #include "rbt.h" |
| 21 #include "mutex.h" |
| 21 #include "umutex.h" | 22 #include "umutex.h" |
| 22 | 23 |
| 23 U_NAMESPACE_BEGIN | 24 U_NAMESPACE_BEGIN |
| 24 | 25 |
| 25 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(RuleBasedTransliterator) | 26 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(RuleBasedTransliterator) |
| 26 | 27 |
| 27 static UMutex transliteratorDataMutex = U_MUTEX_INITIALIZER; | 28 static UMutex transliteratorDataMutex = U_MUTEX_INITIALIZER; |
| 28 static Replaceable *gLockedText = NULL; | 29 static Replaceable *gLockedText = NULL; |
| 29 | 30 |
| 30 void RuleBasedTransliterator::_construct(const UnicodeString& rules, | 31 void RuleBasedTransliterator::_construct(const UnicodeString& rules, |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 237 // A Complication: compound transliterators can result in recursive entries
to this | 238 // A Complication: compound transliterators can result in recursive entries
to this |
| 238 // function, sometimes with different "This" objects, always with the same
text. | 239 // function, sometimes with different "This" objects, always with the same
text. |
| 239 // Double-locking must be prevented in these cases. | 240 // Double-locking must be prevented in these cases. |
| 240 // | 241 // |
| 241 | 242 |
| 242 // If the transliteration data is exclusively owned by this transliterator o
bject, | 243 // If the transliteration data is exclusively owned by this transliterator o
bject, |
| 243 // we don't need to do any locking. No sharing between transliterators is
possible, | 244 // we don't need to do any locking. No sharing between transliterators is
possible, |
| 244 // so no concurrent access from multiple threads is possible. | 245 // so no concurrent access from multiple threads is possible. |
| 245 UBool lockedMutexAtThisLevel = FALSE; | 246 UBool lockedMutexAtThisLevel = FALSE; |
| 246 if (isDataOwned == FALSE) { | 247 if (isDataOwned == FALSE) { |
| 247 // Test whether this request is operating on the same text string as som
e | 248 // Test whether this request is operating on the same text string as |
| 248 // some other transliteration that is still in progress and holding th
e | 249 // some other transliteration that is still in progress and holding th
e |
| 249 // transliteration mutex. If so, do not lock the transliteration | 250 // transliteration mutex. If so, do not lock the transliteration |
| 250 // mutex again. | 251 // mutex again. |
| 252 // |
| 253 // gLockedText variable is protected by the global ICU mutex. |
| 254 // Shared RBT data protected by transliteratorDataMutex. |
| 255 // |
| 251 // TODO(andy): Need a better scheme for handling this. | 256 // TODO(andy): Need a better scheme for handling this. |
| 252 UBool needToLock; | 257 UBool needToLock; |
| 253 umtx_lock(NULL); | 258 { |
| 254 needToLock = (&text != gLockedText); | 259 Mutex m; |
| 255 umtx_unlock(NULL); | 260 needToLock = (&text != gLockedText); |
| 261 } |
| 256 if (needToLock) { | 262 if (needToLock) { |
| 257 umtx_lock(&transliteratorDataMutex); | 263 umtx_lock(&transliteratorDataMutex); // Contention, longish waits p
ossible here. |
| 264 Mutex m; |
| 258 gLockedText = &text; | 265 gLockedText = &text; |
| 259 lockedMutexAtThisLevel = TRUE; | 266 lockedMutexAtThisLevel = TRUE; |
| 260 } | 267 } |
| 261 } | 268 } |
| 262 | 269 |
| 263 // Check to make sure we don't dereference a null pointer. | 270 // Check to make sure we don't dereference a null pointer. |
| 264 if (fData != NULL) { | 271 if (fData != NULL) { |
| 265 while (index.start < index.limit && | 272 while (index.start < index.limit && |
| 266 loopCount <= loopLimit && | 273 loopCount <= loopLimit && |
| 267 fData->ruleSet.transliterate(text, index, isIncremental)) { | 274 fData->ruleSet.transliterate(text, index, isIncremental)) { |
| 268 ++loopCount; | 275 ++loopCount; |
| 269 } | 276 } |
| 270 } | 277 } |
| 271 if (lockedMutexAtThisLevel) { | 278 if (lockedMutexAtThisLevel) { |
| 272 gLockedText = NULL; | 279 { |
| 280 Mutex m; |
| 281 gLockedText = NULL; |
| 282 } |
| 273 umtx_unlock(&transliteratorDataMutex); | 283 umtx_unlock(&transliteratorDataMutex); |
| 274 } | 284 } |
| 275 } | 285 } |
| 276 | 286 |
| 277 UnicodeString& RuleBasedTransliterator::toRules(UnicodeString& rulesSource, | 287 UnicodeString& RuleBasedTransliterator::toRules(UnicodeString& rulesSource, |
| 278 UBool escapeUnprintable) const { | 288 UBool escapeUnprintable) const { |
| 279 return fData->ruleSet.toRules(rulesSource, escapeUnprintable); | 289 return fData->ruleSet.toRules(rulesSource, escapeUnprintable); |
| 280 } | 290 } |
| 281 | 291 |
| 282 /** | 292 /** |
| 283 * Implement Transliterator framework | 293 * Implement Transliterator framework |
| 284 */ | 294 */ |
| 285 void RuleBasedTransliterator::handleGetSourceSet(UnicodeSet& result) const { | 295 void RuleBasedTransliterator::handleGetSourceSet(UnicodeSet& result) const { |
| 286 fData->ruleSet.getSourceTargetSet(result, FALSE); | 296 fData->ruleSet.getSourceTargetSet(result, FALSE); |
| 287 } | 297 } |
| 288 | 298 |
| 289 /** | 299 /** |
| 290 * Override Transliterator framework | 300 * Override Transliterator framework |
| 291 */ | 301 */ |
| 292 UnicodeSet& RuleBasedTransliterator::getTargetSet(UnicodeSet& result) const { | 302 UnicodeSet& RuleBasedTransliterator::getTargetSet(UnicodeSet& result) const { |
| 293 return fData->ruleSet.getSourceTargetSet(result, TRUE); | 303 return fData->ruleSet.getSourceTargetSet(result, TRUE); |
| 294 } | 304 } |
| 295 | 305 |
| 296 U_NAMESPACE_END | 306 U_NAMESPACE_END |
| 297 | 307 |
| 298 #endif /* #if !UCONFIG_NO_TRANSLITERATION */ | 308 #endif /* #if !UCONFIG_NO_TRANSLITERATION */ |
| OLD | NEW |