void ResourceLoadScheduler::servePendingRequests(ResourceLoadPriority minimumPriority) { LOG(ResourceLoading, "ResourceLoadScheduler::servePendingRequests. m_suspendPendingRequestsCount=%d", m_suspendPendingRequestsCount); if (isSuspendingPendingRequests()) return; m_requestTimer.stop(); servePendingRequests(m_nonHTTPProtocolHost, minimumPriority); Vector<HostInformation*> hostsToServe; m_hosts.checkConsistency(); HostMap::iterator end = m_hosts.end(); for (HostMap::iterator iter = m_hosts.begin(); iter != end; ++iter) hostsToServe.append(iter->value); int size = hostsToServe.size(); for (int i = 0; i < size; ++i) { HostInformation* host = hostsToServe[i]; if (host->hasRequests()) servePendingRequests(host, minimumPriority); else delete m_hosts.take(host->name()); } }
void ResourceLoadScheduler::scheduleLoad(ResourceLoader* resourceLoader, ResourceLoadPriority priority) { ASSERT(resourceLoader); ASSERT(priority != ResourceLoadPriorityUnresolved); LOG(ResourceLoading, "ResourceLoadScheduler::load resource %p '%s'", resourceLoader, resourceLoader->url().string().latin1().data()); #if PLATFORM(IOS) // If there's a web archive resource for this URL, we don't need to schedule the load since it will never touch the network. if (!isSuspendingPendingRequests() && resourceLoader->documentLoader()->archiveResourceForURL(resourceLoader->iOSOriginalRequest().url())) { resourceLoader->startLoading(); return; } #else if (resourceLoader->documentLoader()->archiveResourceForURL(resourceLoader->request().url())) { resourceLoader->start(); return; } #endif #if PLATFORM(IOS) HostInformation* host = hostForURL(resourceLoader->iOSOriginalRequest().url(), CreateIfNotFound); #else HostInformation* host = hostForURL(resourceLoader->url(), CreateIfNotFound); #endif bool hadRequests = host->hasRequests(); host->schedule(resourceLoader, priority); #if PLATFORM(COCOA) || USE(CFNETWORK) if (!isSuspendingPendingRequests()) { // Serve all requests at once to keep the pipeline full at the network layer. // FIXME: Does this code do anything useful, given that we also set maxRequestsInFlightPerHost to effectively unlimited on these platforms? servePendingRequests(host, ResourceLoadPriorityVeryLow); return; } #endif #if PLATFORM(IOS) if ((priority > ResourceLoadPriorityLow || !resourceLoader->iOSOriginalRequest().url().protocolIsInHTTPFamily() || (priority == ResourceLoadPriorityLow && !hadRequests)) && !isSuspendingPendingRequests()) { // Try to request important resources immediately. servePendingRequests(host, priority); return; } #else if (priority > ResourceLoadPriorityLow || !resourceLoader->url().protocolIsInHTTPFamily() || (priority == ResourceLoadPriorityLow && !hadRequests)) { // Try to request important resources immediately. servePendingRequests(host, priority); return; } #endif notifyDidScheduleResourceRequest(resourceLoader); // Handle asynchronously so early low priority requests don't // get scheduled before later high priority ones. scheduleServePendingRequests(); }
void ResourceLoadScheduler::scheduleLoad(ResourceLoader* resourceLoader, ResourceLoadPriority priority) { ASSERT(resourceLoader); ASSERT(priority != ResourceLoadPriorityUnresolved); #if !REQUEST_MANAGEMENT_ENABLED priority = ResourceLoadPriorityHighest; #endif LOG(ResourceLoading, "ResourceLoadScheduler::load resource %p '%s'", resourceLoader, resourceLoader->url().string().latin1().data()); // If there's a web archive resource for this URL, we don't need to schedule the load since it will never touch the network. if (resourceLoader->documentLoader()->archiveResourceForURL(resourceLoader->request().url())) { resourceLoader->start(); return; } HostInformation* host = hostForURL(resourceLoader->url(), CreateIfNotFound); bool hadRequests = host->hasRequests(); host->schedule(resourceLoader, priority); if (priority > ResourceLoadPriorityLow || !resourceLoader->url().protocolIsInHTTPFamily() || (priority == ResourceLoadPriorityLow && !hadRequests)) { // Try to request important resources immediately. servePendingRequests(host, priority); return; } notifyDidScheduleResourceRequest(resourceLoader); // Handle asynchronously so early low priority requests don't // get scheduled before later high priority ones. scheduleServePendingRequests(); }
void Loader::didFail(SubresourceLoader* loader, bool cancelled) { RequestMap::iterator i = m_requestsLoading.find(loader); if (i == m_requestsLoading.end()) return; Request* req = i->second; m_requestsLoading.remove(i); DocLoader* docLoader = req->docLoader(); if (!req->isMultipart()) docLoader->decrementRequestCount(); CachedResource* object = req->cachedResource(); if (!cancelled) { docLoader->setLoadInProgress(true); object->error(); } docLoader->setLoadInProgress(false); cache()->remove(object); delete req; servePendingRequests(); }
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::didFinishLoading(SubresourceLoader* loader) { 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 we got a 4xx response, we're pretending to have received a network // error, so we can't send the successful data() and finish() callbacks. if (!resource->errorOccurred()) { docLoader->setLoadInProgress(true); resource->data(loader->resourceData(), true); resource->finish(); } delete request; docLoader->setLoadInProgress(false); #if REQUEST_DEBUG KURL u(resource->url()); printf("HOST %s COUNT %d RECEIVED %s\n", u.host().latin1().data(), m_requestsLoading.size(), resource->url().latin1().data()); #endif servePendingRequests(); }
void Loader::Host::didReceiveResponse(SubresourceLoader* loader, const ResourceResponse& response) { Request* request = m_requestsLoading.get(loader); // FIXME: This is a workaround for <rdar://problem/5236843> // If a load starts while the frame is still in the provisional state // (this can be the case when loading the user style sheet), committing the load then causes all // requests to be removed from the m_requestsLoading map. This means that request might be null here. // In that case we just return early. // ASSERT(request); if (!request) return; CachedResource* resource = request->cachedResource(); if (resource->isCacheValidator()) { if (response.httpStatusCode() == 304) { // 304 Not modified / Use local copy m_requestsLoading.remove(loader); loader->clearClient(); request->docLoader()->decrementRequestCount(); // Existing resource is ok, just use it updating the expiration time. cache()->revalidationSucceeded(resource, response); if (request->docLoader()->frame()) request->docLoader()->frame()->loader()->checkCompleted(); delete request; servePendingRequests(); return; } // Did not get 304 response, continue as a regular resource load. cache()->revalidationFailed(resource); } resource->setResponse(response); String encoding = response.textEncodingName(); if (!encoding.isNull()) resource->setEncoding(encoding); if (request->isMultipart()) { ASSERT(resource->isImage()); static_cast<CachedImage*>(resource)->clear(); if (request->docLoader()->frame()) request->docLoader()->frame()->loader()->checkCompleted(); } else if (response.isMultipart()) { request->setIsMultipart(true); // We don't count multiParts in a DocLoader's request count request->docLoader()->decrementRequestCount(); // If we get a multipart response, we must have a handle ASSERT(loader->handle()); if (!resource->isImage()) loader->handle()->cancel(); } }
void Loader::load(DocLoader* dl, CachedResource* object, bool incremental, bool skipCanLoadCheck, bool sendResourceLoadCallbacks) { ASSERT(dl); Request* req = new Request(dl, object, incremental, skipCanLoadCheck, sendResourceLoadCallbacks); m_requestsPending.append(req); dl->incrementRequestCount(); servePendingRequests(); }
void Loader::Host::servePendingRequests(Loader::Priority minimumPriority) { if (cache()->loader()->isSuspendingPendingRequests()) return; bool serveMore = true; for (int priority = High; priority >= minimumPriority && serveMore; --priority) servePendingRequests(m_requestsPending[priority], serveMore); }
void ResourceLoadScheduler::servePendingRequests(ResourceLoadPriority minimumPriority) { LOG(ResourceLoading, "ResourceLoadScheduler::servePendingRequests. m_suspendPendingRequestsCount=%d", m_suspendPendingRequestsCount); if (isSuspendingPendingRequests()) return; m_requestTimer.stop(); servePendingRequests(m_nonHTTPProtocolHost, minimumPriority); Vector<HostInformation*> hostsToServe; copyValuesToVector(m_hosts, hostsToServe); for (auto* host : hostsToServe) { if (host->hasRequests()) servePendingRequests(host, minimumPriority); else delete m_hosts.take(host->name()); } }
void Loader::Host::didFinishLoading(SubresourceLoader* loader) { RefPtr<Host> myProtector(this); 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(); ASSERT(!resource->resourceToRevalidate()); // If we got a 4xx response, we're pretending to have received a network // error, so we can't send the successful data() and finish() callbacks. if (!resource->errorOccurred()) { docLoader->setLoadInProgress(true); resource->data(loader->resourceData(), true); resource->finish(); } delete request; docLoader->setLoadInProgress(false); docLoader->checkForPendingPreloads(); #if REQUEST_DEBUG KURL u(ParsedURLString, resource->url()); printf("HOST %s COUNT %d RECEIVED %s\n", u.host().latin1().data(), m_requestsLoading.size(), resource->url().latin1().data()); #endif 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 Loader::didFinishLoading(SubresourceLoader* loader) { RequestMap::iterator i = m_requestsLoading.find(loader); if (i == m_requestsLoading.end()) return; Request* req = i->second; m_requestsLoading.remove(i); DocLoader* docLoader = req->docLoader(); if (!req->isMultipart()) docLoader->decrementRequestCount(); CachedResource* object = req->cachedResource(); docLoader->setLoadInProgress(true); object->data(loader->resourceData(), true); docLoader->setLoadInProgress(false); object->finish(); delete req; servePendingRequests(); }
void ResourceLoadScheduler::scheduleLoad(ResourceLoader* resourceLoader, ResourceLoadPriority priority) { ASSERT(resourceLoader); ASSERT(priority != ResourceLoadPriorityUnresolved); #if !REQUEST_MANAGEMENT_ENABLED priority = ResourceLoadPriorityHighest; #endif LOG(ResourceLoading, "ResourceLoadScheduler::load resource %p '%s'", resourceLoader, resourceLoader->url().string().latin1().data()); HostInformation* host = hostForURL(resourceLoader->url(), CreateIfNotFound); bool hadRequests = host->hasRequests(); host->schedule(resourceLoader, priority); if (priority > ResourceLoadPriorityLow || !resourceLoader->url().protocolInHTTPFamily() || (priority == ResourceLoadPriorityLow && !hadRequests)) { // Try to request important resources immediately. servePendingRequests(host, priority); return; } // Handle asynchronously so early low priority requests don't get scheduled before later high priority ones. InspectorInstrumentation::didScheduleResourceRequest(resourceLoader->frameLoader() ? resourceLoader->frameLoader()->frame()->document() : 0, resourceLoader->url()); scheduleServePendingRequests(); }
void NetworkResourceLoadScheduler::requestTimerFired(WebCore::Timer<NetworkResourceLoadScheduler>*) { servePendingRequests(); }
void Loader::requestTimerFired(Timer<Loader>*) { servePendingRequests(); }
void ResourceLoadScheduler::requestTimerFired(Timer<ResourceLoadScheduler>*) { LOG(ResourceLoading, "ResourceLoadScheduler::requestTimerFired\n"); servePendingRequests(); }
void Loader::Host::servePendingRequests(Loader::Priority minimumPriority) { for (int priority = High; priority >= minimumPriority; --priority) servePendingRequests(m_requestsPending[priority]); }
void Loader::Host::servePendingRequests(Loader::Priority minimumPriority) { bool serveMore = true; for (int priority = High; priority >= minimumPriority && serveMore; --priority) servePendingRequests(m_requestsPending[priority], serveMore); }