void Loader::Host::didFail(SubresourceLoader* loader, bool cancelled) { loader->clearClient(); RequestMap::iterator i = m_requestsLoading.find(loader); if (i == m_requestsLoading.end()) return; Request* request = i->second; m_requestsLoading.remove(i); DocLoader* docLoader = request->docLoader(); if (!request->isMultipart()) docLoader->decrementRequestCount(); CachedResource* resource = request->cachedResource(); if (!cancelled) { docLoader->setLoadInProgress(true); resource->error(); } docLoader->setLoadInProgress(false); if (cancelled || !resource->isPreloaded()) cache()->remove(resource); delete request; servePendingRequests(); }
void Loader::Host::didFail(SubresourceLoader* loader, bool cancelled) { RefPtr<Host> myProtector(this); loader->clearClient(); RequestMap::iterator i = m_requestsLoading.find(loader); if (i == m_requestsLoading.end()) return; Request* request = i->second; m_requestsLoading.remove(i); DocLoader* docLoader = request->docLoader(); // Prevent the document from being destroyed before we are done with // the docLoader that it will delete when the document gets deleted. RefPtr<Document> protector(docLoader->doc()); if (!request->isMultipart()) docLoader->decrementRequestCount(); CachedResource* resource = request->cachedResource(); if (resource->resourceToRevalidate()) cache()->revalidationFailed(resource); if (!cancelled) { docLoader->setLoadInProgress(true); resource->error(); } docLoader->setLoadInProgress(false); if (cancelled || !resource->isPreloaded()) cache()->remove(resource); delete request; docLoader->checkForPendingPreloads(); servePendingRequests(); }
void DocLoader::checkForReload(const KURL& fullURL) { if (m_allowStaleResources) return; // Don't reload resources while pasting if (fullURL.isEmpty()) return; if (m_reloadedURLs.contains(fullURL.string())) return; CachedResource* existing = cache()->resourceForURL(fullURL.string()); if (!existing || existing->isPreloaded()) return; switch (cachePolicy()) { case CachePolicyVerify: if (!existing->mustRevalidate(CachePolicyVerify)) return; cache()->revalidateResource(existing, this); break; case CachePolicyCache: if (!existing->mustRevalidate(CachePolicyCache)) return; cache()->revalidateResource(existing, this); break; case CachePolicyReload: cache()->remove(existing); break; case CachePolicyRevalidate: cache()->revalidateResource(existing, this); break; default: ASSERT_NOT_REACHED(); } m_reloadedURLs.add(fullURL.string()); }
void MemoryCache::pruneDeadResourcesToSize(unsigned targetSize) { if (m_inPruneResources) return; TemporaryChange<bool> reentrancyProtector(m_inPruneResources, true); int size = m_allResources.size(); // See if we have any purged resources we can evict. for (int i = 0; i < size; i++) { CachedResource* current = m_allResources[i].m_tail; while (current) { CachedResource* prev = current->m_prevInAllResourcesList; if (current->wasPurged()) { ASSERT(!current->hasClients()); ASSERT(!current->isPreloaded()); evict(current); } current = prev; } } if (targetSize && m_deadSize <= targetSize) return; bool canShrinkLRULists = true; for (int i = size - 1; i >= 0; i--) { // Remove from the tail, since this is the least frequently accessed of the objects. CachedResource* current = m_allResources[i].m_tail; // First flush all the decoded data in this queue. while (current) { // Protect 'previous' so it can't get deleted during destroyDecodedData(). CachedResourceHandle<CachedResource> previous = current->m_prevInAllResourcesList; ASSERT(!previous || previous->inCache()); if (!current->hasClients() && !current->isPreloaded() && current->isLoaded()) { // Destroy our decoded data. This will remove us from // m_liveDecodedResources, and possibly move us to a different // LRU list in m_allResources. current->destroyDecodedData(); if (targetSize && m_deadSize <= targetSize) return; } // Decoded data may reference other resources. Stop iterating if 'previous' somehow got // kicked out of cache during destroyDecodedData(). if (previous && !previous->inCache()) break; current = previous.get(); } // Now evict objects from this queue. current = m_allResources[i].m_tail; while (current) { CachedResourceHandle<CachedResource> previous = current->m_prevInAllResourcesList; ASSERT(!previous || previous->inCache()); if (!current->hasClients() && !current->isPreloaded() && !current->isCacheValidator()) { if (!makeResourcePurgeable(current)) evict(current); if (targetSize && m_deadSize <= targetSize) return; } if (previous && !previous->inCache()) break; current = previous.get(); } // Shrink the vector back down so we don't waste time inspecting // empty LRU lists on future prunes. if (m_allResources[i].m_head) canShrinkLRULists = false; else if (canShrinkLRULists) m_allResources.resize(i); } }