CachedResource* CachedResourceLoader::loadResource(CachedResource::Type type, ResourceRequest& request, const String& charset, ResourceLoadPriority priority) { ASSERT(!memoryCache()->resourceForURL(request.url())); LOG(ResourceLoading, "Loading CachedResource for '%s'.", request.url().string().latin1().data()); CachedResource* resource = createResource(type, request, charset); bool inCache = memoryCache()->add(resource); // Pretend the resource is in the cache, to prevent it from being deleted during the load() call. // FIXME: CachedResource should just use normal refcounting instead. if (!inCache) resource->setInCache(true); resource->setLoadPriority(priority); resource->load(this); if (!inCache) { resource->setOwningCachedResourceLoader(this); resource->setInCache(false); } // We don't support immediate loads, but we do support immediate failure. if (resource->errorOccurred()) { if (inCache) memoryCache()->remove(resource); else delete resource; return 0; } m_validatedURLs.add(request.url()); return resource; }
void MemoryCache::remove(CachedResource& resource) { ASSERT(WTF::isMainThread()); LOG(ResourceLoading, "Evicting resource %p for '%s' from cache", &resource, resource.url().string().latin1().data()); // The resource may have already been removed by someone other than our caller, // who needed a fresh copy for a reload. See <http://bugs.webkit.org/show_bug.cgi?id=12479#c6>. if (auto* resources = sessionResourceMap(resource.sessionID())) { #if ENABLE(CACHE_PARTITIONING) auto key = std::make_pair(resource.url(), resource.cachePartition()); #else auto& key = resource.url(); #endif if (resource.inCache()) { // Remove resource from the resource map. resources->remove(key); resource.setInCache(false); // If the resource map is now empty, remove it from m_sessionResources. if (resources->isEmpty()) m_sessionResources.remove(resource.sessionID()); // Remove from the appropriate LRU list. removeFromLRUList(resource); removeFromLiveDecodedResourcesList(resource); adjustSize(resource.hasClients(), -static_cast<int>(resource.size())); } else ASSERT(resources->get(key) != &resource); } resource.deleteIfPossible(); }
void MemoryCache::revalidationSucceeded(CachedResource* revalidatingResource, const ResourceResponse& response) { CachedResource* resource = revalidatingResource->resourceToRevalidate(); ASSERT(resource); ASSERT(!resource->inCache()); ASSERT(resource->isLoaded()); ASSERT(revalidatingResource->inCache()); // Calling evict() can potentially delete revalidatingResource, which we use // below. This mustn't be the case since revalidation means it is loaded // and so canDelete() is false. ASSERT(!revalidatingResource->canDelete()); evict(revalidatingResource); CachedResourceMap& resources = getSessionMap(resource->sessionID()); #if ENABLE(CACHE_PARTITIONING) ASSERT(!resources.get(resource->url()) || !resources.get(resource->url())->get(resource->cachePartition())); CachedResourceItem* originMap = resources.get(resource->url()); if (!originMap) { originMap = new CachedResourceItem; resources.set(resource->url(), adoptPtr(originMap)); } originMap->set(resource->cachePartition(), resource); #else ASSERT(!resources.get(resource->url())); resources.set(resource->url(), resource); #endif resource->setInCache(true); resource->updateResponseAfterRevalidation(response); insertInLRUList(resource); int delta = resource->size(); if (resource->decodedSize() && resource->hasClients()) insertInLiveDecodedResourcesList(resource); if (delta) adjustSize(resource->hasClients(), delta); revalidatingResource->switchClientsToRevalidatedResource(); ASSERT(!revalidatingResource->m_deleted); // this deletes the revalidating resource revalidatingResource->clearResourceToRevalidate(); }
bool MemoryCache::add(CachedResource& resource) { if (disabled()) return false; ASSERT(WTF::isMainThread()); #if ENABLE(CACHE_PARTITIONING) auto key = std::make_pair(resource.url(), resource.cachePartition()); #else auto& key = resource.url(); #endif ensureSessionResourceMap(resource.sessionID()).set(key, &resource); resource.setInCache(true); resourceAccessed(resource); LOG(ResourceLoading, "MemoryCache::add Added '%s', resource %p\n", resource.url().string().latin1().data(), &resource); return true; }