static UStringPrepProfile* usprep_getProfile(const char* path, const char* name, UErrorCode *status){ UStringPrepProfile* profile = NULL; initCache(status); if(U_FAILURE(*status)){ return NULL; } UStringPrepKey stackKey; /* * const is cast way to save malloc, strcpy and free calls * we use the passed in pointers for fetching the data from the * hash table which is safe */ stackKey.name = (char*) name; stackKey.path = (char*) path; /* fetch the data from the cache */ umtx_lock(usprepMutex()); profile = (UStringPrepProfile*) (uhash_get(SHARED_DATA_HASHTABLE,&stackKey)); if(profile != NULL) { profile->refCount++; } umtx_unlock(usprepMutex()); if(profile == NULL) { /* else load the data and put the data in the cache */ LocalMemory<UStringPrepProfile> newProfile; if(newProfile.allocateInsteadAndReset() == NULL) { *status = U_MEMORY_ALLOCATION_ERROR; return NULL; } /* load the data */ if(!loadData(newProfile.getAlias(), path, name, _SPREP_DATA_TYPE, status) || U_FAILURE(*status) ){ return NULL; } /* get the options */ newProfile->doNFKC = (UBool)((newProfile->indexes[_SPREP_OPTIONS] & _SPREP_NORMALIZATION_ON) > 0); newProfile->checkBiDi = (UBool)((newProfile->indexes[_SPREP_OPTIONS] & _SPREP_CHECK_BIDI_ON) > 0); LocalMemory<UStringPrepKey> key; LocalMemory<char> keyName; LocalMemory<char> keyPath; if( key.allocateInsteadAndReset() == NULL || keyName.allocateInsteadAndCopy(static_cast<int32_t>(uprv_strlen(name)+1)) == NULL || (path != NULL && keyPath.allocateInsteadAndCopy(static_cast<int32_t>(uprv_strlen(path)+1)) == NULL) ) { *status = U_MEMORY_ALLOCATION_ERROR; usprep_unload(newProfile.getAlias()); return NULL; } umtx_lock(usprepMutex()); // 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()); } return profile; }