diff --git a/icu4c/source/i18n/translit.cpp b/icu4c/source/i18n/translit.cpp index 12cb93e8757..19e4284b179 100644 --- a/icu4c/source/i18n/translit.cpp +++ b/icu4c/source/i18n/translit.cpp @@ -14,6 +14,7 @@ #include "rbt_data.h" #include "rbt_pars.h" #include "transreg.h" +#include "ucln_in.h" #include "unicode/cpdtrans.h" #include "unicode/hangjamo.h" #include "unicode/hextouni.h" @@ -1438,28 +1439,21 @@ void Transliterator::initializeRegistry(void) { registry->put(new UnicodeNameTransliterator(), TRUE); registry->put(new NameUnicodeTransliterator(), TRUE); NormalizationTransliterator::registerIDs(); + ucln_i18n_registerCleanup(); } // Defined in ucln_in.h: -/** - * Cleanup function for transliterator component; delegates to - * Transliterator::cleanupRegistry(). - */ -U_CFUNC UBool transliterator_cleanup(void) { - Transliterator::cleanupRegistry(); - return TRUE; -} - /** * Release all static memory held by transliterator. This will * necessarily invalidate any rule-based transliterators held by the * user, because RBTs hold pointers to common data objects. - */ -void Transliterator::cleanupRegistry() { - Mutex lock(®istryMutex); + */ +U_CFUNC UBool transliterator_cleanup(void) { delete registry; registry = 0; + umtx_destroy(®istryMutex); + return TRUE; } //eof diff --git a/icu4c/source/i18n/ucln_in.c b/icu4c/source/i18n/ucln_in.c index c50a4be0c58..8e94c8985ee 100644 --- a/icu4c/source/i18n/ucln_in.c +++ b/icu4c/source/i18n/ucln_in.c @@ -19,10 +19,11 @@ static UBool i18n_cleanup(void) { - ucol_bld_cleanup(); - ucol_cleanup(); - timeZone_cleanup(); transliterator_cleanup(); + unicodeset_cleanup(); + timeZone_cleanup(); + ucol_cleanup(); + ucol_bld_cleanup(); return TRUE; } diff --git a/icu4c/source/i18n/ucln_in.h b/icu4c/source/i18n/ucln_in.h index 58f1fa6d6e1..9ecd837cdbe 100644 --- a/icu4c/source/i18n/ucln_in.h +++ b/icu4c/source/i18n/ucln_in.h @@ -22,12 +22,16 @@ /* Main library cleanup function. */ U_CFUNC void ucln_i18n_registerCleanup(void); +/* See common/ucln.h for details on adding a cleanup function. */ + +U_CFUNC UBool transliterator_cleanup(void); + +U_CFUNC UBool unicodeset_cleanup(void); + +U_CFUNC UBool timeZone_cleanup(void); + U_CFUNC UBool ucol_cleanup(void); U_CFUNC UBool ucol_bld_cleanup(void); -U_CFUNC UBool timeZone_cleanup(void); - -U_CFUNC UBool transliterator_cleanup(void); - #endif diff --git a/icu4c/source/i18n/unicode/translit.h b/icu4c/source/i18n/unicode/translit.h index a86cc83a62c..da2634f7199 100644 --- a/icu4c/source/i18n/unicode/translit.h +++ b/icu4c/source/i18n/unicode/translit.h @@ -925,9 +925,6 @@ protected: private: static void initializeRegistry(void); - - friend UBool transliterator_cleanup(); - static void cleanupRegistry(void); }; inline int32_t Transliterator::getMaximumContextLength(void) const { diff --git a/icu4c/source/i18n/unicode/uniset.h b/icu4c/source/i18n/unicode/uniset.h index 9b0ed7b242b..3e39205e9c1 100644 --- a/icu4c/source/i18n/unicode/uniset.h +++ b/icu4c/source/i18n/unicode/uniset.h @@ -265,13 +265,6 @@ class U_I18N_API UnicodeSet : public UnicodeFilter { */ UnicodeString pat; - /** - * A cache mapping character category integers, as returned by - * Unicode::getType(), to pairs strings. Entries are initially - * zero length and are filled in on demand. - */ - static UnicodeSet* CATEGORY_CACHE; - public: /** diff --git a/icu4c/source/i18n/uniset.cpp b/icu4c/source/i18n/uniset.cpp index d53a28f6479..9e7adcaca30 100644 --- a/icu4c/source/i18n/uniset.cpp +++ b/icu4c/source/i18n/uniset.cpp @@ -14,6 +14,8 @@ #include "symtable.h" #include "cmemory.h" #include "rbt_rule.h" +#include "umutex.h" +#include "ucln_in.h" // HIGH_VALUE > all valid values. 110000 for codepoints #define UNICODESET_HIGH 0x0110000 @@ -92,8 +94,7 @@ static const UChar CATEGORY_NAMES[] = { * Unicode::getType(), to pairs strings. Entries are initially * zero length and are filled in on demand. */ -UnicodeSet _CATEGORY_CACHE[Unicode::GENERAL_TYPES_COUNT]; -UnicodeSet* UnicodeSet::CATEGORY_CACHE = _CATEGORY_CACHE; +static UnicodeSet* CATEGORY_CACHE = NULL; /** * Delimiter string used in patterns to close a category reference: @@ -102,6 +103,18 @@ UnicodeSet* UnicodeSet::CATEGORY_CACHE = _CATEGORY_CACHE; static const UChar CATEGORY_CLOSE[] = {COLON, SET_CLOSE, 0x0000}; /* ":]" */ +/** + * Cleanup function for transliterator component; delegates to + * Transliterator::cleanupRegistry(). + */ +U_CFUNC UBool unicodeset_cleanup(void) { + if (CATEGORY_CACHE) { + delete []CATEGORY_CACHE; + CATEGORY_CACHE = NULL; + } + return TRUE; +} + //---------------------------------------------------------------- // Constructors &c //---------------------------------------------------------------- @@ -1366,6 +1379,14 @@ const UnicodeSet& UnicodeSet::getCategorySet(int8_t cat) { // In order to tell what cache entries are empty, we assume // every category specifies at least one character. Thus // sets in the cache that are empty are uninitialized. + if (CATEGORY_CACHE == NULL) { + umtx_lock(NULL); + if (CATEGORY_CACHE == NULL) { + CATEGORY_CACHE = new UnicodeSet[Unicode::GENERAL_TYPES_COUNT]; + ucln_i18n_registerCleanup(); + } + umtx_unlock(NULL); + } if (CATEGORY_CACHE[cat].isEmpty()) { // Walk through all Unicode characters, noting the start // and end of each range for which Character.getType(c)