void *nsHashtable::Remove(nsHashKey *aKey) { if (!mHashtable.ops) return nsnull; if (mLock) PR_Lock(mLock); // shouldn't be adding an item during enumeration PR_ASSERT(!mEnumerating); // need to see if the entry is actually there, in order to get the // old value for the result HTEntry* entry = static_cast<HTEntry*> (PL_DHashTableOperate(&mHashtable, aKey, PL_DHASH_LOOKUP)); void *res; if (PL_DHASH_ENTRY_IS_FREE(entry)) { // value wasn't in the table anyway res = nsnull; } else { res = entry->value; PL_DHashTableRawRemove(&mHashtable, entry); } if (mLock) PR_Unlock(mLock); return res; }
nsresult nsPropertyTable::TransferOrDeleteAllPropertiesFor(nsPropertyOwner aObject, nsPropertyTable *aOtherTable) { nsresult rv = NS_OK; for (PropertyList* prop = mPropertyList; prop; prop = prop->mNext) { if (prop->mTransfer) { PropertyListMapEntry *entry = static_cast<PropertyListMapEntry*> (PL_DHashTableOperate(&prop->mObjectValueMap, aObject, PL_DHASH_LOOKUP)); if (PL_DHASH_ENTRY_IS_BUSY(entry)) { rv = aOtherTable->SetProperty(aObject, prop->mName, entry->value, prop->mDtorFunc, prop->mDtorData, prop->mTransfer); if (NS_FAILED(rv)) { DeleteAllPropertiesFor(aObject); aOtherTable->DeleteAllPropertiesFor(aObject); break; } PL_DHashTableRawRemove(&prop->mObjectValueMap, entry); } } else { prop->DeletePropertyFor(aObject); } } return rv; }
void* nsPropertyTable::GetPropertyInternal(nsPropertyOwner aObject, nsIAtom *aPropertyName, bool aRemove, nsresult *aResult) { NS_PRECONDITION(aPropertyName && aObject, "unexpected null param"); nsresult rv = NS_PROPTABLE_PROP_NOT_THERE; void *propValue = nullptr; PropertyList* propertyList = GetPropertyListFor(aPropertyName); if (propertyList) { PropertyListMapEntry *entry = static_cast<PropertyListMapEntry*> (PL_DHashTableOperate(&propertyList->mObjectValueMap, aObject, PL_DHASH_LOOKUP)); if (PL_DHASH_ENTRY_IS_BUSY(entry)) { propValue = entry->value; if (aRemove) { // don't call propertyList->mDtorFunc. That's the caller's job now. PL_DHashTableRawRemove(&propertyList->mObjectValueMap, entry); } rv = NS_OK; } } if (aResult) *aResult = rv; return propValue; }
bool nsPropertyTable::PropertyList::DeletePropertyFor(nsPropertyOwner aObject) { PropertyListMapEntry *entry = static_cast<PropertyListMapEntry*> (PL_DHashTableOperate(&mObjectValueMap, aObject, PL_DHASH_LOOKUP)); if (!PL_DHASH_ENTRY_IS_BUSY(entry)) return false; void* value = entry->value; PL_DHashTableRawRemove(&mObjectValueMap, entry); if (mDtorFunc) mDtorFunc(const_cast<void*>(aObject.get()), mName, value, mDtorData); return true; }
already_AddRefed<nsContentList> NS_GetContentList(nsINode* aRootNode, nsIAtom* aMatchAtom, PRInt32 aMatchNameSpaceId) { NS_ASSERTION(aRootNode, "content list has to have a root"); nsContentList* list = nsnull; static PLDHashTableOps hash_table_ops = { PL_DHashAllocTable, PL_DHashFreeTable, ContentListHashtableHashKey, ContentListHashtableMatchEntry, PL_DHashMoveEntryStub, PL_DHashClearEntryStub, PL_DHashFinalizeStub }; // Initialize the hashtable if needed. if (!gContentListHashTable.ops) { PRBool success = PL_DHashTableInit(&gContentListHashTable, &hash_table_ops, nsnull, sizeof(ContentListHashEntry), 16); if (!success) { gContentListHashTable.ops = nsnull; } } ContentListHashEntry *entry = nsnull; // First we look in our hashtable. Then we create a content list if needed if (gContentListHashTable.ops) { nsContentListKey hashKey(aRootNode, aMatchAtom, aMatchNameSpaceId); // A PL_DHASH_ADD is equivalent to a PL_DHASH_LOOKUP for cases // when the entry is already in the hashtable. entry = static_cast<ContentListHashEntry *> (PL_DHashTableOperate(&gContentListHashTable, &hashKey, PL_DHASH_ADD)); if (entry) list = entry->mContentList; } if (!list) { // We need to create a ContentList and add it to our new entry, if // we have an entry list = new nsContentList(aRootNode, aMatchAtom, aMatchNameSpaceId); if (entry) { if (list) entry->mContentList = list; else PL_DHashTableRawRemove(&gContentListHashTable, entry); } NS_ENSURE_TRUE(list, nsnull); } NS_ADDREF(list); // Hold on to the last requested content list to avoid having it be // removed from the cache immediately when it's released. Avoid // bumping the refcount on the list if the requested list is the one // that's already cached. if (gCachedContentList != list) { NS_IF_RELEASE(gCachedContentList); gCachedContentList = list; NS_ADDREF(gCachedContentList); } return list; }
NS_IMETHODIMP nsLoadGroup::RemoveRequest(nsIRequest *request, nsISupports* ctxt, nsresult aStatus) { NS_ENSURE_ARG_POINTER(request); nsresult rv; #if defined(PR_LOGGING) { nsCAutoString nameStr; request->GetName(nameStr); LOG(("LOADGROUP [%x]: Removing request %x %s status %x (count=%d).\n", this, request, nameStr.get(), aStatus, mRequests.entryCount-1)); } #endif // Make sure we have a owning reference to the request we're about // to remove. nsCOMPtr<nsIRequest> kungFuDeathGrip(request); // // Remove the request from the group. If this fails, it means that // the request was *not* in the group so do not update the foreground // count or it will get messed up... // RequestMapEntry *entry = static_cast<RequestMapEntry *> (PL_DHashTableOperate(&mRequests, request, PL_DHASH_LOOKUP)); if (PL_DHASH_ENTRY_IS_FREE(entry)) { LOG(("LOADGROUP [%x]: Unable to remove request %x. Not in group!\n", this, request)); return NS_ERROR_FAILURE; } PL_DHashTableRawRemove(&mRequests, entry); // Undo any group priority delta... if (mPriority != 0) RescheduleRequest(request, -mPriority); nsLoadFlags flags; rv = request->GetLoadFlags(&flags); if (NS_FAILED(rv)) return rv; if (!(flags & nsIRequest::LOAD_BACKGROUND)) { NS_ASSERTION(mForegroundCount > 0, "ForegroundCount messed up"); mForegroundCount -= 1; // Fire the OnStopRequest out to the observer... nsCOMPtr<nsIRequestObserver> observer = do_QueryReferent(mObserver); if (observer) { LOG(("LOADGROUP [%x]: Firing OnStopRequest for request %x." "(foreground count=%d).\n", this, request, mForegroundCount)); rv = observer->OnStopRequest(request, ctxt, aStatus); #if defined(PR_LOGGING) if (NS_FAILED(rv)) { LOG(("LOADGROUP [%x]: OnStopRequest for request %x FAILED.\n", this, request)); } #endif } // If that was the last request -> remove ourselves from loadgroup if (mForegroundCount == 0 && mLoadGroup) { mLoadGroup->RemoveRequest(this, nsnull, aStatus); } } return rv; }