+// © 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,
// 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.
}
}
if (lockedMutexAtThisLevel) {
- gLockedText = NULL;
+ {
+ Mutex m;
+ gLockedText = NULL;
+ }
umtx_unlock(&transliteratorDataMutex);
}
}