ICU-4078 Decouple the cleanup functions from u_init and u_cleanup.
X-SVN-Rev: 16403
This commit is contained in:
parent
1188be07f8
commit
e2188e6775
@ -58,7 +58,7 @@ DEFS += -DU_COMMON_IMPLEMENTATION
|
||||
# $(LIBICUDT) is either stub data or the real DLL common data.
|
||||
LIBS = $(LIBICUDT) $(DEFAULT_LIBS)
|
||||
|
||||
OBJECTS = putil.o uobject.o cmemory.o umutex.o \
|
||||
OBJECTS = putil.o uobject.o cmemory.o umutex.o ucln_cmn.o uinit.o \
|
||||
udata.o ucmndata.o udatamem.o udataswp.o umapfile.o ucol_swp.o \
|
||||
uresbund.o ures_cnv.o uresdata.o resbund.o resbund_cnv.o \
|
||||
ucat.o locmap.o uloc.o locid.o \
|
||||
@ -70,7 +70,7 @@ unistr.o unistr_case.o unistr_cnv.o unistr_props.o \
|
||||
utf_impl.o ustring.o ustr_cnv.o ustrcase.o cstring.o ustrfmt.o ustrtrns.o ustr_wcs.o uinvchar.o \
|
||||
normlzr.o unorm.o unormcmp.o unorm_it.o chariter.o schriter.o uchriter.o uiter.o \
|
||||
uchar.o uprops.o ucase.o propname.o ubidi.o ubidiwrt.o ubidiln.o ushape.o unames.o \
|
||||
ucln_cmn.o uscript.o usc_impl.o uvector.o ustack.o uvectr32.o ucmp8.o \
|
||||
uscript.o usc_impl.o uvector.o ustack.o uvectr32.o ucmp8.o \
|
||||
uarrsort.o utrie.o uset.o uset_props.o uniset.o uniset_props.o ruleiter.o caniter.o unifilt.o unifunct.o usetiter.o \
|
||||
brkiter.o brkdict.o ubrk.o dbbi.o dbbi_tbl.o \
|
||||
rbbi.o rbbidata.o rbbinode.o rbbirb.o rbbiscan.o rbbisetb.o rbbistbl.o rbbitblb.o \
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "unicode/brkiter.h"
|
||||
#include "unicode/udata.h"
|
||||
#include "unicode/ures.h"
|
||||
#include "ucln_cmn.h"
|
||||
#include "cstring.h"
|
||||
#include "mutex.h"
|
||||
#include "iculserv.h"
|
||||
@ -362,6 +363,26 @@ public:
|
||||
|
||||
// -------------------------------------
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
||||
// defined in ucln_cmn.h
|
||||
|
||||
/**
|
||||
* Release all static memory held by breakiterator.
|
||||
*/
|
||||
U_CDECL_BEGIN
|
||||
static UBool U_CALLCONV breakiterator_cleanup(void) {
|
||||
#if !UCONFIG_NO_SERVICE
|
||||
if (gService) {
|
||||
delete gService;
|
||||
gService = NULL;
|
||||
}
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
U_CDECL_END
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
static ICULocaleService*
|
||||
getService(void)
|
||||
{
|
||||
@ -376,6 +397,7 @@ getService(void)
|
||||
if (gService == NULL) {
|
||||
gService = tService;
|
||||
tService = NULL;
|
||||
ucln_common_registerCleanup(UCLN_COMMON_BREAKITERATOR, breakiterator_cleanup);
|
||||
}
|
||||
umtx_unlock(NULL);
|
||||
delete tService;
|
||||
@ -520,21 +542,6 @@ BreakIterator::getLocaleID(ULocDataLocaleType type, UErrorCode& status) const {
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
||||
// defined in ucln_cmn.h
|
||||
|
||||
/**
|
||||
* Release all static memory held by breakiterator.
|
||||
*/
|
||||
U_CFUNC UBool breakiterator_cleanup(void) {
|
||||
#if !UCONFIG_NO_SERVICE
|
||||
if (gService) {
|
||||
delete gService;
|
||||
gService = NULL;
|
||||
}
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#endif /* #if !UCONFIG_NO_BREAK_ITERATION */
|
||||
|
||||
//eof
|
||||
|
@ -1712,6 +1712,10 @@ SOURCE=.\umapfile.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\uinit.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\umapfile.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
@ -962,6 +962,9 @@
|
||||
<File
|
||||
RelativePath=".\udataswp.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\uinit.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\umapfile.c">
|
||||
<FileConfiguration
|
||||
|
@ -17,10 +17,9 @@
|
||||
#include "ustrfmt.h"
|
||||
#include "uhash.h"
|
||||
#include "charstr.h"
|
||||
#include "ucln_cmn.h"
|
||||
#include "uassert.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
// see LocaleUtility::getAvailableLocaleNames
|
||||
static Hashtable * LocaleUtility_cache = NULL;
|
||||
|
||||
@ -32,6 +31,21 @@ static Hashtable * LocaleUtility_cache = NULL;
|
||||
******************************************************************
|
||||
*/
|
||||
|
||||
/**
|
||||
* Release all static memory held by Locale Utility.
|
||||
*/
|
||||
U_CDECL_BEGIN
|
||||
static UBool U_CALLCONV service_cleanup(void) {
|
||||
if (LocaleUtility_cache) {
|
||||
delete LocaleUtility_cache;
|
||||
LocaleUtility_cache = NULL;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
U_CDECL_END
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
UnicodeString&
|
||||
LocaleUtility::canonicalLocaleString(const UnicodeString* id, UnicodeString& result)
|
||||
{
|
||||
@ -194,6 +208,7 @@ LocaleUtility::getAvailableLocaleNames(const UnicodeString& bundleID)
|
||||
if (h == NULL) {
|
||||
LocaleUtility_cache = h = cache;
|
||||
cache = NULL;
|
||||
ucln_common_registerCleanup(UCLN_COMMON_SERVICE, service_cleanup);
|
||||
}
|
||||
umtx_unlock(NULL);
|
||||
delete cache;
|
||||
@ -243,15 +258,6 @@ LocaleUtility::isFallbackOf(const UnicodeString& root, const UnicodeString& chil
|
||||
child.charAt(root.length()) == UNDERSCORE_CHAR);
|
||||
}
|
||||
|
||||
UBool
|
||||
LocaleUtility::cleanup(void) {
|
||||
if (LocaleUtility_cache) {
|
||||
delete LocaleUtility_cache;
|
||||
LocaleUtility_cache = NULL;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
******************************************************************
|
||||
*/
|
||||
@ -950,15 +956,6 @@ ICULocaleService::createKey(const UnicodeString* id, int32_t kind, UErrorCode& s
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
||||
// defined in ucln_cmn.h
|
||||
|
||||
/**
|
||||
* Release all static memory held by Locale Utility.
|
||||
*/
|
||||
U_CFUNC UBool service_cleanup(void) {
|
||||
return LocaleUtility::cleanup();
|
||||
}
|
||||
|
||||
/* !UCONFIG_NO_SERVICE */
|
||||
#endif
|
||||
|
||||
|
@ -547,7 +547,6 @@ public:
|
||||
static UnicodeString& initNameFromLocale(const Locale& locale, UnicodeString& result);
|
||||
static const Hashtable* getAvailableLocaleNames(const UnicodeString& bundleID);
|
||||
static UBool isFallbackOf(const UnicodeString& root, const UnicodeString& child);
|
||||
static UBool cleanup(void);
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
@ -88,11 +88,8 @@ static void U_CALLCONV
|
||||
deleteLocale(void *obj) {
|
||||
delete (Locale *) obj;
|
||||
}
|
||||
U_CDECL_END
|
||||
|
||||
|
||||
UBool
|
||||
locale_cleanup(void)
|
||||
static UBool U_CALLCONV locale_cleanup(void)
|
||||
{
|
||||
U_NAMESPACE_USE
|
||||
|
||||
@ -115,6 +112,7 @@ locale_cleanup(void)
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
U_CDECL_END
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(Locale)
|
||||
@ -170,6 +168,7 @@ void locale_set_default_internal(const char *id)
|
||||
umtx_lock(NULL);
|
||||
if (gDefaultLocalesHashT == NULL) {
|
||||
gDefaultLocalesHashT = tHashTable;
|
||||
ucln_common_registerCleanup(UCLN_COMMON_LOCALE, locale_cleanup);
|
||||
umtx_unlock(NULL);
|
||||
} else {
|
||||
umtx_unlock(NULL);
|
||||
@ -972,6 +971,7 @@ Locale::getAvailableLocales(int32_t& count)
|
||||
availableLocaleListCount = count;
|
||||
availableLocaleList = newLocaleList;
|
||||
newLocaleList = NULL;
|
||||
ucln_common_registerCleanup(UCLN_COMMON_LOCALE, locale_cleanup);
|
||||
}
|
||||
umtx_unlock(NULL);
|
||||
delete []newLocaleList;
|
||||
@ -1175,6 +1175,7 @@ Locale::getLocaleCache(void)
|
||||
if (gLocaleCache == NULL) {
|
||||
gLocaleCache = tLocaleCache;
|
||||
tLocaleCache = NULL;
|
||||
ucln_common_registerCleanup(UCLN_COMMON_LOCALE, locale_cleanup);
|
||||
}
|
||||
umtx_unlock(NULL);
|
||||
if (tLocaleCache) {
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "umutex.h"
|
||||
#include "cmemory.h"
|
||||
#include "cstring.h"
|
||||
#include "ucln_cmn.h"
|
||||
#include "uarrsort.h"
|
||||
|
||||
U_CDECL_BEGIN
|
||||
@ -232,8 +233,7 @@ isPNameAcceptable(void* /*context*/,
|
||||
info->formatVersion[0] == PNAME_FORMAT_VERSION;
|
||||
}
|
||||
|
||||
UBool
|
||||
pname_cleanup() {
|
||||
static UBool U_CALLCONV pname_cleanup() {
|
||||
if (UDATA) {
|
||||
udata_close(UDATA);
|
||||
UDATA = NULL;
|
||||
@ -258,6 +258,7 @@ static UBool _load() {
|
||||
if (UDATA == NULL) {
|
||||
UDATA = data;
|
||||
PNAME = (const PropertyAliases*) udata_getMemory(UDATA);
|
||||
ucln_common_registerCleanup(UCLN_COMMON_PNAME, pname_cleanup);
|
||||
data = NULL;
|
||||
}
|
||||
umtx_unlock(NULL);
|
||||
|
@ -1249,7 +1249,7 @@ static char *gDataDirectory = NULL;
|
||||
static char *gCorrectedPOSIXLocale = NULL; /* Heap allocated */
|
||||
#endif
|
||||
|
||||
UBool putil_cleanup(void)
|
||||
static UBool U_CALLCONV putil_cleanup(void)
|
||||
{
|
||||
if (gDataDirectory) {
|
||||
uprv_free(gDataDirectory);
|
||||
@ -1295,6 +1295,7 @@ u_setDataDirectory(const char *directory) {
|
||||
uprv_free(gDataDirectory);
|
||||
}
|
||||
gDataDirectory = newDataDir;
|
||||
ucln_common_registerCleanup(UCLN_COMMON_PUTIL, putil_cleanup);
|
||||
umtx_unlock(NULL);
|
||||
}
|
||||
|
||||
@ -1692,6 +1693,7 @@ The leftmost codepage (.xxx) wins.
|
||||
|
||||
if (gCorrectedPOSIXLocale == NULL) {
|
||||
gCorrectedPOSIXLocale = correctedPOSIXLocale;
|
||||
ucln_common_registerCleanup(UCLN_COMMON_PUTIL, putil_cleanup);
|
||||
correctedPOSIXLocale = NULL;
|
||||
}
|
||||
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "cmemory.h"
|
||||
#include "utrie.h"
|
||||
#include "ucase.h"
|
||||
#include "ucln_cmn.h"
|
||||
|
||||
struct UCaseProps {
|
||||
UDataMemory *mem;
|
||||
@ -182,6 +183,14 @@ static UCaseProps *gCsp=NULL;
|
||||
static UErrorCode gErrorCode=U_ZERO_ERROR;
|
||||
static int8_t gHaveData=0;
|
||||
|
||||
static UBool U_CALLCONV ucase_cleanup(void) {
|
||||
ucase_close(gCsp);
|
||||
gCsp=NULL;
|
||||
gErrorCode=U_ZERO_ERROR;
|
||||
gHaveData=0;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
U_CAPI UCaseProps * U_EXPORT2
|
||||
ucase_getSingleton(UErrorCode *pErrorCode) {
|
||||
int8_t haveData;
|
||||
@ -214,6 +223,7 @@ ucase_getSingleton(UErrorCode *pErrorCode) {
|
||||
gCsp=csp;
|
||||
csp=NULL;
|
||||
gHaveData=1;
|
||||
ucln_common_registerCleanup(UCLN_COMMON_UCASE, ucase_cleanup);
|
||||
}
|
||||
umtx_unlock(NULL);
|
||||
|
||||
@ -222,14 +232,6 @@ ucase_getSingleton(UErrorCode *pErrorCode) {
|
||||
}
|
||||
}
|
||||
|
||||
U_CFUNC void
|
||||
ucase_cleanup() {
|
||||
ucase_close(gCsp);
|
||||
gCsp=NULL;
|
||||
gErrorCode=U_ZERO_ERROR;
|
||||
gHaveData=0;
|
||||
}
|
||||
|
||||
/* Unicode case mapping data swapping --------------------------------------- */
|
||||
|
||||
U_CAPI int32_t U_EXPORT2
|
||||
|
@ -44,9 +44,6 @@ ucase_close(UCaseProps *csp);
|
||||
U_CAPI UCaseProps * U_EXPORT2
|
||||
ucase_getSingleton(UErrorCode *pErrorCode);
|
||||
|
||||
U_CFUNC void
|
||||
ucase_cleanup();
|
||||
|
||||
|
||||
U_CAPI int32_t U_EXPORT2
|
||||
ucase_swap(const UDataSwapper *ds,
|
||||
|
@ -95,8 +95,7 @@ isAcceptable(void *context,
|
||||
}
|
||||
}
|
||||
|
||||
UBool
|
||||
uchar_cleanup()
|
||||
static UBool U_CALLCONV uchar_cleanup(void)
|
||||
{
|
||||
if (propsData) {
|
||||
udata_close(propsData);
|
||||
@ -203,6 +202,7 @@ uprv_loadPropsData(UErrorCode *pErrorCode) {
|
||||
}
|
||||
|
||||
havePropsData=1;
|
||||
ucln_common_registerCleanup(UCLN_COMMON_UCHAR, uchar_cleanup);
|
||||
umtx_unlock(NULL);
|
||||
} else {
|
||||
dataErrorCode=*pErrorCode;
|
||||
|
@ -25,121 +25,28 @@
|
||||
#include "cmemory.h"
|
||||
#include "uassert.h"
|
||||
|
||||
static UBool gICUInitialized = FALSE;
|
||||
static UMTX gICUInitMutex = NULL;
|
||||
static cleanupFunc *gCommonCleanupFunctions[UCLN_COMMON_COUNT];
|
||||
|
||||
|
||||
static cleanupFunc *gCleanupFunctions[UCLN_COMMON] = {
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
U_CAPI void U_EXPORT2
|
||||
ucln_registerCleanup(ECleanupLibraryType type,
|
||||
cleanupFunc *func)
|
||||
void ucln_common_registerCleanup(ECleanupCommonType type,
|
||||
cleanupFunc *func)
|
||||
{
|
||||
U_ASSERT(UCLN_START < type && type < UCLN_COMMON);
|
||||
if (UCLN_START < type && type < UCLN_COMMON)
|
||||
U_ASSERT(UCLN_COMMON_START < type && type < UCLN_COMMON_COUNT);
|
||||
if (UCLN_COMMON_START < type && type < UCLN_COMMON_COUNT)
|
||||
{
|
||||
gCleanupFunctions[type] = func;
|
||||
gCommonCleanupFunctions[type] = func;
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************
|
||||
The cleanup order is important in this function.
|
||||
Please be sure that you have read ucln.h
|
||||
************************************************/
|
||||
U_CAPI void U_EXPORT2
|
||||
u_cleanup(void)
|
||||
{
|
||||
ECleanupLibraryType libType;
|
||||
U_CFUNC UBool ucln_common_lib_cleanup(void) {
|
||||
ECleanupCommonType commonFunc;
|
||||
|
||||
UTRACE_ENTRY_OC(UTRACE_U_CLEANUP);
|
||||
umtx_lock(NULL); /* Force a memory barrier, so that we are sure to see */
|
||||
umtx_unlock(NULL); /* all state left around by any other threads. */
|
||||
|
||||
for (libType = UCLN_START+1; libType<UCLN_COMMON; libType++) {
|
||||
if (gCleanupFunctions[libType])
|
||||
for (commonFunc = UCLN_COMMON_START+1; commonFunc<UCLN_COMMON_COUNT; commonFunc++) {
|
||||
if (gCommonCleanupFunctions[commonFunc])
|
||||
{
|
||||
gCleanupFunctions[libType]();
|
||||
gCleanupFunctions[libType] = NULL;
|
||||
gCommonCleanupFunctions[commonFunc]();
|
||||
gCommonCleanupFunctions[commonFunc] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#if !UCONFIG_NO_IDNA
|
||||
usprep_cleanup();
|
||||
#endif
|
||||
#if !UCONFIG_NO_BREAK_ITERATION
|
||||
breakiterator_cleanup();
|
||||
#endif
|
||||
#if !UCONFIG_NO_SERVICE
|
||||
service_cleanup();
|
||||
#endif
|
||||
ures_cleanup();
|
||||
locale_cleanup();
|
||||
uloc_cleanup();
|
||||
#if !UCONFIG_NO_NORMALIZATION
|
||||
unorm_cleanup();
|
||||
#endif
|
||||
uset_cleanup();
|
||||
unames_cleanup();
|
||||
pname_cleanup();
|
||||
ucase_cleanup();
|
||||
uchar_cleanup();
|
||||
#if !UCONFIG_NO_CONVERSION
|
||||
ucnv_cleanup();
|
||||
ucnv_io_cleanup();
|
||||
#endif
|
||||
udata_cleanup();
|
||||
putil_cleanup();
|
||||
|
||||
umtx_destroy(&gICUInitMutex);
|
||||
umtx_cleanup();
|
||||
cmemory_cleanup(); /* undo any heap functions set by u_setMemoryFunctions(). */
|
||||
gICUInitialized = FALSE;
|
||||
UTRACE_EXIT(); /* Must be before utrace_cleanup(), which turns off tracing. */
|
||||
utrace_cleanup();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* ICU Initialization Function. Force loading and/or initialization of
|
||||
* any shared data that could potentially be used concurrently
|
||||
* by multiple threads.
|
||||
*/
|
||||
|
||||
U_CAPI void U_EXPORT2
|
||||
u_init(UErrorCode *status) {
|
||||
UTRACE_ENTRY_OC(UTRACE_U_INIT);
|
||||
/* Make sure the global mutexes are initialized. */
|
||||
umtx_init(NULL);
|
||||
umtx_lock(&gICUInitMutex);
|
||||
if (gICUInitialized || U_FAILURE(*status)) {
|
||||
umtx_unlock(&gICUInitMutex);
|
||||
UTRACE_EXIT_STATUS(*status);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Do any required init for services that don't have open operations
|
||||
* and use "only" the double-check initialization method for performance
|
||||
* reasons (avoiding a mutex lock even for _checking_ whether the
|
||||
* initialization had occurred).
|
||||
*/
|
||||
|
||||
/* Char Properties */
|
||||
uprv_loadPropsData(status);
|
||||
|
||||
#if !UCONFIG_NO_NORMALIZATION
|
||||
/* Normalization */
|
||||
unorm_haveData(status);
|
||||
#endif
|
||||
gICUInitialized = TRUE; /* TODO: don't set if U_FAILURE? */
|
||||
umtx_unlock(&gICUInitMutex);
|
||||
UTRACE_EXIT_STATUS(*status);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* *
|
||||
* Copyright (C) 2001-2003, International Business Machines *
|
||||
* Copyright (C) 2001-2004, International Business Machines *
|
||||
* Corporation and others. All Rights Reserved. *
|
||||
* *
|
||||
******************************************************************************
|
||||
@ -18,45 +18,43 @@
|
||||
#define __UCLN_CMN_H__
|
||||
|
||||
#include "unicode/utypes.h"
|
||||
#include "ucln.h"
|
||||
|
||||
/* These are the cleanup functions for various APIs. */
|
||||
/* @return true if cleanup complete successfully.*/
|
||||
U_CFUNC UBool unames_cleanup(void);
|
||||
|
||||
U_CFUNC UBool unorm_cleanup(void);
|
||||
|
||||
U_CFUNC UBool uchar_cleanup(void);
|
||||
|
||||
U_CFUNC UBool pname_cleanup(void);
|
||||
|
||||
U_CFUNC UBool locale_cleanup(void);
|
||||
|
||||
U_CFUNC UBool uloc_cleanup(void);
|
||||
|
||||
U_CFUNC UBool breakiterator_cleanup(void);
|
||||
|
||||
U_CFUNC UBool usprep_cleanup(void);
|
||||
|
||||
U_CFUNC UBool U_EXPORT2 ucnv_cleanup(void);
|
||||
|
||||
U_CFUNC UBool ucnv_io_cleanup(void);
|
||||
|
||||
U_CFUNC UBool ures_cleanup(void);
|
||||
|
||||
U_CFUNC UBool udata_cleanup(void);
|
||||
|
||||
U_CFUNC UBool putil_cleanup(void);
|
||||
|
||||
U_CFUNC UBool uset_cleanup(void);
|
||||
|
||||
U_CFUNC UBool service_cleanup(void);
|
||||
|
||||
U_CFUNC UBool cmemory_cleanup(void);
|
||||
|
||||
U_CFUNC UBool umtx_cleanup(void);
|
||||
|
||||
U_CFUNC UBool utrace_cleanup(void);
|
||||
|
||||
U_CFUNC UBool ucln_common_lib_cleanup(void);
|
||||
|
||||
/*
|
||||
Please keep the order of enums declared in same order
|
||||
as the functions are suppose to be called. */
|
||||
typedef enum ECleanupCommonType {
|
||||
UCLN_COMMON_START = -1,
|
||||
UCLN_COMMON_USPREP,
|
||||
UCLN_COMMON_BREAKITERATOR,
|
||||
UCLN_COMMON_SERVICE,
|
||||
UCLN_COMMON_URES,
|
||||
UCLN_COMMON_LOCALE,
|
||||
UCLN_COMMON_ULOC,
|
||||
UCLN_COMMON_UNORM,
|
||||
UCLN_COMMON_USET,
|
||||
UCLN_COMMON_UNAMES,
|
||||
UCLN_COMMON_PNAME,
|
||||
UCLN_COMMON_UCASE,
|
||||
UCLN_COMMON_UCHAR,
|
||||
UCLN_COMMON_UCNV,
|
||||
UCLN_COMMON_UCNV_IO,
|
||||
UCLN_COMMON_UDATA,
|
||||
UCLN_COMMON_PUTIL,
|
||||
UCLN_COMMON_COUNT /* This must be last */
|
||||
} ECleanupCommonType;
|
||||
|
||||
/* Main library cleanup registration function. */
|
||||
/* See common/ucln.h for details on adding a cleanup function. */
|
||||
U_CFUNC void U_EXPORT2 ucln_common_registerCleanup(ECleanupCommonType type,
|
||||
cleanupFunc *func);
|
||||
|
||||
#endif
|
||||
|
@ -161,7 +161,7 @@ static const char DATA_TYPE[] = "cnv";
|
||||
/* by open converters. */
|
||||
/* Not thread safe. */
|
||||
/* Not supported API. Marked U_CAPI only for use by test programs. */
|
||||
U_CFUNC UBool U_EXPORT2 ucnv_cleanup(void) {
|
||||
static UBool U_CALLCONV ucnv_cleanup(void) {
|
||||
if (SHARED_DATA_HASHTABLE != NULL) {
|
||||
ucnv_flushCache();
|
||||
if (SHARED_DATA_HASHTABLE != NULL && uhash_count(SHARED_DATA_HASHTABLE) == 0) {
|
||||
@ -381,6 +381,8 @@ ucnv_shareConverterData(UConverterSharedData * data)
|
||||
SHARED_DATA_HASHTABLE = uhash_openSize(uhash_hashChars, uhash_compareChars,
|
||||
ucnv_io_countAvailableAliases(&err),
|
||||
&err);
|
||||
ucln_common_registerCleanup(UCLN_COMMON_UCNV, ucnv_cleanup);
|
||||
|
||||
if (U_FAILURE(err))
|
||||
return;
|
||||
}
|
||||
|
@ -219,6 +219,37 @@ isAcceptable(void *context,
|
||||
pInfo->formatVersion[0]==3);
|
||||
}
|
||||
|
||||
static UBool U_CALLCONV ucnv_io_cleanup(void)
|
||||
{
|
||||
if (gAliasData) {
|
||||
udata_close(gAliasData);
|
||||
gAliasData = NULL;
|
||||
}
|
||||
|
||||
ucnv_io_flushAvailableConverterCache();
|
||||
|
||||
gConverterListSize = 0;
|
||||
gTagListSize = 0;
|
||||
gAliasListSize = 0;
|
||||
gUntaggedConvArraySize = 0;
|
||||
gTaggedAliasArraySize = 0;
|
||||
gTaggedAliasListsSize = 0;
|
||||
gStringTableSize = 0;
|
||||
|
||||
gConverterList = NULL;
|
||||
gTagList = NULL;
|
||||
gAliasList = NULL;
|
||||
gUntaggedConvArray = NULL;
|
||||
gTaggedAliasArray = NULL;
|
||||
gTaggedAliasLists = NULL;
|
||||
gStringTable = NULL;
|
||||
|
||||
gDefaultConverterName = NULL;
|
||||
gDefaultConverterNameBuffer[0] = 0;
|
||||
|
||||
return TRUE; /* Everything was cleaned up */
|
||||
}
|
||||
|
||||
static UBool
|
||||
haveAliasData(UErrorCode *pErrorCode) {
|
||||
int haveData;
|
||||
@ -292,6 +323,7 @@ haveAliasData(UErrorCode *pErrorCode) {
|
||||
currOffset += reservedSize1;
|
||||
gStringTable = table + currOffset;
|
||||
|
||||
ucln_common_registerCleanup(UCLN_COMMON_UCNV_IO, ucnv_io_cleanup);
|
||||
}
|
||||
umtx_unlock(NULL);
|
||||
|
||||
@ -316,39 +348,6 @@ isAlias(const char *alias, UErrorCode *pErrorCode) {
|
||||
}
|
||||
}
|
||||
|
||||
UBool
|
||||
ucnv_io_cleanup()
|
||||
{
|
||||
if (gAliasData) {
|
||||
udata_close(gAliasData);
|
||||
gAliasData = NULL;
|
||||
}
|
||||
|
||||
ucnv_io_flushAvailableConverterCache();
|
||||
|
||||
gConverterListSize = 0;
|
||||
gTagListSize = 0;
|
||||
gAliasListSize = 0;
|
||||
gUntaggedConvArraySize = 0;
|
||||
gTaggedAliasArraySize = 0;
|
||||
gTaggedAliasListsSize = 0;
|
||||
gStringTableSize = 0;
|
||||
|
||||
gConverterList = NULL;
|
||||
gTagList = NULL;
|
||||
gAliasList = NULL;
|
||||
gUntaggedConvArray = NULL;
|
||||
gTaggedAliasArray = NULL;
|
||||
gTaggedAliasLists = NULL;
|
||||
gStringTable = NULL;
|
||||
|
||||
gDefaultConverterName = NULL;
|
||||
gDefaultConverterNameBuffer[0] = 0;
|
||||
|
||||
return TRUE; /* Everything was cleaned up */
|
||||
}
|
||||
|
||||
|
||||
static uint32_t getTagNumber(const char *tagname) {
|
||||
if (gTagList) {
|
||||
uint32_t tagNum;
|
||||
@ -889,6 +888,7 @@ static UBool haveAvailableConverterList(UErrorCode *pErrorCode) {
|
||||
if (gAvailableConverters == NULL) {
|
||||
gAvailableConverters = localConverterList;
|
||||
gAvailableConverterCount = localConverterCount;
|
||||
/* haveData should have already registered the cleanup function */
|
||||
}
|
||||
else {
|
||||
uprv_free((char **)localConverterList);
|
||||
@ -1045,6 +1045,7 @@ ucnv_io_getDefaultConverterName() {
|
||||
gDefaultConverterNameBuffer[length]=0;
|
||||
gDefaultConverterName = gDefaultConverterNameBuffer;
|
||||
name = gDefaultConverterName;
|
||||
ucln_common_registerCleanup(UCLN_COMMON_UCNV_IO, ucnv_io_cleanup);
|
||||
umtx_unlock(NULL);
|
||||
|
||||
/* The close may make the current name go away. */
|
||||
|
@ -78,8 +78,8 @@ static UDataMemory *gStubICUData = NULL; /* If gCommonICUData does get upda
|
||||
static UHashtable *gCommonDataCache = NULL; /* Global hash table of opened ICU data files. */
|
||||
|
||||
|
||||
UBool
|
||||
udata_cleanup()
|
||||
static UBool U_CALLCONV
|
||||
udata_cleanup(void)
|
||||
{
|
||||
if (gCommonDataCache) { /* Delete the cache of user data mappings. */
|
||||
uhash_close(gCommonDataCache); /* Table owns the contents, and will delete them. */
|
||||
@ -128,6 +128,7 @@ setCommonICUData(UDataMemory *pData, /* The new common data. Belongs to ca
|
||||
if (gCommonICUData==oldData) {
|
||||
gStubICUData = gCommonICUData; /* remember the old Common Data, so it can be cleaned up. */
|
||||
gCommonICUData = newCommonData;
|
||||
ucln_common_registerCleanup(UCLN_COMMON_UDATA, udata_cleanup);
|
||||
}
|
||||
else {
|
||||
if (warn==TRUE) {
|
||||
@ -222,6 +223,7 @@ static UHashtable *udata_getHashTable() {
|
||||
if (gCommonDataCache == NULL) {
|
||||
gCommonDataCache = tHT;
|
||||
tHT = NULL;
|
||||
ucln_common_registerCleanup(UCLN_COMMON_UDATA, udata_cleanup);
|
||||
}
|
||||
umtx_unlock(NULL);
|
||||
if (tHT != NULL) {
|
||||
|
111
icu4c/source/common/uinit.c
Normal file
111
icu4c/source/common/uinit.c
Normal file
@ -0,0 +1,111 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* *
|
||||
* Copyright (C) 2001-2004, International Business Machines *
|
||||
* Corporation and others. All Rights Reserved. *
|
||||
* *
|
||||
******************************************************************************
|
||||
* file name: uinit.c
|
||||
* encoding: US-ASCII
|
||||
* tab size: 8 (not used)
|
||||
* indentation:4
|
||||
*
|
||||
* created on: 2001July05
|
||||
* created by: George Rhoten
|
||||
*/
|
||||
|
||||
#include "unicode/utypes.h"
|
||||
#include "unicode/uclean.h"
|
||||
#include "utracimp.h"
|
||||
#include "ustr_imp.h"
|
||||
#include "unormimp.h"
|
||||
#include "ucln_cmn.h"
|
||||
#include "umutex.h"
|
||||
#include "ucln.h"
|
||||
#include "cmemory.h"
|
||||
#include "uassert.h"
|
||||
|
||||
static UBool gICUInitialized = FALSE;
|
||||
static UMTX gICUInitMutex = NULL;
|
||||
|
||||
|
||||
static cleanupFunc *gLibCleanupFunctions[UCLN_COMMON];
|
||||
|
||||
U_CAPI void U_EXPORT2
|
||||
ucln_registerCleanup(ECleanupLibraryType type,
|
||||
cleanupFunc *func)
|
||||
{
|
||||
U_ASSERT(UCLN_START < type && type < UCLN_COMMON);
|
||||
if (UCLN_START < type && type < UCLN_COMMON)
|
||||
{
|
||||
gLibCleanupFunctions[type] = func;
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************
|
||||
The cleanup order is important in this function.
|
||||
Please be sure that you have read ucln.h
|
||||
************************************************/
|
||||
U_CAPI void U_EXPORT2
|
||||
u_cleanup(void)
|
||||
{
|
||||
ECleanupLibraryType libType;
|
||||
|
||||
UTRACE_ENTRY_OC(UTRACE_U_CLEANUP);
|
||||
umtx_lock(NULL); /* Force a memory barrier, so that we are sure to see */
|
||||
umtx_unlock(NULL); /* all state left around by any other threads. */
|
||||
|
||||
for (libType = UCLN_START+1; libType<UCLN_COMMON; libType++) {
|
||||
if (gLibCleanupFunctions[libType])
|
||||
{
|
||||
gLibCleanupFunctions[libType]();
|
||||
gLibCleanupFunctions[libType] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
ucln_common_lib_cleanup();
|
||||
|
||||
umtx_destroy(&gICUInitMutex);
|
||||
umtx_cleanup();
|
||||
cmemory_cleanup(); /* undo any heap functions set by u_setMemoryFunctions(). */
|
||||
gICUInitialized = FALSE;
|
||||
UTRACE_EXIT(); /* Must be before utrace_cleanup(), which turns off tracing. */
|
||||
utrace_cleanup();
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* ICU Initialization Function. Force loading and/or initialization of
|
||||
* any shared data that could potentially be used concurrently
|
||||
* by multiple threads.
|
||||
*/
|
||||
U_CAPI void U_EXPORT2
|
||||
u_init(UErrorCode *status) {
|
||||
UTRACE_ENTRY_OC(UTRACE_U_INIT);
|
||||
/* Make sure the global mutexes are initialized. */
|
||||
umtx_init(NULL);
|
||||
umtx_lock(&gICUInitMutex);
|
||||
if (gICUInitialized || U_FAILURE(*status)) {
|
||||
umtx_unlock(&gICUInitMutex);
|
||||
UTRACE_EXIT_STATUS(*status);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Do any required init for services that don't have open operations
|
||||
* and use "only" the double-check initialization method for performance
|
||||
* reasons (avoiding a mutex lock even for _checking_ whether the
|
||||
* initialization had occurred).
|
||||
*/
|
||||
|
||||
/* Char Properties */
|
||||
uprv_loadPropsData(status);
|
||||
|
||||
#if !UCONFIG_NO_NORMALIZATION
|
||||
/* Normalization */
|
||||
unorm_haveData(status);
|
||||
#endif
|
||||
gICUInitialized = TRUE; /* TODO: don't set if U_FAILURE? */
|
||||
umtx_unlock(&gICUInitMutex);
|
||||
UTRACE_EXIT_STATUS(*status);
|
||||
}
|
||||
|
@ -2660,6 +2660,20 @@ uloc_getDisplayKeywordValue( const char* locale,
|
||||
|
||||
/* ### Get available **************************************************/
|
||||
|
||||
static UBool U_CALLCONV uloc_cleanup(void) {
|
||||
char ** temp;
|
||||
|
||||
if (_installedLocales) {
|
||||
temp = _installedLocales;
|
||||
_installedLocales = NULL;
|
||||
|
||||
_installedLocalesCount = 0;
|
||||
|
||||
uprv_free(temp);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void _load_installedLocales()
|
||||
{
|
||||
UBool localesLoaded;
|
||||
@ -2696,6 +2710,7 @@ static void _load_installedLocales()
|
||||
_installedLocales = temp;
|
||||
_installedLocalesCount = localeCount;
|
||||
temp = NULL;
|
||||
ucln_common_registerCleanup(UCLN_COMMON_ULOC, uloc_cleanup);
|
||||
}
|
||||
umtx_unlock(NULL);
|
||||
|
||||
@ -2724,20 +2739,6 @@ uloc_countAvailable()
|
||||
return _installedLocalesCount;
|
||||
}
|
||||
|
||||
UBool uloc_cleanup(void) {
|
||||
char ** temp;
|
||||
|
||||
if (_installedLocales) {
|
||||
temp = _installedLocales;
|
||||
_installedLocales = NULL;
|
||||
|
||||
_installedLocalesCount = 0;
|
||||
|
||||
uprv_free(temp);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of all language codes defined in ISO 639. This is a pointer
|
||||
* to an array of pointers to arrays of char. All of these pointers are owned
|
||||
|
@ -85,8 +85,7 @@ charCatNames[U_CHAR_EXTENDED_CATEGORY_COUNT];
|
||||
|
||||
/* implementation ----------------------------------------------------------- */
|
||||
|
||||
UBool
|
||||
unames_cleanup()
|
||||
static UBool U_CALLCONV unames_cleanup(void)
|
||||
{
|
||||
if(uCharNamesData) {
|
||||
udata_close(uCharNamesData);
|
||||
@ -151,6 +150,7 @@ isDataLoaded(UErrorCode *pErrorCode) {
|
||||
uCharNamesData=data;
|
||||
data=NULL;
|
||||
names=NULL;
|
||||
ucln_common_registerCleanup(UCLN_COMMON_UNAMES, unames_cleanup);
|
||||
}
|
||||
umtx_unlock(NULL);
|
||||
}
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "ruleiter.h"
|
||||
#include "cmemory.h"
|
||||
#include "uhash.h"
|
||||
#include "ucln_cmn.h"
|
||||
#include "util.h"
|
||||
#include "uvector.h"
|
||||
#include "uprops.h"
|
||||
@ -1464,6 +1465,32 @@ _set_addString(USet *set, const UChar *str, int32_t length) {
|
||||
((UnicodeSet *)set)->add(UnicodeString((UBool)(length<0), str, length));
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleanup function for UnicodeSet
|
||||
*/
|
||||
static UBool U_CALLCONV uset_cleanup(void) {
|
||||
int32_t i;
|
||||
|
||||
for(i = UPROPS_SRC_NONE; i < UPROPS_SRC_COUNT; ++i) {
|
||||
if (INCLUSIONS[i] != NULL) {
|
||||
delete INCLUSIONS[i];
|
||||
INCLUSIONS[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (CASE_EQUIV_HASH != NULL) {
|
||||
delete CASE_EQUIV_HASH;
|
||||
CASE_EQUIV_HASH = NULL;
|
||||
}
|
||||
|
||||
if (CASE_EQUIV_CBA != NULL) {
|
||||
ucmp8_close(CASE_EQUIV_CBA);
|
||||
CASE_EQUIV_CBA = NULL;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
U_CDECL_END
|
||||
|
||||
const UnicodeSet* UnicodeSet::getInclusions(int32_t src, UErrorCode &status) {
|
||||
@ -1503,8 +1530,9 @@ const UnicodeSet* UnicodeSet::getInclusions(int32_t src, UErrorCode &status) {
|
||||
umtx_lock(NULL);
|
||||
if (INCLUSIONS[src] == NULL) {
|
||||
INCLUSIONS[src] = incl;
|
||||
incl = NULL;
|
||||
}
|
||||
incl = NULL;
|
||||
ucln_common_registerCleanup(UCLN_COMMON_USET, uset_cleanup);
|
||||
}
|
||||
umtx_unlock(NULL);
|
||||
}
|
||||
delete incl;
|
||||
@ -1515,32 +1543,6 @@ const UnicodeSet* UnicodeSet::getInclusions(int32_t src, UErrorCode &status) {
|
||||
return INCLUSIONS[src];
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleanup function for UnicodeSet
|
||||
*/
|
||||
U_CFUNC UBool uset_cleanup(void) {
|
||||
int32_t i;
|
||||
|
||||
for(i = UPROPS_SRC_NONE; i < UPROPS_SRC_COUNT; ++i) {
|
||||
if (INCLUSIONS[i] != NULL) {
|
||||
delete INCLUSIONS[i];
|
||||
INCLUSIONS[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (CASE_EQUIV_HASH != NULL) {
|
||||
delete CASE_EQUIV_HASH;
|
||||
CASE_EQUIV_HASH = NULL;
|
||||
}
|
||||
|
||||
if (CASE_EQUIV_CBA != NULL) {
|
||||
ucmp8_close(CASE_EQUIV_CBA);
|
||||
CASE_EQUIV_CBA = NULL;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Case folding API
|
||||
//----------------------------------------------------------------
|
||||
@ -2030,6 +2032,7 @@ const CaseEquivClass* UnicodeSet::getCaseMapOf(const UnicodeString& folded) {
|
||||
if (CASE_EQUIV_HASH == NULL) {
|
||||
CASE_EQUIV_HASH = hash;
|
||||
hash = NULL;
|
||||
ucln_common_registerCleanup(UCLN_COMMON_USET, uset_cleanup);
|
||||
}
|
||||
umtx_unlock(NULL);
|
||||
}
|
||||
@ -2073,6 +2076,7 @@ const CaseEquivClass* UnicodeSet::getCaseMapOf(UChar folded) {
|
||||
if (CASE_EQUIV_CBA == NULL) {
|
||||
CASE_EQUIV_CBA = cba;
|
||||
cba = NULL;
|
||||
ucln_common_registerCleanup(UCLN_COMMON_USET, uset_cleanup);
|
||||
}
|
||||
umtx_unlock(NULL);
|
||||
if (cba != NULL) {
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "unicode/uniset.h"
|
||||
#include "unicode/usetiter.h"
|
||||
#include "unicode/unorm.h"
|
||||
#include "ucln_cmn.h"
|
||||
#include "unormimp.h"
|
||||
#include "ucase.h"
|
||||
#include "cmemory.h"
|
||||
@ -189,7 +190,7 @@ static UnicodeSet *nxCache[_NORM_OPTIONS_SETS_MASK+1]={ NULL };
|
||||
|
||||
U_CDECL_BEGIN
|
||||
|
||||
UBool
|
||||
static UBool U_CALLCONV
|
||||
unorm_cleanup() {
|
||||
int32_t i;
|
||||
|
||||
@ -348,6 +349,7 @@ loadNormData(UErrorCode &errorCode) {
|
||||
(indexes[_NORM_INDEX_FCD_TRIE_SIZE]+indexes[_NORM_INDEX_AUX_TRIE_SIZE])/2;
|
||||
}
|
||||
haveNormData=1;
|
||||
ucln_common_registerCleanup(UCLN_COMMON_UNORM, unorm_cleanup);
|
||||
umtx_unlock(NULL);
|
||||
|
||||
/* if a different thread set it first, then close the extra data */
|
||||
|
@ -138,29 +138,6 @@ static const ResourceData *getFallbackData(const UResourceBundle* resBundle, con
|
||||
}
|
||||
}
|
||||
|
||||
/** INTERNAL: Initializes the cache for resources */
|
||||
static void initCache(UErrorCode *status) {
|
||||
UBool makeCache = FALSE;
|
||||
umtx_lock(&resbMutex);
|
||||
makeCache = (cache == NULL);
|
||||
umtx_unlock(&resbMutex);
|
||||
if(makeCache) {
|
||||
UHashtable *newCache = uhash_open(hashEntry, compareEntries, status);
|
||||
if (U_FAILURE(*status)) {
|
||||
return;
|
||||
}
|
||||
umtx_lock(&resbMutex);
|
||||
if(cache == NULL) {
|
||||
cache = newCache;
|
||||
newCache = NULL;
|
||||
}
|
||||
umtx_unlock(&resbMutex);
|
||||
if(newCache != NULL) {
|
||||
uhash_close(newCache);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Works just like ucnv_flushCache() */
|
||||
/* TODO: figure out why fCountExisting may not go to zero. Do not make this function public yet. */
|
||||
static int32_t ures_flushCache()
|
||||
@ -214,7 +191,7 @@ static int32_t ures_flushCache()
|
||||
return rbDeletedNum;
|
||||
}
|
||||
|
||||
UBool ures_cleanup(void)
|
||||
static UBool U_CALLCONV ures_cleanup(void)
|
||||
{
|
||||
if (cache != NULL) {
|
||||
ures_flushCache();
|
||||
@ -229,6 +206,29 @@ UBool ures_cleanup(void)
|
||||
return (cache == NULL);
|
||||
}
|
||||
|
||||
/** INTERNAL: Initializes the cache for resources */
|
||||
static void initCache(UErrorCode *status) {
|
||||
UBool makeCache = FALSE;
|
||||
umtx_lock(&resbMutex);
|
||||
makeCache = (cache == NULL);
|
||||
umtx_unlock(&resbMutex);
|
||||
if(makeCache) {
|
||||
UHashtable *newCache = uhash_open(hashEntry, compareEntries, status);
|
||||
if (U_FAILURE(*status)) {
|
||||
return;
|
||||
}
|
||||
umtx_lock(&resbMutex);
|
||||
if(cache == NULL) {
|
||||
cache = newCache;
|
||||
newCache = NULL;
|
||||
ucln_common_registerCleanup(UCLN_COMMON_URES, ures_cleanup);
|
||||
}
|
||||
umtx_unlock(&resbMutex);
|
||||
if(newCache != NULL) {
|
||||
uhash_close(newCache);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** INTERNAL: sets the name (locale) of the resource bundle to given name */
|
||||
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "uhash.h"
|
||||
#include "cstring.h"
|
||||
#include "udataswp.h"
|
||||
#include "ucln_cmn.h"
|
||||
#include "unormimp.h"
|
||||
|
||||
U_CDECL_BEGIN
|
||||
@ -104,9 +105,85 @@ compareEntries(const UHashTok p1, const UHashTok p2) {
|
||||
uhash_compareChars(path1, path2)));
|
||||
}
|
||||
|
||||
static void
|
||||
usprep_unload(UStringPrepProfile* data){
|
||||
udata_close(data->sprepData);
|
||||
}
|
||||
|
||||
static int32_t
|
||||
usprep_internal_flushCache(UBool noRefCount){
|
||||
UStringPrepProfile *profile = NULL;
|
||||
UStringPrepKey *key = NULL;
|
||||
int32_t pos = -1;
|
||||
int32_t deletedNum = 0;
|
||||
const UHashElement *e;
|
||||
|
||||
/*
|
||||
* if shared data hasn't even been lazy evaluated yet
|
||||
* return 0
|
||||
*/
|
||||
umtx_lock(&usprepMutex);
|
||||
if (SHARED_DATA_HASHTABLE == NULL) {
|
||||
umtx_unlock(&usprepMutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*creates an enumeration to iterate through every element in the table */
|
||||
while ((e = uhash_nextElement(SHARED_DATA_HASHTABLE, &pos)) != NULL)
|
||||
{
|
||||
profile = (UStringPrepProfile *) e->value.pointer;
|
||||
key = (UStringPrepKey *) e->key.pointer;
|
||||
|
||||
if ((noRefCount== FALSE && profile->refCount == 0) ||
|
||||
noRefCount== TRUE) {
|
||||
deletedNum++;
|
||||
uhash_removeElement(SHARED_DATA_HASHTABLE, e);
|
||||
|
||||
/* unload the data */
|
||||
usprep_unload(profile);
|
||||
|
||||
if(key->name != NULL) {
|
||||
uprv_free(key->name);
|
||||
key->name=NULL;
|
||||
}
|
||||
if(key->path != NULL) {
|
||||
uprv_free(key->path);
|
||||
key->path=NULL;
|
||||
}
|
||||
uprv_free(profile);
|
||||
uprv_free(key);
|
||||
}
|
||||
|
||||
}
|
||||
umtx_unlock(&usprepMutex);
|
||||
|
||||
return deletedNum;
|
||||
}
|
||||
|
||||
/* Works just like ucnv_flushCache()
|
||||
static int32_t
|
||||
usprep_flushCache(){
|
||||
return usprep_internal_flushCache(FALSE);
|
||||
}
|
||||
*/
|
||||
|
||||
static UBool U_CALLCONV usprep_cleanup(void){
|
||||
if (SHARED_DATA_HASHTABLE != NULL) {
|
||||
usprep_internal_flushCache(TRUE);
|
||||
if (SHARED_DATA_HASHTABLE != NULL && uhash_count(SHARED_DATA_HASHTABLE) == 0) {
|
||||
uhash_close(SHARED_DATA_HASHTABLE);
|
||||
SHARED_DATA_HASHTABLE = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
umtx_destroy(&usprepMutex); /* Don't worry about destroying the mutex even */
|
||||
/* if the hash table still exists. The mutex */
|
||||
/* will lazily re-init itself if needed. */
|
||||
return (SHARED_DATA_HASHTABLE == NULL);
|
||||
}
|
||||
U_CDECL_END
|
||||
|
||||
U_CFUNC void
|
||||
static void
|
||||
usprep_init() {
|
||||
umtx_init(&usprepMutex);
|
||||
}
|
||||
@ -114,25 +191,26 @@ usprep_init() {
|
||||
/** Initializes the cache for resources */
|
||||
static void
|
||||
initCache(UErrorCode *status) {
|
||||
UBool makeCache = FALSE;
|
||||
umtx_lock(&usprepMutex);
|
||||
makeCache = (SHARED_DATA_HASHTABLE == NULL);
|
||||
umtx_unlock(&usprepMutex);
|
||||
if(makeCache) {
|
||||
UHashtable *newCache = uhash_open(hashEntry, compareEntries, status);
|
||||
if (U_FAILURE(*status)) {
|
||||
return;
|
||||
}
|
||||
umtx_lock(&usprepMutex);
|
||||
if(SHARED_DATA_HASHTABLE == NULL) {
|
||||
SHARED_DATA_HASHTABLE = newCache;
|
||||
newCache = NULL;
|
||||
}
|
||||
umtx_unlock(&usprepMutex);
|
||||
if(newCache != NULL) {
|
||||
uhash_close(newCache);
|
||||
}
|
||||
}
|
||||
UBool makeCache = FALSE;
|
||||
umtx_lock(&usprepMutex);
|
||||
makeCache = (SHARED_DATA_HASHTABLE == NULL);
|
||||
umtx_unlock(&usprepMutex);
|
||||
if(makeCache) {
|
||||
UHashtable *newCache = uhash_open(hashEntry, compareEntries, status);
|
||||
if (U_FAILURE(*status)) {
|
||||
return;
|
||||
}
|
||||
umtx_lock(&usprepMutex);
|
||||
if(SHARED_DATA_HASHTABLE == NULL) {
|
||||
SHARED_DATA_HASHTABLE = newCache;
|
||||
ucln_common_registerCleanup(UCLN_COMMON_USPREP, usprep_cleanup);
|
||||
newCache = NULL;
|
||||
}
|
||||
umtx_unlock(&usprepMutex);
|
||||
if(newCache != NULL) {
|
||||
uhash_close(newCache);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static UBool U_CALLCONV
|
||||
@ -337,85 +415,6 @@ usprep_close(UStringPrepProfile* profile){
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
usprep_unload(UStringPrepProfile* data){
|
||||
udata_close(data->sprepData);
|
||||
}
|
||||
|
||||
|
||||
static int32_t
|
||||
usprep_internal_flushCache(UBool noRefCount){
|
||||
UStringPrepProfile *profile = NULL;
|
||||
UStringPrepKey *key = NULL;
|
||||
int32_t pos = -1;
|
||||
int32_t deletedNum = 0;
|
||||
const UHashElement *e;
|
||||
|
||||
/*
|
||||
* if shared data hasn't even been lazy evaluated yet
|
||||
* return 0
|
||||
*/
|
||||
umtx_lock(&usprepMutex);
|
||||
if (SHARED_DATA_HASHTABLE == NULL) {
|
||||
umtx_unlock(&usprepMutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*creates an enumeration to iterate through every element in the table */
|
||||
while ((e = uhash_nextElement(SHARED_DATA_HASHTABLE, &pos)) != NULL)
|
||||
{
|
||||
profile = (UStringPrepProfile *) e->value.pointer;
|
||||
key = (UStringPrepKey *) e->key.pointer;
|
||||
|
||||
if ((noRefCount== FALSE && profile->refCount == 0) ||
|
||||
noRefCount== TRUE) {
|
||||
deletedNum++;
|
||||
uhash_removeElement(SHARED_DATA_HASHTABLE, e);
|
||||
|
||||
/* unload the data */
|
||||
usprep_unload(profile);
|
||||
|
||||
if(key->name != NULL) {
|
||||
uprv_free(key->name);
|
||||
key->name=NULL;
|
||||
}
|
||||
if(key->path != NULL) {
|
||||
uprv_free(key->path);
|
||||
key->path=NULL;
|
||||
}
|
||||
uprv_free(profile);
|
||||
uprv_free(key);
|
||||
}
|
||||
|
||||
}
|
||||
umtx_unlock(&usprepMutex);
|
||||
|
||||
return deletedNum;
|
||||
}
|
||||
|
||||
/* Works just like ucnv_flushCache()
|
||||
static int32_t
|
||||
usprep_flushCache(){
|
||||
return usprep_internal_flushCache(FALSE);
|
||||
}
|
||||
*/
|
||||
|
||||
U_CFUNC UBool
|
||||
usprep_cleanup(void){
|
||||
if (SHARED_DATA_HASHTABLE != NULL) {
|
||||
usprep_internal_flushCache(TRUE);
|
||||
if (SHARED_DATA_HASHTABLE != NULL && uhash_count(SHARED_DATA_HASHTABLE) == 0) {
|
||||
uhash_close(SHARED_DATA_HASHTABLE);
|
||||
SHARED_DATA_HASHTABLE = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
umtx_destroy(&usprepMutex); /* Don't worry about destroying the mutex even */
|
||||
/* if the hash table still exists. The mutex */
|
||||
/* will lazily re-init itself if needed. */
|
||||
return (SHARED_DATA_HASHTABLE == NULL);
|
||||
}
|
||||
|
||||
U_CFUNC void
|
||||
uprv_syntaxError(const UChar* rules,
|
||||
int32_t pos,
|
||||
|
Loading…
Reference in New Issue
Block a user