16b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner/* 26b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner Copyright (C) 1998 Lars Knoll (knoll@mpi-hd.mpg.de) 36b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner Copyright (C) 2001 Dirk Mueller (mueller@kde.org) 46b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner Copyright (C) 2002 Waldo Bastian (bastian@kde.org) 56b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com) 66b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. 76b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner Copyright (C) 2010 Google Inc. All rights reserved. 86b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 96b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner This library is free software; you can redistribute it and/or 106b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner modify it under the terms of the GNU Library General Public 116b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner License as published by the Free Software Foundation; either 126b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner version 2 of the License, or (at your option) any later version. 136b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 146b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner This library is distributed in the hope that it will be useful, 156b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner but WITHOUT ANY WARRANTY; without even the implied warranty of 166b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 176b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner Library General Public License for more details. 186b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 196b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner You should have received a copy of the GNU Library General Public License 206b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner along with this library; see the file COPYING.LIB. If not, write to 216b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 226b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner Boston, MA 02110-1301, USA. 236b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner */ 246b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 256b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner#include "config.h" 266b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner#include "ResourceLoadScheduler.h" 276b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 286b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner#include "Document.h" 296b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner#include "Frame.h" 306b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner#include "FrameLoader.h" 316b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner#include "InspectorInstrumentation.h" 326b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner#include "KURL.h" 336b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner#include "Logging.h" 346b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner#include "NetscapePlugInStreamLoader.h" 356b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner#include "ResourceLoader.h" 366b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner#include "ResourceRequest.h" 376b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner#include "SubresourceLoader.h" 389f8811ec084be6ba9380c41abf6e2a080b6d9b91Russell Brenner#include <wtf/text/CString.h> 396b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 406b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner#define REQUEST_MANAGEMENT_ENABLED 1 416b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 426b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennernamespace WebCore { 436b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 446b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner#if REQUEST_MANAGEMENT_ENABLED 456b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennerstatic const unsigned maxRequestsInFlightForNonHTTPProtocols = 20; 466b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner// Match the parallel connection count used by the networking layer. 476b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennerstatic unsigned maxRequestsInFlightPerHost; 486b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner#else 496b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennerstatic const unsigned maxRequestsInFlightForNonHTTPProtocols = 10000; 506b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennerstatic const unsigned maxRequestsInFlightPerHost = 10000; 516b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner#endif 526b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 536b70adc33054f8aee8c54d0f460458a9df11b8a5Russell BrennerResourceLoadScheduler::HostInformation* ResourceLoadScheduler::hostForURL(const KURL& url, CreateHostPolicy createHostPolicy) 546b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner{ 556b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner if (!url.protocolInHTTPFamily()) 566b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner return m_nonHTTPProtocolHost; 576b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 586b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner m_hosts.checkConsistency(); 596b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner String hostName = url.host(); 606b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner HostInformation* host = m_hosts.get(hostName); 616b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner if (!host && createHostPolicy == CreateIfNotFound) { 626b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner host = new HostInformation(hostName, maxRequestsInFlightPerHost); 636b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner m_hosts.add(hostName, host); 646b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner } 656b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner return host; 666b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner} 676b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 686b70adc33054f8aee8c54d0f460458a9df11b8a5Russell BrennerResourceLoadScheduler* resourceLoadScheduler() 696b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner{ 706b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner ASSERT(isMainThread()); 716b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner DEFINE_STATIC_LOCAL(ResourceLoadScheduler, resourceLoadScheduler, ()); 726b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner return &resourceLoadScheduler; 736b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner} 746b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 756b70adc33054f8aee8c54d0f460458a9df11b8a5Russell BrennerResourceLoadScheduler::ResourceLoadScheduler() 766b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner : m_nonHTTPProtocolHost(new HostInformation(String(), maxRequestsInFlightForNonHTTPProtocols)) 776b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner , m_requestTimer(this, &ResourceLoadScheduler::requestTimerFired) 786b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner , m_isSuspendingPendingRequests(false) 79f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch , m_isSerialLoadingEnabled(false) 806b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner{ 816b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner#if REQUEST_MANAGEMENT_ENABLED 826b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner maxRequestsInFlightPerHost = initializeMaximumHTTPConnectionCountPerHost(); 836b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner#endif 846b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner} 856b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 862bde8e466a4451c7319e3a072d118917957d6554Steve BlockPassRefPtr<SubresourceLoader> ResourceLoadScheduler::scheduleSubresourceLoad(Frame* frame, SubresourceLoaderClient* client, const ResourceRequest& request, ResourceLoadPriority priority, SecurityCheckPolicy securityCheck, 8754cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block bool sendResourceLoadCallbacks, bool shouldContentSniff, const String& optionalOutgoingReferrer, bool shouldBufferData) 886b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner{ 8954cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block RefPtr<SubresourceLoader> loader = SubresourceLoader::create(frame, client, request, securityCheck, sendResourceLoadCallbacks, shouldContentSniff, optionalOutgoingReferrer, shouldBufferData); 906b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner if (loader) 916b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner scheduleLoad(loader.get(), priority); 922bde8e466a4451c7319e3a072d118917957d6554Steve Block return loader.release(); 936b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner} 942fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 956b70adc33054f8aee8c54d0f460458a9df11b8a5Russell BrennerPassRefPtr<NetscapePlugInStreamLoader> ResourceLoadScheduler::schedulePluginStreamLoad(Frame* frame, NetscapePlugInStreamLoaderClient* client, const ResourceRequest& request) 966b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner{ 976b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner PassRefPtr<NetscapePlugInStreamLoader> loader = NetscapePlugInStreamLoader::create(frame, client, request); 986b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner if (loader) 99f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch scheduleLoad(loader.get(), ResourceLoadPriorityLow); 1006b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner return loader; 1016b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner} 1026b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 1036b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennervoid ResourceLoadScheduler::addMainResourceLoad(ResourceLoader* resourceLoader) 1046b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner{ 1056b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner hostForURL(resourceLoader->url(), CreateIfNotFound)->addLoadInProgress(resourceLoader); 1066b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner} 1076b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 108f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochvoid ResourceLoadScheduler::scheduleLoad(ResourceLoader* resourceLoader, ResourceLoadPriority priority) 1096b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner{ 1106b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner ASSERT(resourceLoader); 111f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch ASSERT(priority != ResourceLoadPriorityUnresolved); 1126b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner#if !REQUEST_MANAGEMENT_ENABLED 113f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch priority = ResourceLoadPriorityHighest; 1146b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner#endif 1156b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 1166b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner LOG(ResourceLoading, "ResourceLoadScheduler::load resource %p '%s'", resourceLoader, resourceLoader->url().string().latin1().data()); 1176b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner HostInformation* host = hostForURL(resourceLoader->url(), CreateIfNotFound); 1186b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner bool hadRequests = host->hasRequests(); 1196b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner host->schedule(resourceLoader, priority); 1206b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 121f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (priority > ResourceLoadPriorityLow || !resourceLoader->url().protocolInHTTPFamily() || (priority == ResourceLoadPriorityLow && !hadRequests)) { 1226b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner // Try to request important resources immediately. 1236b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner servePendingRequests(host, priority); 1242fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return; 1256b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner } 1262fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1272fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // Handle asynchronously so early low priority requests don't get scheduled before later high priority ones. 1282fc2651226baac27029e38c9d6ef883fa32084dbSteve Block InspectorInstrumentation::didScheduleResourceRequest(resourceLoader->frameLoader() ? resourceLoader->frameLoader()->frame()->document() : 0, resourceLoader->url()); 1292fc2651226baac27029e38c9d6ef883fa32084dbSteve Block scheduleServePendingRequests(); 1306b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner} 1316b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 1326b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennervoid ResourceLoadScheduler::remove(ResourceLoader* resourceLoader) 1336b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner{ 1346b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner ASSERT(resourceLoader); 1356b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 1366b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner HostInformation* host = hostForURL(resourceLoader->url()); 1376b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner if (host) 1386b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner host->remove(resourceLoader); 1396b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner scheduleServePendingRequests(); 1406b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner} 1416b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 1426b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennervoid ResourceLoadScheduler::crossOriginRedirectReceived(ResourceLoader* resourceLoader, const KURL& redirectURL) 1436b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner{ 1446b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner HostInformation* oldHost = hostForURL(resourceLoader->url()); 1456b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner ASSERT(oldHost); 1466b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner HostInformation* newHost = hostForURL(redirectURL, CreateIfNotFound); 1476b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 1486b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner if (oldHost->name() == newHost->name()) 1496b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner return; 1506b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 1516b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner newHost->addLoadInProgress(resourceLoader); 1526b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner oldHost->remove(resourceLoader); 1536b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner} 1546b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 155f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochvoid ResourceLoadScheduler::servePendingRequests(ResourceLoadPriority minimumPriority) 1566b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner{ 1576b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner LOG(ResourceLoading, "ResourceLoadScheduler::servePendingRequests. m_isSuspendingPendingRequests=%d", m_isSuspendingPendingRequests); 1586b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner if (m_isSuspendingPendingRequests) 1596b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner return; 1606b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 1616b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner m_requestTimer.stop(); 1626b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 1636b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner servePendingRequests(m_nonHTTPProtocolHost, minimumPriority); 1646b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 1656b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner Vector<HostInformation*> hostsToServe; 1666b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner m_hosts.checkConsistency(); 1676b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner HostMap::iterator end = m_hosts.end(); 1686b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner for (HostMap::iterator iter = m_hosts.begin(); iter != end; ++iter) 1696b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner hostsToServe.append(iter->second); 1706b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 1716b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner int size = hostsToServe.size(); 1726b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner for (int i = 0; i < size; ++i) { 1736b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner HostInformation* host = hostsToServe[i]; 1746b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner if (host->hasRequests()) 1756b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner servePendingRequests(host, minimumPriority); 1766b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner else 1776b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner delete m_hosts.take(host->name()); 1786b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner } 1796b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner} 1806b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 181f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochvoid ResourceLoadScheduler::servePendingRequests(HostInformation* host, ResourceLoadPriority minimumPriority) 1826b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner{ 1836b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner LOG(ResourceLoading, "ResourceLoadScheduler::servePendingRequests HostInformation.m_name='%s'", host->name().latin1().data()); 1846b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 185f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch for (int priority = ResourceLoadPriorityHighest; priority >= minimumPriority; --priority) { 1862daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch HostInformation::RequestQueue& requestsPending = host->requestsPending(ResourceLoadPriority(priority)); 1876b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 1886b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner while (!requestsPending.isEmpty()) { 1896b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner RefPtr<ResourceLoader> resourceLoader = requestsPending.first(); 1906b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 1916b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner // For named hosts - which are only http(s) hosts - we should always enforce the connection limit. 1926b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner // For non-named hosts - everything but http(s) - we should only enforce the limit if the document isn't done parsing 1936b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner // and we don't know all stylesheets yet. 1946b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner Document* document = resourceLoader->frameLoader() ? resourceLoader->frameLoader()->frame()->document() : 0; 1956b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner bool shouldLimitRequests = !host->name().isNull() || (document && (document->parsing() || !document->haveStylesheetsLoaded())); 1962daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (shouldLimitRequests && host->limitRequests(ResourceLoadPriority(priority))) 1976b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner return; 1986b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 1996b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner requestsPending.removeFirst(); 2004576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang host->addLoadInProgress(resourceLoader.get()); 2014576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang resourceLoader->start(); 2026b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner } 2036b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner } 2046b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner} 2056b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 2066b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennervoid ResourceLoadScheduler::suspendPendingRequests() 2076b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner{ 2086b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner ASSERT(!m_isSuspendingPendingRequests); 2096b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner m_isSuspendingPendingRequests = true; 2106b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner} 2116b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 2126b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennervoid ResourceLoadScheduler::resumePendingRequests() 2136b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner{ 2146b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner ASSERT(m_isSuspendingPendingRequests); 2156b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner m_isSuspendingPendingRequests = false; 2166b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner if (!m_hosts.isEmpty() || m_nonHTTPProtocolHost->hasRequests()) 2176b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner scheduleServePendingRequests(); 2186b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner} 2196b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 2206b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennervoid ResourceLoadScheduler::scheduleServePendingRequests() 2216b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner{ 2226b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner LOG(ResourceLoading, "ResourceLoadScheduler::scheduleServePendingRequests, m_requestTimer.isActive()=%u", m_requestTimer.isActive()); 2236b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner if (!m_requestTimer.isActive()) 2246b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner m_requestTimer.startOneShot(0); 2256b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner} 2266b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 2276b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennervoid ResourceLoadScheduler::requestTimerFired(Timer<ResourceLoadScheduler>*) 2286b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner{ 2296b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner LOG(ResourceLoading, "ResourceLoadScheduler::requestTimerFired\n"); 2306b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner servePendingRequests(); 2316b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner} 2326b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 2336b70adc33054f8aee8c54d0f460458a9df11b8a5Russell BrennerResourceLoadScheduler::HostInformation::HostInformation(const String& name, unsigned maxRequestsInFlight) 2346b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner : m_name(name) 2356b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner , m_maxRequestsInFlight(maxRequestsInFlight) 2366b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner{ 2376b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner} 2386b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 2396b70adc33054f8aee8c54d0f460458a9df11b8a5Russell BrennerResourceLoadScheduler::HostInformation::~HostInformation() 2406b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner{ 2416b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner ASSERT(m_requestsLoading.isEmpty()); 242f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch for (unsigned p = 0; p <= ResourceLoadPriorityHighest; p++) 2436b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner ASSERT(m_requestsPending[p].isEmpty()); 2446b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner} 2456b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 246f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochvoid ResourceLoadScheduler::HostInformation::schedule(ResourceLoader* resourceLoader, ResourceLoadPriority priority) 2476b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner{ 2486b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner m_requestsPending[priority].append(resourceLoader); 2496b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner} 2506b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 2516b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennervoid ResourceLoadScheduler::HostInformation::addLoadInProgress(ResourceLoader* resourceLoader) 2526b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner{ 2536b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner LOG(ResourceLoading, "HostInformation '%s' loading '%s'. Current count %d", m_name.latin1().data(), resourceLoader->url().string().latin1().data(), m_requestsLoading.size()); 2546b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner m_requestsLoading.add(resourceLoader); 2556b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner} 2566b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 2576b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennervoid ResourceLoadScheduler::HostInformation::remove(ResourceLoader* resourceLoader) 2586b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner{ 2596b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner if (m_requestsLoading.contains(resourceLoader)) { 2606b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner m_requestsLoading.remove(resourceLoader); 2616b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner return; 2626b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner } 2636b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 264f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch for (int priority = ResourceLoadPriorityHighest; priority >= ResourceLoadPriorityLowest; --priority) { 2656b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner RequestQueue::iterator end = m_requestsPending[priority].end(); 2666b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner for (RequestQueue::iterator it = m_requestsPending[priority].begin(); it != end; ++it) { 2676b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner if (*it == resourceLoader) { 2686b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner m_requestsPending[priority].remove(it); 2696b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner return; 2706b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner } 2716b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner } 2726b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner } 2736b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner} 2746b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 2756b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennerbool ResourceLoadScheduler::HostInformation::hasRequests() const 2766b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner{ 2776b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner if (!m_requestsLoading.isEmpty()) 2786b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner return true; 279f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch for (unsigned p = 0; p <= ResourceLoadPriorityHighest; p++) { 2806b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner if (!m_requestsPending[p].isEmpty()) 2816b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner return true; 2826b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner } 2836b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner return false; 2846b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner} 2856b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 2862daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochbool ResourceLoadScheduler::HostInformation::limitRequests(ResourceLoadPriority priority) const 2872daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 2882daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (priority == ResourceLoadPriorityVeryLow && !m_requestsLoading.isEmpty()) 2892daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return true; 290f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch return m_requestsLoading.size() >= (resourceLoadScheduler()->isSerialLoadingEnabled() ? 1 : m_maxRequestsInFlight); 291f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch} 292f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 2936b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner} // namespace WebCore 294