already_AddRefed<CacheEntryHandle> CacheEntry::ReopenTruncated(bool aMemoryOnly, nsICacheEntryOpenCallback* aCallback) { LOG(("CacheEntry::ReopenTruncated [this=%p]", this)); mLock.AssertCurrentThreadOwns(); // Hold callbacks invocation, AddStorageEntry would invoke from doom prematurly mPreventCallbacks = true; nsRefPtr<CacheEntryHandle> handle; nsRefPtr<CacheEntry> newEntry; { mozilla::MutexAutoUnlock unlock(mLock); // The following call dooms this entry (calls DoomAlreadyRemoved on us) nsresult rv = CacheStorageService::Self()->AddStorageEntry( GetStorageID(), GetURI(), GetEnhanceID(), mUseDisk && !aMemoryOnly, true, // always create true, // truncate existing (this one) getter_AddRefs(handle)); if (NS_SUCCEEDED(rv)) { newEntry = handle->Entry(); LOG((" exchanged entry %p by entry %p, rv=0x%08x", this, newEntry.get(), rv)); newEntry->AsyncOpen(aCallback, nsICacheStorage::OPEN_TRUNCATE); } else { LOG((" exchanged of entry %p failed, rv=0x%08x", this, rv)); AsyncDoom(nullptr); } } mPreventCallbacks = false; if (!newEntry) return nullptr; newEntry->TransferCallbacks(*this); mCallbacks.Clear(); // Must return a new write handle, since the consumer is expected to // write to this newly recreated entry. The |handle| is only a common // reference counter and doesn't revert entry state back when write // fails and also doesn't update the entry frecency. Not updating // frecency causes entries to not be purged from our memory pools. nsRefPtr<CacheEntryHandle> writeHandle = newEntry->NewWriteHandle(); return writeHandle.forget(); }
already_AddRefed<CacheEntryHandle> CacheEntry::ReopenTruncated(bool aMemoryOnly, nsICacheEntryOpenCallback* aCallback) { LOG(("CacheEntry::ReopenTruncated [this=%p]", this)); mLock.AssertCurrentThreadOwns(); // Hold callbacks invocation, AddStorageEntry would invoke from doom prematurly mPreventCallbacks = true; nsRefPtr<CacheEntryHandle> handle; nsRefPtr<CacheEntry> newEntry; { mozilla::MutexAutoUnlock unlock(mLock); // The following call dooms this entry (calls DoomAlreadyRemoved on us) nsresult rv = CacheStorageService::Self()->AddStorageEntry( GetStorageID(), GetURI(), GetEnhanceID(), mUseDisk && !aMemoryOnly, true, // always create true, // truncate existing (this one) getter_AddRefs(handle)); LOG((" exchanged entry %p by entry %p, rv=0x%08x", this, newEntry.get(), rv)); if (NS_SUCCEEDED(rv)) { newEntry = handle->Entry(); newEntry->AsyncOpen(aCallback, nsICacheStorage::OPEN_TRUNCATE); } else { AsyncDoom(nullptr); } } mPreventCallbacks = false; if (!newEntry) return nullptr; newEntry->TransferCallbacks(*this); mCallbacks.Clear(); return handle.forget(); }