ICU-4078 Loosely couple the cleanup functions.

X-SVN-Rev: 16307
This commit is contained in:
George Rhoten 2004-09-12 23:07:29 +00:00
parent 8066f2dfe3
commit 7dd960a8b4
19 changed files with 225 additions and 218 deletions

View File

@ -58,6 +58,15 @@ static inline UBool isINVALID(double d) {
return(uprv_isNaN(d));
}
static UMTX ccLock = NULL;
U_CDECL_BEGIN
static UBool calendar_astro_cleanup(void) {
umtx_destroy(&ccLock);
return TRUE;
}
U_CDECL_END
U_NAMESPACE_BEGIN
/**
@ -1475,10 +1484,9 @@ UnicodeString CalendarAstronomer::Horizon::toString() const
// }
// =============== Calendar Cache ================
static UMTX ccLock = NULL;
void CalendarCache::createCache(CalendarCache** cache, UErrorCode& status) {
ucln_i18n_registerCleanup();
ucln_i18n_registerCleanup(UCLN_I18N_ASTRO_CALENDAR, calendar_astro_cleanup);
*cache = new CalendarCache(32, status);
if(cache == NULL) {
status = U_MEMORY_ALLOCATION_ERROR;
@ -1547,9 +1555,4 @@ CalendarCache::~CalendarCache() {
U_NAMESPACE_END
U_CFUNC UBool calendar_astro_cleanup(void) {
umtx_destroy(&ccLock);
return TRUE;
}
#endif // !UCONFIG_NO_FORMATTING

View File

@ -43,7 +43,23 @@
#include "locbased.h"
#include "uresimp.h"
U_NAMESPACE_BEGIN
#if !UCONFIG_NO_SERVICE
static ICULocaleService* gService = NULL;
#endif
// INTERNAL - for cleanup
U_CDECL_BEGIN
static UBool calendar_cleanup(void) {
#if !UCONFIG_NO_SERVICE
if (gService) {
delete gService;
gService = NULL;
}
#endif
return TRUE;
}
U_CDECL_END
// ------------------------------------------
//
@ -101,6 +117,8 @@ static const char * const gBasicCalendars[] = { "@calendar=gregorian", "@calenda
"@calendar=islamic", "@calendar=hebrew", "@calendar=chinese",
NULL };
U_NAMESPACE_BEGIN
static UBool isStandardSupportedID( const char *id, UErrorCode& status) {
if(U_FAILURE(status)) {
return FALSE;
@ -141,7 +159,6 @@ static Calendar *createStandardCalendar(char *calType, const Locale &canLoc, UEr
}
#if !UCONFIG_NO_SERVICE
static ICULocaleService* gService = NULL;
// -------------------------------------
@ -326,7 +343,7 @@ public:
// -------------------------------------
static ICULocaleService*
getCalendarService(void)
getCalendarService(UErrorCode &status)
{
UBool needInit;
{
@ -334,7 +351,6 @@ getCalendarService(void)
needInit = (UBool)(gService == NULL);
}
if (needInit) {
UErrorCode status = U_ZERO_ERROR;
#ifdef U_DEBUG_CALSVC
fprintf(stderr, "Spinning up Calendar Service\n");
#endif
@ -369,7 +385,7 @@ getCalendarService(void)
delete newservice;
} else {
// we won the contention - we can register the cleanup.
ucln_i18n_registerCleanup();
ucln_i18n_registerCleanup(UCLN_I18N_CALENDAR, calendar_cleanup);
}
}
return gService;
@ -377,11 +393,11 @@ getCalendarService(void)
URegistryKey Calendar::registerFactory(ICUServiceFactory* toAdopt, UErrorCode& status)
{
return getCalendarService()->registerFactory(toAdopt, status);
return getCalendarService(status)->registerFactory(toAdopt, status);
}
UBool Calendar::unregister(URegistryKey key, UErrorCode& status) {
return getCalendarService()->unregister(key, status);
return getCalendarService(status)->unregister(key, status);
}
#endif /* UCONFIG_NO_SERVICE */
@ -610,13 +626,13 @@ Calendar::createInstance(TimeZone* zone, const Locale& aLocale, UErrorCode& succ
int32_t calLocaleTypeLen = uprv_strlen(calLocaleType);
int32_t keywordCapacity = aLocale.getKeywordValue("calendar", calLocaleType+calLocaleTypeLen, sizeof(calLocaleType)-calLocaleTypeLen, success);
if (keywordCapacity == 0) {
// no calendar type. Default to nothing.
calLocaleType[0] = 0;
}
// no calendar type. Default to nothing.
calLocaleType[0] = 0;
}
u = createStandardCalendar(calLocaleType, aLocale, success);
}
#else
u = getCalendarService()->get(aLocale, LocaleKey::KIND_ANY, &actualLoc, success);
u = getCalendarService(success)->get(aLocale, LocaleKey::KIND_ANY, &actualLoc, success);
#endif
Calendar* c = NULL;
@ -660,7 +676,7 @@ Calendar::createInstance(TimeZone* zone, const Locale& aLocale, UErrorCode& succ
// Don't overwrite actualLoc, since the actual loc from this call
// may be something like "@calendar=gregorian" -- TODO investigate
// further...
c = (Calendar*)getCalendarService()->get(l, LocaleKey::KIND_ANY, &actualLoc2, success);
c = (Calendar*)getCalendarService(success)->get(l, LocaleKey::KIND_ANY, &actualLoc2, success);
if(U_FAILURE(success) || !c) {
delete zone;
@ -3006,26 +3022,6 @@ Calendar::getLocaleID(ULocDataLocaleType type, UErrorCode& status) const {
U_NAMESPACE_END
// INTERNAL - for cleanup
// clean up the astronomical data & cache
U_CFUNC UBool calendar_islamic_cleanup(void);
U_CFUNC UBool calendar_hebrew_cleanup(void);
U_CFUNC UBool calendar_astro_cleanup(void);
U_CFUNC UBool calendar_cleanup(void) {
calendar_islamic_cleanup();
calendar_hebrew_cleanup();
calendar_astro_cleanup();
#if !UCONFIG_NO_SERVICE
if (gService) {
delete gService;
gService = NULL;
}
#endif
return TRUE;
}
#endif /* #if !UCONFIG_NO_FORMATTING */

View File

@ -51,8 +51,23 @@
#include "ucln_in.h"
U_NAMESPACE_BEGIN
#if !UCONFIG_NO_SERVICE
U_NAMESPACE_END
static ICULocaleService* gService = NULL;
/**
* Release all static memory held by collator.
*/
static UBool collator_cleanup(void) {
if (gService) {
delete gService;
gService = NULL;
}
return TRUE;
}
U_NAMESPACE_BEGIN
// ------------------------------------------
//
// Registration
@ -163,8 +178,6 @@ public:
class ICUCollatorService;
static ICULocaleService* gService = NULL;
static ICULocaleService*
getService(void)
{
@ -184,8 +197,11 @@ getService(void)
}
if(newservice) {
delete newservice;
} else {
ucln_i18n_registerCleanup();
}
else {
#if !UCONFIG_NO_SERVICE
ucln_i18n_registerCleanup(UCLN_I18N_COLLATOR, collator_cleanup);
#endif
}
}
return gService;
@ -652,21 +668,6 @@ Collator::getFunctionalEquivalent(const char* keyword, const Locale& locale,
U_NAMESPACE_END
// defined in ucln_cmn.h
/**
* Release all static memory held by collator.
*/
U_CFUNC UBool collator_cleanup(void) {
#if !UCONFIG_NO_SERVICE
if (gService) {
delete gService;
gService = NULL;
}
#endif
return TRUE;
}
#endif /* #if !UCONFIG_NO_COLLATION */
/* eof */

View File

@ -23,7 +23,6 @@
#include "uhash.h"
#include "ucln_in.h"
U_NAMESPACE_BEGIN
// Hebrew Calendar implementation
/**
@ -130,12 +129,17 @@ static const int32_t LEAP_MONTH_START[][3] = {
{ 383, 384, 385 }, // Elul
};
//-------------------------------------------------------------------------
// Data Members...
//-------------------------------------------------------------------------
static CalendarCache *gCache = NULL;
U_CDECL_BEGIN
static UBool calendar_hebrew_cleanup(void) {
delete gCache;
gCache = NULL;
return TRUE;
}
U_CDECL_END
U_NAMESPACE_BEGIN
//-------------------------------------------------------------------------
// Constructors...
//-------------------------------------------------------------------------
@ -372,6 +376,7 @@ static const int32_t BAHARAD = 11*HOUR_PARTS + 204;
*/
int32_t HebrewCalendar::startOfYear(int32_t year, UErrorCode &status)
{
ucln_i18n_registerCleanup(UCLN_I18N_HEBREW_CALENDAR, calendar_hebrew_cleanup);
int32_t day = CalendarCache::get(&gCache, year, status);
if (day == 0) {
@ -718,15 +723,7 @@ HebrewCalendar::initializeSystemDefaultCentury()
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(HebrewCalendar);
U_NAMESPACE_END
U_CFUNC UBool calendar_hebrew_cleanup(void) {
delete gCache;
gCache = NULL;
return TRUE;
}
#endif // UCONFIG_NO_FORMATTING

View File

@ -54,6 +54,21 @@ static UMTX astroLock = 0; // pod bay door lock
static CalendarCache *gMonthCache = NULL;
static CalendarAstronomer *gIslamicCalendarAstro = NULL;
U_CDECL_BEGIN
static UBool calendar_islamic_cleanup(void) {
if (gMonthCache) {
delete gMonthCache;
gMonthCache = NULL;
}
if (gIslamicCalendarAstro) {
delete gIslamicCalendarAstro;
gIslamicCalendarAstro = NULL;
}
umtx_destroy(&astroLock);
return TRUE;
}
U_CDECL_END
U_NAMESPACE_BEGIN
// Implementation of the IslamicCalendar class
@ -258,7 +273,7 @@ double IslamicCalendar::moonAge(UDate time)
}
gIslamicCalendarAstro->setTime(time);
age = gIslamicCalendarAstro->getMoonAge();
ucln_i18n_registerCleanup();
ucln_i18n_registerCleanup(UCLN_I18N_ISLAMIC_CALENDAR, calendar_islamic_cleanup);
umtx_unlock(&astroLock);
// Convert to degrees and normalize...
@ -507,21 +522,7 @@ IslamicCalendar::initializeSystemDefaultCentury()
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(IslamicCalendar)
U_NAMESPACE_END
U_CFUNC UBool calendar_islamic_cleanup(void) {
if (gMonthCache) {
delete gMonthCache;
gMonthCache = NULL;
}
if (gIslamicCalendarAstro) {
delete gIslamicCalendarAstro;
gIslamicCalendarAstro = NULL;
}
umtx_destroy(&astroLock);
return TRUE;
}
#endif

View File

@ -464,6 +464,19 @@ NumberFormat::getAvailableLocales(int32_t& count)
#if !UCONFIG_NO_SERVICE
static ICULocaleService* gService = NULL;
/**
* Release all static memory held by numberformat.
*/
U_CDECL_BEGIN
static UBool U_CALLCONV numfmt_cleanup(void) {
if (gService) {
delete gService;
gService = NULL;
}
return TRUE;
}
U_CDECL_END
// -------------------------------------
class ICUNumberFormatFactory : public ICUResourceBundleFactory {
@ -586,7 +599,9 @@ getNumberFormatService(void)
delete newservice;
} else {
// we won the contention, this thread can register cleanup.
ucln_i18n_registerCleanup();
#if !UCONFIG_NO_SERVICE
ucln_i18n_registerCleanup(UCLN_I18N_NUMFMT, numfmt_cleanup);
#endif
}
}
return gService;
@ -903,21 +918,6 @@ cleanup:
U_NAMESPACE_END
// defined in ucln_cmn.h
/**
* Release all static memory held by numberformat.
*/
U_CFUNC UBool numfmt_cleanup(void) {
#if !UCONFIG_NO_SERVICE
if (gService) {
delete gService;
gService = NULL;
}
#endif
return TRUE;
}
#endif /* #if !UCONFIG_NO_FORMATTING */
//eof

View File

@ -82,19 +82,6 @@ RegexCompile::RegexCompile(RegexPattern *rxp, UErrorCode &status) : fParenStack(
RegexCompile::~RegexCompile() {
}
//----------------------------------------------------------------------------------------
//
// cleanup. Called (indirectly) by u_cleanup to free all cached memory
//
//----------------------------------------------------------------------------------------
void RegexCompile::cleanup() {
delete RegexStaticSets::gStaticSets;
RegexStaticSets::gStaticSets = NULL;
}
//---------------------------------------------------------------------------------
//
// Compile regex pattern. The state machine for rexexp pattern parsing is here.

View File

@ -216,7 +216,7 @@ RegexStaticSets::RegexStaticSets(UErrorCode *status) {
// Empty UnicodeString, for use by matchers with NULL input.
fEmptyString = new UnicodeString;
};
}
RegexStaticSets::~RegexStaticSets() {
@ -236,9 +236,29 @@ RegexStaticSets::~RegexStaticSets() {
fRuleDigits = NULL;
delete fEmptyString;
fEmptyString = NULL;
};
}
//----------------------------------------------------------------------------------
//
// regex_cleanup Memory cleanup function, free/delete all
// cached memory. Called by ICU's u_cleanup() function.
//
//----------------------------------------------------------------------------------
UBool
RegexStaticSets::cleanup(void) {
delete RegexStaticSets::gStaticSets;
RegexStaticSets::gStaticSets = NULL;
return TRUE;
}
U_CDECL_BEGIN
static UBool U_CALLCONV
regex_cleanup(void) {
return RegexStaticSets::cleanup();
}
U_CDECL_END
void RegexStaticSets::initGlobals(UErrorCode *status) {
umtx_lock(NULL);
RegexStaticSets *p = gStaticSets;
@ -258,7 +278,7 @@ void RegexStaticSets::initGlobals(UErrorCode *status) {
if (p) {
delete p;
}
ucln_i18n_registerCleanup();
ucln_i18n_registerCleanup(UCLN_I18N_REGEX, regex_cleanup);
}
}

View File

@ -36,6 +36,7 @@ public:
RegexStaticSets(UErrorCode *status);
~RegexStaticSets();
static void initGlobals(UErrorCode *status);
static UBool cleanup();
UnicodeSet *fPropSets[URX_LAST_SET]; // The sets for common regex items, e.g. \s
Regex8BitSet fPropSets8[URX_LAST_SET]; // Fast bitmap sets for latin-1 range for above.

View File

@ -603,17 +603,5 @@ RegexPatternDump(const RegexPattern *This) {
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(RegexPattern)
//----------------------------------------------------------------------------------
//
// regex_cleanup Memory cleanup function, free/delete all
// cached memory. Called by ICU's u_cleanup() function.
//
//----------------------------------------------------------------------------------
U_CFUNC UBool
regex_cleanup(void) {
RegexCompile::cleanup();
return TRUE;
};
U_NAMESPACE_END
#endif // !UCONFIG_NO_REGULAR_EXPRESSIONS

View File

@ -104,7 +104,8 @@ static TimeZone* _GMT = NULL; // cf. TimeZone::GMT
static UnicodeString* OLSON_IDS = 0;
#endif
UBool timeZone_cleanup()
U_CDECL_BEGIN
static UBool U_CALLCONV timeZone_cleanup()
{
#ifdef U_USE_TIMEZONE_OBSOLETE_2_8
delete []OLSON_IDS;
@ -124,6 +125,7 @@ UBool timeZone_cleanup()
return TRUE;
}
U_CDECL_END
U_NAMESPACE_BEGIN
@ -340,7 +342,7 @@ static UBool loadOlsonIDs() {
if (OLSON_IDS == 0) {
OLSON_IDS = ids;
ids = 0;
ucln_i18n_registerCleanup();
ucln_i18n_registerCleanup(UCLN_I18N_TIMEZONE, timeZone_cleanup);
}
umtx_unlock(&LOCK);
@ -363,7 +365,7 @@ TimeZone::getGMT(void)
// be valid even if we can't load the time zone UDataMemory.
if (_GMT == 0) {
_GMT = new SimpleTimeZone(0, UnicodeString(GMT_ID, GMT_ID_LENGTH));
ucln_i18n_registerCleanup();
ucln_i18n_registerCleanup(UCLN_I18N_TIMEZONE, timeZone_cleanup);
}
return _GMT;
}
@ -578,7 +580,7 @@ TimeZone::initDefault()
if (DEFAULT_ZONE == NULL) {
DEFAULT_ZONE = default_zone;
default_zone = NULL;
ucln_i18n_registerCleanup();
ucln_i18n_registerCleanup(UCLN_I18N_TIMEZONE, timeZone_cleanup);
}
umtx_unlock(&LOCK);
@ -618,7 +620,7 @@ TimeZone::adoptDefault(TimeZone* zone)
umtx_unlock(&LOCK);
delete old;
ucln_i18n_registerCleanup();
ucln_i18n_registerCleanup(UCLN_I18N_TIMEZONE, timeZone_cleanup);
}
}
// -------------------------------------

View File

@ -1522,7 +1522,7 @@ UBool Transliterator::initializeRegistry() {
_registerSpecialInverse("Upper", "Lower", TRUE);
_registerSpecialInverse("Title", "Lower", FALSE);
ucln_i18n_registerCleanup();
ucln_i18n_registerCleanup(UCLN_I18N_TRANSLITERATOR, transliterator_cleanup);
return TRUE;
}

View File

@ -897,7 +897,7 @@ void TransliteratorIDParser::init() {
umtx_unlock(&LOCK);
delete special_inverses;
ucln_i18n_registerCleanup();
ucln_i18n_registerCleanup(UCLN_I18N_TRANSLITERATOR, transliterator_cleanup);
}
/**

View File

@ -20,35 +20,30 @@
/* Leave this copyright notice here! It needs to go somewhere in this library. */
static const char copyright[] = U_COPYRIGHT_STRING;
static cleanupFunc *gCleanupFunctions[UCLN_I18N_COUNT];
static UBool i18n_cleanup(void)
{
#if !UCONFIG_NO_TRANSLITERATION
transliterator_cleanup();
#endif
#if !UCONFIG_NO_REGULAR_EXPRESSIONS
regex_cleanup();
#endif
#if !UCONFIG_NO_FORMATTING
calendar_cleanup();
numfmt_cleanup();
currency_cleanup();
timeZone_cleanup();
#endif
#if !UCONFIG_NO_COLLATION
usearch_cleanup();
collator_cleanup();
ucol_cleanup();
ucol_bld_cleanup();
#endif
ECleanupLibraryType libType;
for (libType = UCLN_I18N_START+1; libType<UCLN_I18N_COUNT; libType++) {
if (gCleanupFunctions[libType])
{
gCleanupFunctions[libType]();
gCleanupFunctions[libType] = NULL;
}
}
return TRUE;
}
void ucln_i18n_registerCleanup()
void ucln_i18n_registerCleanup(ECleanupI18NType type,
cleanupFunc *func)
{
U_ASSERT(UCLN_I18N_START < type && type < UCLN_I18N_COUNT);
ucln_registerCleanup(UCLN_I18N, i18n_cleanup);
if (UCLN_I18N_START < type && type < UCLN_I18N_COUNT)
{
gCleanupFunctions[type] = func;
}
}

View File

@ -18,30 +18,34 @@
#define __UCLN_CMN_H__
#include "unicode/utypes.h"
#include "ucln.h"
/* Main library cleanup function. */
U_CFUNC void ucln_i18n_registerCleanup(void);
/*
Please keep the order of enums declared in same order
as the functions are suppose to be called. */
typedef enum ECleanupI18NType {
UCLN_I18N_START = -1,
UCLN_I18N_TRANSLITERATOR,
UCLN_I18N_REGEX,
UCLN_I18N_ISLAMIC_CALENDAR,
UCLN_I18N_HEBREW_CALENDAR,
UCLN_I18N_ASTRO_CALENDAR,
UCLN_I18N_CALENDAR,
UCLN_I18N_NUMFMT,
UCLN_I18N_CURRENCY,
UCLN_I18N_TIMEZONE,
UCLN_I18N_USEARCH,
UCLN_I18N_COLLATOR,
UCLN_I18N_UCOL,
UCLN_I18N_UCOL_BLD,
UCLN_I18N_COUNT /* This must be last */
} ECleanupI18NType;
/* Main library cleanup registration function. */
/* See common/ucln.h for details on adding a cleanup function. */
U_CFUNC void U_EXPORT2 ucln_i18n_registerCleanup(ECleanupI18NType type,
cleanupFunc *func);
U_CFUNC UBool transliterator_cleanup(void);
U_CFUNC UBool timeZone_cleanup(void);
U_CFUNC UBool numfmt_cleanup(void);
U_CFUNC UBool calendar_cleanup(void);
U_CFUNC UBool currency_cleanup(void);
U_CFUNC UBool collator_cleanup(void);
U_CFUNC UBool ucol_cleanup(void);
U_CFUNC UBool ucol_bld_cleanup(void);
U_CFUNC UBool regex_cleanup(void);
U_CFUNC UBool usearch_cleanup(void);
#endif

View File

@ -974,21 +974,6 @@ UCollator* ucol_initCollator(const UCATableHeader *image, UCollator *fillIn, con
return result;
}
U_CFUNC UBool
ucol_cleanup(void)
{
if (UCA_DATA_MEM) {
udata_close(UCA_DATA_MEM);
UCA_DATA_MEM = NULL;
}
if (_staticUCA) {
ucol_close(_staticUCA);
_staticUCA = NULL;
}
fcdTrieIndex = NULL;
return TRUE;
}
/* new Mark's code */
/**
@ -1327,6 +1312,23 @@ uprv_uca_initImplicitConstants(int32_t minPrimary, int32_t maxPrimary, UErrorCod
initImplicitConstants(minPrimary, maxPrimary, 0x04, 0xFE, 1, 1, status);
}
U_CDECL_BEGIN
static UBool U_CALLCONV
ucol_cleanup(void)
{
if (UCA_DATA_MEM) {
udata_close(UCA_DATA_MEM);
UCA_DATA_MEM = NULL;
}
if (_staticUCA) {
ucol_close(_staticUCA);
_staticUCA = NULL;
}
fcdTrieIndex = NULL;
return TRUE;
}
U_CDECL_END
/* do not close UCA returned by ucol_initUCA! */
UCollator *
ucol_initUCA(UErrorCode *status) {
@ -1351,7 +1353,7 @@ ucol_initUCA(UErrorCode *status) {
// init FCD data
if (fcdTrieIndex == NULL) {
fcdTrieIndex = unorm_getFCDTrie(status);
ucln_i18n_registerCleanup();
ucln_i18n_registerCleanup(UCLN_I18N_UCOL, ucol_cleanup);
}
if(result != NULL) { /* It looks like sometimes we can fail to find the data file */
@ -1377,7 +1379,7 @@ ucol_initUCA(UErrorCode *status) {
uprv_free(newUCA);
}
else {
ucln_i18n_registerCleanup();
ucln_i18n_registerCleanup(UCLN_I18N_UCOL, ucol_cleanup);
}
// Initalize variables for implicit generation
const UCAConstants *UCAconsts = (UCAConstants *)((uint8_t *)_staticUCA->image + _staticUCA->image->UCAConsts);

View File

@ -1207,7 +1207,8 @@ UCATableHeader *ucol_assembleTailoringTable(UColTokenParser *src, UErrorCode *st
return myData;
}
UBool
U_CDECL_BEGIN
static UBool U_CALLCONV
ucol_bld_cleanup(void)
{
udata_close(invUCA_DATA_MEM);
@ -1215,6 +1216,7 @@ ucol_bld_cleanup(void)
_staticInvUCA = NULL;
return TRUE;
}
U_CDECL_END
U_CAPI const InverseUCATableHeader * U_EXPORT2
ucol_initInverseUCA(UErrorCode *status)
@ -1264,7 +1266,7 @@ ucol_initInverseUCA(UErrorCode *status)
//uprv_free(newInvUCA);
}
else {
ucln_i18n_registerCleanup();
ucln_i18n_registerCleanup(UCLN_I18N_UCOL_BLD, ucol_bld_cleanup);
}
}
}

View File

@ -189,6 +189,9 @@ idForLocale(const char* locale, char* countryAndVariant, int capacity, UErrorCod
// don't use ICUService since we don't need fallback
#if !UCONFIG_NO_SERVICE
U_CDECL_BEGIN
static UBool U_CALLCONV currency_cleanup(void);
U_CDECL_END
struct CReg;
/* Remember to call umtx_init(&gCRegLock) before using it! */
@ -222,7 +225,7 @@ struct CReg : public UMemory {
Mutex mutex(&gCRegLock);
if (!gCRegHead) {
/* register for the first time */
ucln_i18n_registerCleanup();
ucln_i18n_registerCleanup(UCLN_I18N_CURRENCY, currency_cleanup);
}
n->next = gCRegHead;
gCRegHead = n;
@ -260,7 +263,8 @@ struct CReg : public UMemory {
Mutex mutex(&gCRegLock);
CReg* p = gCRegHead;
ucln_i18n_registerCleanup(); /* register cleanup of the mutex */
/* register cleanup of the mutex */
ucln_i18n_registerCleanup(UCLN_I18N_CURRENCY, currency_cleanup);
while (p) {
if (uprv_strcmp(id, p->id) == 0) {
return p->iso;
@ -281,6 +285,18 @@ struct CReg : public UMemory {
}
};
/**
* Release all static memory held by currency.
*/
U_CDECL_BEGIN
static UBool U_CALLCONV currency_cleanup(void) {
#if !UCONFIG_NO_SERVICE
CReg::cleanup();
#endif
return TRUE;
}
U_CDECL_END
// -------------------------------------
U_CAPI UCurrRegistryKey U_EXPORT2
@ -694,16 +710,6 @@ ucurr_getRoundingIncrement(const UChar* currency, UErrorCode* ec) {
return double(data[1]) / POW10[data[0]];
}
/**
* Release all static memory held by currency.
*/
U_CFUNC UBool currency_cleanup(void) {
#if !UCONFIG_NO_SERVICE
CReg::cleanup();
#endif
return TRUE;
}
#endif /* #if !UCONFIG_NO_FORMATTING */
//eof

View File

@ -84,6 +84,14 @@ inline int hash(uint32_t ce)
return UCOL_PRIMARYORDER(ce) % MAX_TABLE_SIZE_;
}
U_CDECL_BEGIN
static UBool U_CALLCONV
usearch_cleanup(void) {
FCD_ = NULL;
return TRUE;
}
U_CDECL_END
/**
* Initializing the fcd tables.
* Internal method, status assumed to be a success.
@ -95,16 +103,10 @@ inline void initializeFCD(UErrorCode *status)
{
if (FCD_ == NULL) {
FCD_ = unorm_getFCDTrie(status);
ucln_i18n_registerCleanup();
ucln_i18n_registerCleanup(UCLN_I18N_USEARCH, usearch_cleanup);
}
}
U_CFUNC UBool
usearch_cleanup(void) {
FCD_ = NULL;
return TRUE;
}
/**
* Gets the fcd value for a character at the argument index.
* This method takes into accounts of the supplementary characters.