X-Git-Url: https://git.saurik.com/apple/icu.git/blobdiff_plain/46f4442e9a5a4f3b98b7c1083586332f6a8a99a4..249c4c5ea9376c24572daf9c2effa7484a282f14:/icuSources/i18n/rbt.cpp?ds=sidebyside diff --git a/icuSources/i18n/rbt.cpp b/icuSources/i18n/rbt.cpp index 6041a924..9cb1b0e9 100644 --- a/icuSources/i18n/rbt.cpp +++ b/icuSources/i18n/rbt.cpp @@ -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 @@ -18,13 +20,14 @@ #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); } }