X-Git-Url: https://git.saurik.com/apple/icu.git/blobdiff_plain/51004dcb01e06fef634b61be77ed73dd61cb6db9..4f1e1a09ce4daed860e35d359ce2fceccb0764e8:/icuSources/i18n/rbt.cpp diff --git a/icuSources/i18n/rbt.cpp b/icuSources/i18n/rbt.cpp index b987ade2..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-2012, International Business Machines +* Copyright (C) 1999-2015, International Business Machines * Corporation and others. All Rights Reserved. ********************************************************************** * Date Name Description @@ -18,6 +20,7 @@ #include "rbt_data.h" #include "rbt_rule.h" #include "rbt.h" +#include "mutex.h" #include "umutex.h" U_NAMESPACE_BEGIN @@ -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); } }