From 250331389ced8d95ff61aaa782c24c68a76ccfe8 Mon Sep 17 00:00:00 2001 From: Vladimir Weinstein Date: Mon, 14 Aug 2000 23:11:00 +0000 Subject: [PATCH] ICU-548 converter leaks fixes X-SVN-Rev: 2230 --- icu4c/source/common/ucnv.c | 21 ++++++++++++ icu4c/source/common/ucnv_bld.c | 44 ++++++++++++++++++++++++-- icu4c/source/common/ucnvsbcs.c | 2 -- icu4c/source/tools/makeconv/makeconv.c | 12 +++++++ 4 files changed, 74 insertions(+), 5 deletions(-) diff --git a/icu4c/source/common/ucnv.c b/icu4c/source/common/ucnv.c index 3d738da91df..f498f34dcf9 100644 --- a/icu4c/source/common/ucnv.c +++ b/icu4c/source/common/ucnv.c @@ -34,6 +34,25 @@ #include "unicode/uloc.h" #include "ucnv_bld.h" +#if 0 +/* debugging for converters */ +# include +void UCNV_DEBUG_LOG(char *what, char *who, void *p, int l) +{ + static FILE *f = NULL; + if(f==NULL) + { + f = fopen("c:\\UCNV_DEBUG_LOG.txt", "w"); + } + fprintf(f, "%-20s %-10s %p@%d\n", + who,what,p,l); + fflush(f); +} +# define UCNV_DEBUG_LOG(x,y,z) UCNV_DEBUG_LOG(x,y,z,__LINE__) +#else +# define UCNV_DEBUG_LOG(x,y,z) +#endif + #define CHUNK_SIZE 5*1024 /* Internal function : begin */ @@ -190,6 +209,8 @@ int32_t ucnv_flushCache () { tableDeletedNum++; + UCNV_DEBUG_LOG("del",mySharedData->staticData->name,mySharedData); + uhash_removeElement(SHARED_DATA_HASHTABLE, e); deleteSharedConverterData (mySharedData); } diff --git a/icu4c/source/common/ucnv_bld.c b/icu4c/source/common/ucnv_bld.c index 1e6196fae3f..84a6887aeb9 100644 --- a/icu4c/source/common/ucnv_bld.c +++ b/icu4c/source/common/ucnv_bld.c @@ -37,6 +37,13 @@ #include +#if 0 +extern void UCNV_DEBUG_LOG(char *what, char *who, void *p, int l); +#define UCNV_DEBUG_LOG(x,y,z) UCNV_DEBUG_LOG(x,y,z,__LINE__) +#else +# define UCNV_DEBUG_LOG(x,y,z) +#endif + static const UConverterSharedData * converterData[UCNV_NUMBER_OF_SUPPORTED_CONVERTER_TYPES]={ &_SBCSData, &_DBCSData, &_MBCSData, &_Latin1Data, @@ -93,6 +100,14 @@ U_CAPI UConverterSharedData* U_EXPORT2 ucnv_data_unFlattenClone(UDataMemory *pD /*initializes some global variables */ UHashtable *SHARED_DATA_HASHTABLE = NULL; +#if 0 +/* For MEMORY LEAK checking.. */ +U_CAPI void U_EXPORT2 ucnv_orphanAllConverters() +{ + SHARED_DATA_HASHTABLE = NULL; /* will leak: hashtable + hashtable elements */ +} +#endif + static UBool isCnvAcceptable(void *context, const char *type, const char *name, @@ -175,6 +190,7 @@ void shareConverterData (UConverterSharedData * data) { UErrorCode err = U_ZERO_ERROR; /*Lazy evaluates the Hashtable itself */ + void *sanity = NULL; if (SHARED_DATA_HASHTABLE == NULL) { @@ -190,11 +206,22 @@ void shareConverterData (UConverterSharedData * data) } umtx_lock (NULL); /* ### check to see if the element is not already there! */ - uhash_put(SHARED_DATA_HASHTABLE, - (void*) data->staticData->name, /* Okay to cast away const as long as + +#if 0 + sanity = getSharedConverterData (data->staticData->name); + if(sanity != NULL) + { + UCNV_DEBUG_LOG("put:overwrite!",data->staticData->name,sanity); + } + UCNV_DEBUG_LOG("put:chk",data->staticData->name,sanity); +#endif + + uhash_put(SHARED_DATA_HASHTABLE, + (void*) data->staticData->name, /* Okay to cast away const as long as keyDeleter == NULL */ data, &err); + UCNV_DEBUG_LOG("put",data->staticData->name,data); umtx_unlock (NULL); return; @@ -206,7 +233,13 @@ UConverterSharedData *getSharedConverterData (const char *name) if (SHARED_DATA_HASHTABLE == NULL) return NULL; else { - return (UConverterSharedData*)uhash_get (SHARED_DATA_HASHTABLE, name); + UConverterSharedData *rc; + +umtx_lock(NULL); + rc = (UConverterSharedData*)uhash_get (SHARED_DATA_HASHTABLE, name); +umtx_unlock(NULL); + UCNV_DEBUG_LOG("get",name,rc); + return rc; } } @@ -241,6 +274,11 @@ UBool deleteSharedConverterData (UConverterSharedData * deadSharedData) udata_close(data); } + if(deadSharedData->table != NULL) + { + uprv_free(deadSharedData->table); + } + uprv_free (deadSharedData); return TRUE; diff --git a/icu4c/source/common/ucnvsbcs.c b/icu4c/source/common/ucnvsbcs.c index 80c8e0aa2d0..bd52063c6ed 100644 --- a/icu4c/source/common/ucnvsbcs.c +++ b/icu4c/source/common/ucnvsbcs.c @@ -56,7 +56,6 @@ _SBCSUnload(UConverterSharedData *sharedData) { ucmp8_close (&sharedData->table->sbcs.fromUnicode); if (sharedData->staticData->hasFromUnicodeFallback == TRUE) ucmp8_close (&sharedData->table->sbcs.fromUnicodeFallback); - uprv_free (sharedData->table); } U_CFUNC void T_UConverter_toUnicode_SBCS (UConverterToUnicodeArgs * args, @@ -405,7 +404,6 @@ _DBCSUnload(UConverterSharedData *sharedData) { ucmp16_close (&sharedData->table->dbcs.fromUnicodeFallback); if (sharedData->staticData->hasToUnicodeFallback == TRUE) ucmp16_close (&sharedData->table->dbcs.toUnicodeFallback); - uprv_free (sharedData->table); } U_CFUNC void T_UConverter_toUnicode_DBCS (UConverterToUnicodeArgs * args, diff --git a/icu4c/source/tools/makeconv/makeconv.c b/icu4c/source/tools/makeconv/makeconv.c index 1eecb1a6a5e..eb5a91c6711 100644 --- a/icu4c/source/tools/makeconv/makeconv.c +++ b/icu4c/source/tools/makeconv/makeconv.c @@ -372,6 +372,17 @@ int main(int argc, const char *argv[]) } else { + /* Make the static data name equal to the file name */ + if( /*VERBOSE && */ uprv_stricmp(cnvName,mySharedData->staticData->name)) + { + fprintf(stderr, "Warning: %s%s claims to be '%s'\n", + cnvName, + CONVERTER_FILE_EXTENSION, + mySharedData->staticData->name); + } + + uprv_strcpy((char*)mySharedData->staticData->name, cnvName); + writeConverterData(mySharedData, cnvName, destdir, &err); makeconv_deleteSharedConverterData(mySharedData); @@ -1125,6 +1136,7 @@ UConverterSharedData* createConverterFromTableFile(const char* converterName, UE myStaticData->structSize = sizeof(UConverterStaticData); mySharedData->staticDataOwned = TRUE; + uprv_strcpy(myStaticData->name, converterName); mySharedData->dataMemory = NULL; /* for init */