]> git.saurik.com Git - apple/icu.git/blobdiff - icuSources/i18n/rbt.cpp
ICU-62123.0.1.tar.gz
[apple/icu.git] / icuSources / i18n / rbt.cpp
index c22b2bd7f36282e77e8a6f4808ab7e749592b8bf..9cb1b0e9a70f20f7266305e8c894a6f0e7a40bdd 100644 (file)
@@ -1,6 +1,8 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
-*   Copyright (C) 1999-2006, International Business Machines
+*   Copyright (C) 1999-2015, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 **********************************************************************
 *   Date        Name        Description
 #include "rbt_data.h"
 #include "rbt_rule.h"
 #include "rbt.h"
+#include "mutex.h"
 #include "umutex.h"
 
 U_NAMESPACE_BEGIN
 
 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(RuleBasedTransliterator)
 
-static UMTX  transliteratorDataMutex = NULL;
+static UMutex transliteratorDataMutex = U_MUTEX_INITIALIZER;
 static Replaceable *gLockedText = NULL;
 
 void RuleBasedTransliterator::_construct(const UnicodeString& rules,
@@ -87,7 +90,7 @@ RuleBasedTransliterator::RuleBasedTransliterator(
  * @exception IllegalArgumentException if rules are malformed
  * or direction is invalid.
  */
-RuleBasedTransliterator::RuleBasedTransliterator(
+/*RuleBasedTransliterator::RuleBasedTransliterator(
                             const UnicodeString& id,
                             const UnicodeString& rules,
                             UTransDirection direction,
@@ -96,12 +99,12 @@ RuleBasedTransliterator::RuleBasedTransliterator(
     Transliterator(id, adoptedFilter) {
     UParseError parseError;
     _construct(rules, direction,parseError, status);
-}
+}*/
 
 /**
  * Covenience constructor with no filter.
  */
-RuleBasedTransliterator::RuleBasedTransliterator(
+/*RuleBasedTransliterator::RuleBasedTransliterator(
                             const UnicodeString& id,
                             const UnicodeString& rules,
                             UTransDirection direction,
@@ -109,24 +112,24 @@ RuleBasedTransliterator::RuleBasedTransliterator(
     Transliterator(id, 0) {
     UParseError parseError;
     _construct(rules, direction,parseError, status);
-}
+}*/
 
 /**
  * Covenience constructor with no filter and FORWARD direction.
  */
-RuleBasedTransliterator::RuleBasedTransliterator(
+/*RuleBasedTransliterator::RuleBasedTransliterator(
                             const UnicodeString& id,
                             const UnicodeString& rules,
                             UErrorCode& status) :
     Transliterator(id, 0) {
     UParseError parseError;
     _construct(rules, UTRANS_FORWARD, parseError, status);
-}
+}*/
 
 /**
  * Covenience constructor with FORWARD direction.
  */
-RuleBasedTransliterator::RuleBasedTransliterator(
+/*RuleBasedTransliterator::RuleBasedTransliterator(
                             const UnicodeString& id,
                             const UnicodeString& rules,
                             UnicodeFilter* adoptedFilter,
@@ -134,7 +137,7 @@ RuleBasedTransliterator::RuleBasedTransliterator(
     Transliterator(id, adoptedFilter) {
     UParseError parseError;
     _construct(rules, UTRANS_FORWARD,parseError, status);
-}
+}*/
 
 RuleBasedTransliterator::RuleBasedTransliterator(const UnicodeString& id,
                                  const TransliterationRuleData* theData,
@@ -239,33 +242,42 @@ RuleBasedTransliterator::handleTransliterate(Replaceable& text, UTransPosition&
     //   Double-locking must be prevented in these cases.
     //   
 
-    // If the transliteration data is exclusively owned by this transliterator object,
-    //   we don't need to do any locking.  No sharing between transliterators is possible,
-    //   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);
-        if (needToLock) {
-            umtx_lock(&transliteratorDataMutex);
-            gLockedText = &text;
-            lockedMutexAtThisLevel = TRUE;
-        }
+
+    // Test whether this request is operating on the same text string as
+    //   some other transliteration that is still in progress and holding the 
+    //   transliteration mutex.  If so, do not lock the transliteration
+    //    mutex again.
+    //
+    //  gLockedText variable is protected by the global ICU mutex.
+    //  Shared RBT data protected by transliteratorDataMutex.
+    //
+    // TODO(andy): Need a better scheme for handling this.
+    UBool needToLock;
+    {
+        Mutex m;
+        needToLock = (&text != gLockedText);
+    }
+    if (needToLock) {
+        umtx_lock(&transliteratorDataMutex);  // Contention, longish waits possible here.
+        Mutex m;
+        gLockedText = &text;
+        lockedMutexAtThisLevel = TRUE;
     }
     
-
-    while (index.start < index.limit &&
-           loopCount <= loopLimit &&
-           fData->ruleSet.transliterate(text, index, isIncremental)) {
-        ++loopCount;
+    // Check to make sure we don't dereference a null pointer.
+    if (fData != NULL) {
+           while (index.start < index.limit &&
+                  loopCount <= loopLimit &&
+                  fData->ruleSet.transliterate(text, index, isIncremental)) {
+               ++loopCount;
+           }
     }
     if (lockedMutexAtThisLevel) {
-        gLockedText = NULL;
+        {
+            Mutex m;
+            gLockedText = NULL;
+        }
         umtx_unlock(&transliteratorDataMutex);
     }
 }