From 467cf876fc78d135e346168fe168f73e26573ed5 Mon Sep 17 00:00:00 2001 From: Michael Grady Date: Thu, 16 Sep 2010 00:49:01 +0000 Subject: [PATCH] ICU-7948 Fix leak in usprep_getProfile when 2 threads race to insert profile data into hash X-SVN-Rev: 28627 --- icu4c/source/common/usprep.cpp | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/icu4c/source/common/usprep.cpp b/icu4c/source/common/usprep.cpp index 29599e6c110..5e25d9f385b 100644 --- a/icu4c/source/common/usprep.cpp +++ b/icu4c/source/common/usprep.cpp @@ -374,19 +374,27 @@ usprep_getProfile(const char* path, return NULL; } - /* initialize the key members */ - key->name = keyName.orphan(); - uprv_strcpy(key->name, name); - if(path != NULL){ - key->path = keyPath.orphan(); - uprv_strcpy(key->path, path); - } - - profile = newProfile.orphan(); umtx_lock(&usprepMutex); - /* add the data object to the cache */ - profile->refCount = 1; - uhash_put(SHARED_DATA_HASHTABLE, key.orphan(), profile, status); + // If another thread already inserted the same key/value, refcount and cleanup our thread data + profile = (UStringPrepProfile*) (uhash_get(SHARED_DATA_HASHTABLE,&stackKey)); + if(profile != NULL) { + profile->refCount++; + usprep_unload(newProfile.getAlias()); + } + else { + /* initialize the key members */ + key->name = keyName.orphan(); + uprv_strcpy(key->name, name); + if(path != NULL){ + key->path = keyPath.orphan(); + uprv_strcpy(key->path, path); + } + profile = newProfile.orphan(); + + /* add the data object to the cache */ + profile->refCount = 1; + uhash_put(SHARED_DATA_HASHTABLE, key.orphan(), profile, status); + } umtx_unlock(&usprepMutex); }