]> git.saurik.com Git - apple/icu.git/blobdiff - icuSources/i18n/rbt.cpp
ICU-62141.0.1.tar.gz
[apple/icu.git] / icuSources / i18n / rbt.cpp
index 6041a9245e654f25daab0936cc8b193c1570218d..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-2008, 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,
@@ -239,22 +242,27 @@ 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) {
-        // 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;
-        UMTX_CHECK(NULL, (&text != gLockedText), needToLock);
-        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;
     }
     
     // Check to make sure we don't dereference a null pointer.
@@ -266,7 +274,10 @@ RuleBasedTransliterator::handleTransliterate(Replaceable& text, UTransPosition&
            }
     }
     if (lockedMutexAtThisLevel) {
-        gLockedText = NULL;
+        {
+            Mutex m;
+            gLockedText = NULL;
+        }
         umtx_unlock(&transliteratorDataMutex);
     }
 }