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 |