// Store a value and error in given hash entry. // On entry, gCacheMutex must be held. Hash entry element must be in progress. // value must be non NULL. // On Exit, soft reference added to value. value and status stored in hash // entry. Soft reference removed from previous stored value. Waiting // threads notified. void UnifiedCache::_put( const UHashElement *element, const SharedObject *value, const UErrorCode status) const { U_ASSERT(_inProgress(element)); const CacheKeyBase *theKey = (const CacheKeyBase *) element->key.pointer; const SharedObject *oldValue = (const SharedObject *) element->value.pointer; theKey->fCreationStatus = status; if (value->noSoftReferences()) { _registerMaster(theKey, value); } value->addSoftRef(); UHashElement *ptr = const_cast<UHashElement *>(element); ptr->value.pointer = (void *) value; oldValue->removeSoftRef(); // Tell waiting threads that we replace in-progress status with // an error. umtx_condBroadcast(&gInProgressValueAddedCond); }
// Places a new value and creationStatus in the cache for the given key. // On entry, gCacheMutex must be held. key must not exist in the cache. // On exit, value and creation status placed under key. Soft reference added // to value on successful add. On error sets status. void UnifiedCache::_putNew( const CacheKeyBase &key, const SharedObject *value, const UErrorCode creationStatus, UErrorCode &status) const { if (U_FAILURE(status)) { return; } CacheKeyBase *keyToAdopt = key.clone(); if (keyToAdopt == NULL) { status = U_MEMORY_ALLOCATION_ERROR; return; } keyToAdopt->fCreationStatus = creationStatus; if (value->noSoftReferences()) { _registerMaster(keyToAdopt, value); } uhash_put(fHashtable, keyToAdopt, (void *) value, &status); if (U_SUCCESS(status)) { value->addSoftRef(); } }
void UnifiedCache::_putNew( const CacheKeyBase &key, const SharedObject *value, const UErrorCode creationStatus, UErrorCode &status) const { if (U_FAILURE(status)) { return; } CacheKeyBase *keyToAdopt = key.clone(); if (keyToAdopt == NULL) { status = U_MEMORY_ALLOCATION_ERROR; return; } keyToAdopt->fCreationStatus = creationStatus; if (value->softRefCount == 0) { _registerMaster(keyToAdopt, value); } void *oldValue = uhash_put(fHashtable, keyToAdopt, (void *) value, &status); U_ASSERT(oldValue == nullptr); (void)oldValue; if (U_SUCCESS(status)) { value->softRefCount++; } }