[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc
japhet at chromium.org
japhet at chromium.org
Wed Dec 22 15:35:15 UTC 2010
The following commit has been merged in the debian/experimental branch:
commit 22e5436cadb1abb368f5ff1e4e2e95a84f680e09
Author: japhet at chromium.org <japhet at chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Mon Nov 8 21:01:53 2010 +0000
2010-11-08 Nate Chapin <japhet at chromium.org>
Reviewed by Alexey Proskuryakov.
Move connection-per-host counting and request prioritization out
of Loader and down to the ResourceLoader level.
https://bugs.webkit.org/show_bug.cgi?id=27165
Refactor only, so no new tests.
* CMakeLists.txt:
* GNUmakefile.am:
* WebCore.exp.in:
* WebCore.gypi:
* WebCore.pro:
* WebCore.vcproj/WebCore.vcproj:
* WebCore.xcodeproj/project.pbxproj:
* dom/ContainerNode.cpp:
(WebCore::ContainerNode::suspendPostAttachCallbacks):
(WebCore::ContainerNode::resumePostAttachCallbacks):
* loader/DocumentThreadableLoader.cpp:
(WebCore::DocumentThreadableLoader::loadRequest):
* loader/MainResourceLoader.cpp:
(WebCore::MainResourceLoader::loadNow):
* loader/NetscapePlugInStreamLoader.cpp:
(WebCore::NetscapePlugInStreamLoader::create):
* loader/NetscapePlugInStreamLoader.h:
* loader/ResourceLoadScheduler.cpp: Added.
(WebCore::ResourceLoadScheduler::hostForURL):
(WebCore::resourceLoadScheduler): Returns the single ResourceLoadScheduler instance
(WebCore::ResourceLoadScheduler::ResourceLoadScheduler):
(WebCore::ResourceLoadScheduler::scheduleSubresourceLoad):
(WebCore::ResourceLoadScheduler::schedulePluginStreamLoad):
(WebCore::ResourceLoadScheduler::addMainResourceLoad):
(WebCore::ResourceLoadScheduler::scheduleLoad):
(WebCore::ResourceLoadScheduler::remove):
(WebCore::ResourceLoadScheduler::crossOriginRedirectReceived):
(WebCore::ResourceLoadScheduler::servePendingRequests):
(WebCore::ResourceLoadScheduler::suspendPendingRequests):
(WebCore::ResourceLoadScheduler::resumePendingRequests):
(WebCore::ResourceLoadScheduler::scheduleServePendingRequests):
(WebCore::ResourceLoadScheduler::requestTimerFired):
(WebCore::ResourceLoadScheduler::assertLoaderBeingCounted):
(WebCore::ResourceLoadScheduler::HostInformation::assertLoaderBeingCounted):
(WebCore::ResourceLoadScheduler::HostInformation::HostInformation):
(WebCore::ResourceLoadScheduler::HostInformation::~HostInformation):
(WebCore::ResourceLoadScheduler::HostInformation::schedule):
(WebCore::ResourceLoadScheduler::HostInformation::addLoadInProgress):
(WebCore::ResourceLoadScheduler::HostInformation::remove):
(WebCore::ResourceLoadScheduler::HostInformation::hasRequests):
* loader/ResourceLoadScheduler.h: Added.
(WebCore::ResourceLoadScheduler::HostInformation::name):
(WebCore::ResourceLoadScheduler::HostInformation::limitRequests):
(WebCore::ResourceLoadScheduler::HostInformation::requestsPending):
* loader/ResourceLoader.cpp:
(WebCore::ResourceLoader::releaseResources): Remove this from ResourceLoadScheduler's counting.
(WebCore::ResourceLoader::load):
(WebCore::ResourceLoader::start): Create the ResourceHandle, called by ResourceLoadScheduler.
(WebCore::ResourceLoader::willSendRequest): Ensure ResourceLoadScheduler counts redirects
correctly.
* loader/ResourceLoader.h:
(WebCore::ResourceLoader::url):
* loader/icon/IconLoader.cpp:
(WebCore::IconLoader::startLoading):
* loader/loader.cpp: Move scheduling to ResourceLoadScheduler, remove Host subclass
and make Loader the SubresourceLoaderClient instead.
(WebCore::determinePriority):
(WebCore::Loader::load): Schedule the creation of the ResourceHandle, rather than
doing it immediately.
(WebCore::Loader::cancelRequests):
(WebCore::Loader::didFinishLoading):
(WebCore::Loader::didFail):
(WebCore::Loader::didReceiveResponse):
(WebCore::Loader::didReceiveData):
(WebCore::Loader::didReceiveCachedMetadata):
* loader/loader.h:
* page/EventSource.cpp:
(WebCore::EventSource::connect):
(WebCore::EventSource::endRequest):
* plugins/PluginStream.cpp:
(WebCore::PluginStream::start):
* xml/XMLHttpRequest.cpp:
(WebCore::XMLHttpRequest::XMLHttpRequest):
(WebCore::XMLHttpRequest::~XMLHttpRequest):
(WebCore::XMLHttpRequest::createRequest):
(WebCore::XMLHttpRequest::didFail):
(WebCore::XMLHttpRequest::didFinishLoading):
* xml/XMLHttpRequest.h:
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@71562 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/WebCore/CMakeLists.txt b/WebCore/CMakeLists.txt
index e7e741a..779c7f8 100644
--- a/WebCore/CMakeLists.txt
+++ b/WebCore/CMakeLists.txt
@@ -1172,6 +1172,7 @@ SET(WebCore_SOURCES
loader/NavigationScheduler.cpp
loader/Request.cpp
loader/ResourceLoadNotifier.cpp
+ loader/ResourceLoadScheduler.cpp
loader/ResourceLoader.cpp
loader/SinkDocument.cpp
loader/SubframeLoader.cpp
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 6bf8f3c..2db8db1 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,93 @@
+2010-11-08 Nate Chapin <japhet at chromium.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ Move connection-per-host counting and request prioritization out
+ of Loader and down to the ResourceLoader level.
+
+ https://bugs.webkit.org/show_bug.cgi?id=27165
+
+ Refactor only, so no new tests.
+
+ * CMakeLists.txt:
+ * GNUmakefile.am:
+ * WebCore.exp.in:
+ * WebCore.gypi:
+ * WebCore.pro:
+ * WebCore.vcproj/WebCore.vcproj:
+ * WebCore.xcodeproj/project.pbxproj:
+ * dom/ContainerNode.cpp:
+ (WebCore::ContainerNode::suspendPostAttachCallbacks):
+ (WebCore::ContainerNode::resumePostAttachCallbacks):
+ * loader/DocumentThreadableLoader.cpp:
+ (WebCore::DocumentThreadableLoader::loadRequest):
+ * loader/MainResourceLoader.cpp:
+ (WebCore::MainResourceLoader::loadNow):
+ * loader/NetscapePlugInStreamLoader.cpp:
+ (WebCore::NetscapePlugInStreamLoader::create):
+ * loader/NetscapePlugInStreamLoader.h:
+ * loader/ResourceLoadScheduler.cpp: Added.
+ (WebCore::ResourceLoadScheduler::hostForURL):
+ (WebCore::resourceLoadScheduler): Returns the single ResourceLoadScheduler instance
+ (WebCore::ResourceLoadScheduler::ResourceLoadScheduler):
+ (WebCore::ResourceLoadScheduler::scheduleSubresourceLoad):
+ (WebCore::ResourceLoadScheduler::schedulePluginStreamLoad):
+ (WebCore::ResourceLoadScheduler::addMainResourceLoad):
+ (WebCore::ResourceLoadScheduler::scheduleLoad):
+ (WebCore::ResourceLoadScheduler::remove):
+ (WebCore::ResourceLoadScheduler::crossOriginRedirectReceived):
+ (WebCore::ResourceLoadScheduler::servePendingRequests):
+ (WebCore::ResourceLoadScheduler::suspendPendingRequests):
+ (WebCore::ResourceLoadScheduler::resumePendingRequests):
+ (WebCore::ResourceLoadScheduler::scheduleServePendingRequests):
+ (WebCore::ResourceLoadScheduler::requestTimerFired):
+ (WebCore::ResourceLoadScheduler::assertLoaderBeingCounted):
+ (WebCore::ResourceLoadScheduler::HostInformation::assertLoaderBeingCounted):
+ (WebCore::ResourceLoadScheduler::HostInformation::HostInformation):
+ (WebCore::ResourceLoadScheduler::HostInformation::~HostInformation):
+ (WebCore::ResourceLoadScheduler::HostInformation::schedule):
+ (WebCore::ResourceLoadScheduler::HostInformation::addLoadInProgress):
+ (WebCore::ResourceLoadScheduler::HostInformation::remove):
+ (WebCore::ResourceLoadScheduler::HostInformation::hasRequests):
+ * loader/ResourceLoadScheduler.h: Added.
+ (WebCore::ResourceLoadScheduler::HostInformation::name):
+ (WebCore::ResourceLoadScheduler::HostInformation::limitRequests):
+ (WebCore::ResourceLoadScheduler::HostInformation::requestsPending):
+ * loader/ResourceLoader.cpp:
+ (WebCore::ResourceLoader::releaseResources): Remove this from ResourceLoadScheduler's counting.
+ (WebCore::ResourceLoader::load):
+ (WebCore::ResourceLoader::start): Create the ResourceHandle, called by ResourceLoadScheduler.
+ (WebCore::ResourceLoader::willSendRequest): Ensure ResourceLoadScheduler counts redirects
+ correctly.
+ * loader/ResourceLoader.h:
+ (WebCore::ResourceLoader::url):
+ * loader/icon/IconLoader.cpp:
+ (WebCore::IconLoader::startLoading):
+ * loader/loader.cpp: Move scheduling to ResourceLoadScheduler, remove Host subclass
+ and make Loader the SubresourceLoaderClient instead.
+ (WebCore::determinePriority):
+ (WebCore::Loader::load): Schedule the creation of the ResourceHandle, rather than
+ doing it immediately.
+ (WebCore::Loader::cancelRequests):
+ (WebCore::Loader::didFinishLoading):
+ (WebCore::Loader::didFail):
+ (WebCore::Loader::didReceiveResponse):
+ (WebCore::Loader::didReceiveData):
+ (WebCore::Loader::didReceiveCachedMetadata):
+ * loader/loader.h:
+ * page/EventSource.cpp:
+ (WebCore::EventSource::connect):
+ (WebCore::EventSource::endRequest):
+ * plugins/PluginStream.cpp:
+ (WebCore::PluginStream::start):
+ * xml/XMLHttpRequest.cpp:
+ (WebCore::XMLHttpRequest::XMLHttpRequest):
+ (WebCore::XMLHttpRequest::~XMLHttpRequest):
+ (WebCore::XMLHttpRequest::createRequest):
+ (WebCore::XMLHttpRequest::didFail):
+ (WebCore::XMLHttpRequest::didFinishLoading):
+ * xml/XMLHttpRequest.h:
+
2010-11-08 Ryosuke Niwa <rniwa at webkit.org>
Reviewed by Darin Adler.
diff --git a/WebCore/GNUmakefile.am b/WebCore/GNUmakefile.am
index 63d0455..53d2fb4 100644
--- a/WebCore/GNUmakefile.am
+++ b/WebCore/GNUmakefile.am
@@ -1999,6 +1999,8 @@ webcore_sources += \
WebCore/loader/ResourceLoader.h \
WebCore/loader/ResourceLoadNotifier.cpp \
WebCore/loader/ResourceLoadNotifier.h \
+ WebCore/loader/ResourceLoadScheduler.cpp \
+ WebCore/loader/ResourceLoadScheduler.h \
WebCore/loader/SinkDocument.cpp \
WebCore/loader/SinkDocument.h \
WebCore/loader/SubframeLoader.cpp \
diff --git a/WebCore/WebCore.exp.in b/WebCore/WebCore.exp.in
index 217f328..89bf768 100644
--- a/WebCore/WebCore.exp.in
+++ b/WebCore/WebCore.exp.in
@@ -479,6 +479,8 @@ __ZN7WebCore20ResourceResponseBaseC2Ev
__ZN7WebCore20SpaceSplitStringData12createVectorEv
__ZN7WebCore20protocolIsJavaScriptERKN3WTF6StringE
__ZN7WebCore21BackForwardController11itemAtIndexEi
+__ZN7WebCore21ResourceLoadScheduler20servePendingRequestsENS0_8PriorityE
+__ZN7WebCore21ResourceLoadScheduler24schedulePluginStreamLoadEPNS_5FrameEPNS_32NetscapePlugInStreamLoaderClientERKNS_15ResourceRequestE
__ZN7WebCore21PlatformKeyboardEvent24disambiguateKeyDownEventENS0_4TypeEb
__ZN7WebCore21PlatformKeyboardEventC1EP7NSEvent
__ZN7WebCore21SVGDocumentExtensions21sampleAnimationAtTimeERKN3WTF6StringEPNS_14SVGSMILElementEd
@@ -493,6 +495,7 @@ __ZN7WebCore21isBackForwardLoadTypeENS_13FrameLoadTypeE
__ZN7WebCore21mainThreadNormalWorldEv
__ZN7WebCore21markerTextForListItemEPNS_7ElementE
__ZN7WebCore21reportThreadViolationEPKcNS_20ThreadViolationRoundE
+__ZN7WebCore21resourceLoadSchedulerEv
__ZN7WebCore21setPlatformStrategiesEPNS_18PlatformStrategiesE
__ZN7WebCore22ScriptExecutionContext26canSuspendActiveDOMObjectsEv
__ZN7WebCore22applicationIsAppleMailEv
@@ -525,7 +528,6 @@ __ZN7WebCore25PluginMainThreadScheduler9schedulerEv
__ZN7WebCore25addLanguageChangeObserverEPvPFvS0_E
__ZN7WebCore25contextMenuItemTagOutlineEv
__ZN7WebCore26CSSMutableStyleDeclarationC1Ev
-__ZN7WebCore26NetscapePlugInStreamLoader6createEPNS_5FrameEPNS_32NetscapePlugInStreamLoaderClientE
__ZN7WebCore26UserTypingGestureIndicator27processingUserTypingGestureEv
__ZN7WebCore26UserTypingGestureIndicator28focusedElementAtGestureStartEv
__ZN7WebCore26contextMenuItemTagFontMenuEv
@@ -699,7 +701,6 @@ __ZN7WebCore6Editor6indentEv
__ZN7WebCore6Editor7CommandC1Ev
__ZN7WebCore6Editor7commandERKN3WTF6StringE
__ZN7WebCore6Editor7outdentEv
-__ZN7WebCore6Loader20servePendingRequestsENS0_8PriorityE
__ZN7WebCore6Widget12setFrameRectERKNS_7IntRectE
__ZN7WebCore6Widget16removeFromParentEv
__ZN7WebCore6Widget17frameRectsChangedEv
diff --git a/WebCore/WebCore.gypi b/WebCore/WebCore.gypi
index faa339a..1b6fb51 100644
--- a/WebCore/WebCore.gypi
+++ b/WebCore/WebCore.gypi
@@ -2102,6 +2102,8 @@
'loader/ResourceLoader.h',
'loader/ResourceLoadNotifier.cpp',
'loader/ResourceLoadNotifier.h',
+ 'loader/ResourceLoadScheduler.cpp',
+ 'loader/ResourceLoadScheduler.h',
'loader/SinkDocument.cpp',
'loader/SinkDocument.h',
'loader/SubframeLoader.cpp',
diff --git a/WebCore/WebCore.pro b/WebCore/WebCore.pro
index 7a98a1f..459e4fb 100644
--- a/WebCore/WebCore.pro
+++ b/WebCore/WebCore.pro
@@ -1069,6 +1069,7 @@ SOURCES += \
loader/Request.cpp \
loader/ResourceLoader.cpp \
loader/ResourceLoadNotifier.cpp \
+ loader/ResourceLoadScheduler.cpp \
loader/SinkDocument.cpp \
loader/SubframeLoader.cpp \
loader/SubresourceLoader.cpp \
diff --git a/WebCore/WebCore.vcproj/WebCore.vcproj b/WebCore/WebCore.vcproj/WebCore.vcproj
index 3d38870..868a5d6 100644
--- a/WebCore/WebCore.vcproj/WebCore.vcproj
+++ b/WebCore/WebCore.vcproj/WebCore.vcproj
@@ -23948,6 +23948,14 @@
>
</File>
<File
+ RelativePath="..\loader\ResourceLoadScheduler.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\loader\ ResourceLoadScheduler.h"
+ >
+ </File>
+ <File
RelativePath="..\loader\SinkDocument.cpp"
>
</File>
diff --git a/WebCore/WebCore.xcodeproj/project.pbxproj b/WebCore/WebCore.xcodeproj/project.pbxproj
index b7e5d48..61e9de3 100644
--- a/WebCore/WebCore.xcodeproj/project.pbxproj
+++ b/WebCore/WebCore.xcodeproj/project.pbxproj
@@ -5327,6 +5327,8 @@
D086FE9909D53AAB005BC74D /* UnlinkCommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D086FE9709D53AAB005BC74D /* UnlinkCommand.cpp */; };
D0B0556809C6700100307E43 /* CreateLinkCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = D0B0556609C6700100307E43 /* CreateLinkCommand.h */; };
D0B0556909C6700100307E43 /* CreateLinkCommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0B0556709C6700100307E43 /* CreateLinkCommand.cpp */; };
+ D0CE58F8125E4CC200F3F199 /* ResourceLoadScheduler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0CE58F6125E4CC200F3F199 /* ResourceLoadScheduler.cpp */; };
+ D0CE58F9125E4CC200F3F199 /* ResourceLoadScheduler.h in Headers */ = {isa = PBXBuildFile; fileRef = D0CE58F7125E4CC200F3F199 /* ResourceLoadScheduler.h */; settings = {ATTRIBUTES = (Private, ); }; };
D0FF2A5D11F8C45A007E74E0 /* PingLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0FF2A5B11F8C45A007E74E0 /* PingLoader.cpp */; };
D0FF2A5E11F8C45A007E74E0 /* PingLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = D0FF2A5C11F8C45A007E74E0 /* PingLoader.h */; };
D23CA55D0AB0EAAE005108A5 /* JSRangeException.h in Headers */ = {isa = PBXBuildFile; fileRef = D23CA55C0AB0EAAE005108A5 /* JSRangeException.h */; };
@@ -11389,6 +11391,8 @@
D086FE9709D53AAB005BC74D /* UnlinkCommand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UnlinkCommand.cpp; sourceTree = "<group>"; };
D0B0556609C6700100307E43 /* CreateLinkCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CreateLinkCommand.h; sourceTree = "<group>"; };
D0B0556709C6700100307E43 /* CreateLinkCommand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CreateLinkCommand.cpp; sourceTree = "<group>"; };
+ D0CE58F6125E4CC200F3F199 /* ResourceLoadScheduler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ResourceLoadScheduler.cpp; sourceTree = "<group>"; };
+ D0CE58F7125E4CC200F3F199 /* ResourceLoadScheduler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ResourceLoadScheduler.h; sourceTree = "<group>"; };
D0FF2A5B11F8C45A007E74E0 /* PingLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PingLoader.cpp; sourceTree = "<group>"; };
D0FF2A5C11F8C45A007E74E0 /* PingLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PingLoader.h; sourceTree = "<group>"; };
D23CA5480AB0E983005108A5 /* RangeException.idl */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = RangeException.idl; sourceTree = "<group>"; };
@@ -17333,6 +17337,8 @@
656D37270ADBA5DE00A4554D /* ResourceLoader.h */,
973E325410883B7C005BC493 /* ResourceLoadNotifier.cpp */,
973E325510883B7C005BC493 /* ResourceLoadNotifier.h */,
+ D0CE58F6125E4CC200F3F199 /* ResourceLoadScheduler.cpp */,
+ D0CE58F7125E4CC200F3F199 /* ResourceLoadScheduler.h */,
51327D5F11A33A2B004F9D65 /* SinkDocument.cpp */,
51327D5E11A33A2B004F9D65 /* SinkDocument.h */,
D000ED2511C1B9CD00C47726 /* SubframeLoader.cpp */,
@@ -20709,6 +20715,7 @@
514C767B0CE923A1007EF3CD /* ResourceHandleInternal.h in Headers */,
656D373F0ADBA5DE00A4554D /* ResourceLoader.h in Headers */,
973E325710883B7C005BC493 /* ResourceLoadNotifier.h in Headers */,
+ D0CE58F9125E4CC200F3F199 /* ResourceLoadScheduler.h in Headers */,
8A81BF8511DCFD9000DA2B98 /* ResourceLoadTiming.h in Headers */,
492863991253B8FC00F792D6 /* ResourceRawHeaders.h in Headers */,
514C76520CE9234E007EF3CD /* ResourceRequest.h in Headers */,
@@ -23896,6 +23903,7 @@
93F19B0508245E59001E9ABC /* XSLTProcessorLibxslt.cpp in Sources */,
E1BE512D0CF6C512002EA959 /* XSLTUnicodeSort.cpp in Sources */,
97DD4D860FDF4D6E00ECF9A4 /* XSSAuditor.cpp in Sources */,
+ D0CE58F8125E4CC200F3F199 /* ResourceLoadScheduler.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
diff --git a/WebCore/dom/ContainerNode.cpp b/WebCore/dom/ContainerNode.cpp
index 79d233a..294d0fe 100644
--- a/WebCore/dom/ContainerNode.cpp
+++ b/WebCore/dom/ContainerNode.cpp
@@ -35,11 +35,11 @@
#include "InlineTextBox.h"
#include "InspectorInstrumentation.h"
#include "MutationEvent.h"
+#include "ResourceLoadScheduler.h"
#include "Page.h"
#include "RenderBox.h"
#include "RenderTheme.h"
#include "RootInlineBox.h"
-#include "loader.h"
#include <wtf/CurrentTime.h>
#include <wtf/Vector.h>
@@ -655,7 +655,7 @@ void ContainerNode::suspendPostAttachCallbacks()
s_shouldReEnableMemoryCacheCallsAfterAttach = true;
}
}
- cache()->loader()->suspendPendingRequests();
+ resourceLoadScheduler()->suspendPendingRequests();
}
++s_attachDepth;
}
@@ -670,7 +670,7 @@ void ContainerNode::resumePostAttachCallbacks()
if (Page* page = document()->page())
page->setMemoryCacheClientCallsEnabled(true);
}
- cache()->loader()->resumePendingRequests();
+ resourceLoadScheduler()->resumePendingRequests();
}
--s_attachDepth;
}
diff --git a/WebCore/loader/DocumentThreadableLoader.cpp b/WebCore/loader/DocumentThreadableLoader.cpp
index a792144..03cea73 100644
--- a/WebCore/loader/DocumentThreadableLoader.cpp
+++ b/WebCore/loader/DocumentThreadableLoader.cpp
@@ -38,6 +38,7 @@
#include "Frame.h"
#include "FrameLoader.h"
#include "ResourceHandle.h"
+#include "ResourceLoadScheduler.h"
#include "ResourceRequest.h"
#include "SecurityOrigin.h"
#include "SubresourceLoader.h"
@@ -319,7 +320,7 @@ void DocumentThreadableLoader::loadRequest(const ResourceRequest& request, Secur
// Clear the loader so that any callbacks from SubresourceLoader::create will not have the old loader.
m_loader = 0;
- m_loader = SubresourceLoader::create(m_document->frame(), this, request, securityCheck, sendLoadCallbacks, sniffContent);
+ m_loader = resourceLoadScheduler()->scheduleSubresourceLoad(m_document->frame(), this, request, ResourceLoadScheduler::Medium, securityCheck, sendLoadCallbacks, sniffContent);
return;
}
diff --git a/WebCore/loader/MainResourceLoader.cpp b/WebCore/loader/MainResourceLoader.cpp
index 7e5eb90..85ceb19 100644
--- a/WebCore/loader/MainResourceLoader.cpp
+++ b/WebCore/loader/MainResourceLoader.cpp
@@ -44,6 +44,7 @@
#endif
#include "ResourceError.h"
#include "ResourceHandle.h"
+#include "ResourceLoadScheduler.h"
#include "SchemeRegistry.h"
#include "Settings.h"
#include <wtf/CurrentTime.h>
@@ -548,6 +549,7 @@ bool MainResourceLoader::loadNow(ResourceRequest& r)
if (shouldLoadEmptyBeforeRedirect && !shouldLoadEmpty && defersLoading())
return true;
+ resourceLoadScheduler()->addMainResourceLoad(this);
if (m_substituteData.isValid())
handleDataLoadSoon(r);
else if (shouldLoadEmpty || frameLoader()->representationExistsForURLScheme(url.protocol()))
diff --git a/WebCore/loader/NetscapePlugInStreamLoader.cpp b/WebCore/loader/NetscapePlugInStreamLoader.cpp
index 1225652..c9725e9 100644
--- a/WebCore/loader/NetscapePlugInStreamLoader.cpp
+++ b/WebCore/loader/NetscapePlugInStreamLoader.cpp
@@ -44,9 +44,12 @@ NetscapePlugInStreamLoader::~NetscapePlugInStreamLoader()
{
}
-PassRefPtr<NetscapePlugInStreamLoader> NetscapePlugInStreamLoader::create(Frame* frame, NetscapePlugInStreamLoaderClient* client)
+PassRefPtr<NetscapePlugInStreamLoader> NetscapePlugInStreamLoader::create(Frame* frame, NetscapePlugInStreamLoaderClient* client, const ResourceRequest& request)
{
- return adoptRef(new NetscapePlugInStreamLoader(frame, client));
+ RefPtr<NetscapePlugInStreamLoader> loader(adoptRef(new NetscapePlugInStreamLoader(frame, client)));
+ loader->setShouldBufferData(false);
+ loader->documentLoader()->addPlugInStreamLoader(loader.get());
+ return loader->load(request) ? loader.release() : 0;
}
bool NetscapePlugInStreamLoader::isDone() const
diff --git a/WebCore/loader/NetscapePlugInStreamLoader.h b/WebCore/loader/NetscapePlugInStreamLoader.h
index c8c4cb6..4d7d03b 100644
--- a/WebCore/loader/NetscapePlugInStreamLoader.h
+++ b/WebCore/loader/NetscapePlugInStreamLoader.h
@@ -47,7 +47,7 @@ namespace WebCore {
class NetscapePlugInStreamLoader : public ResourceLoader {
public:
- static PassRefPtr<NetscapePlugInStreamLoader> create(Frame*, NetscapePlugInStreamLoaderClient*);
+ static PassRefPtr<NetscapePlugInStreamLoader> create(Frame*, NetscapePlugInStreamLoaderClient*, const ResourceRequest&);
virtual ~NetscapePlugInStreamLoader();
bool isDone() const;
diff --git a/WebCore/loader/ResourceLoadScheduler.cpp b/WebCore/loader/ResourceLoadScheduler.cpp
new file mode 100644
index 0000000..ad04f12
--- /dev/null
+++ b/WebCore/loader/ResourceLoadScheduler.cpp
@@ -0,0 +1,312 @@
+/*
+ Copyright (C) 1998 Lars Knoll (knoll at mpi-hd.mpg.de)
+ Copyright (C) 2001 Dirk Mueller (mueller at kde.org)
+ Copyright (C) 2002 Waldo Bastian (bastian at kde.org)
+ Copyright (C) 2006 Samuel Weinig (sam.weinig at gmail.com)
+ Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ Copyright (C) 2010 Google Inc. All rights reserved.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "ResourceLoadScheduler.h"
+
+#include "Document.h"
+#include "Frame.h"
+#include "FrameLoader.h"
+#include "InspectorInstrumentation.h"
+#include "KURL.h"
+#include "Logging.h"
+#include "NetscapePlugInStreamLoader.h"
+#include "ResourceLoader.h"
+#include "ResourceRequest.h"
+#include "SubresourceLoader.h"
+
+#define REQUEST_MANAGEMENT_ENABLED 1
+
+namespace WebCore {
+
+#if REQUEST_MANAGEMENT_ENABLED
+static const unsigned maxRequestsInFlightForNonHTTPProtocols = 20;
+// Match the parallel connection count used by the networking layer.
+static unsigned maxRequestsInFlightPerHost;
+#else
+static const unsigned maxRequestsInFlightForNonHTTPProtocols = 10000;
+static const unsigned maxRequestsInFlightPerHost = 10000;
+#endif
+
+ResourceLoadScheduler::HostInformation* ResourceLoadScheduler::hostForURL(const KURL& url, CreateHostPolicy createHostPolicy)
+{
+ if (!url.protocolInHTTPFamily())
+ return m_nonHTTPProtocolHost;
+
+ m_hosts.checkConsistency();
+ String hostName = url.host();
+ HostInformation* host = m_hosts.get(hostName);
+ if (!host && createHostPolicy == CreateIfNotFound) {
+ host = new HostInformation(hostName, maxRequestsInFlightPerHost);
+ m_hosts.add(hostName, host);
+ }
+ return host;
+}
+
+ResourceLoadScheduler* resourceLoadScheduler()
+{
+ ASSERT(isMainThread());
+ DEFINE_STATIC_LOCAL(ResourceLoadScheduler, resourceLoadScheduler, ());
+ return &resourceLoadScheduler;
+}
+
+ResourceLoadScheduler::ResourceLoadScheduler()
+ : m_nonHTTPProtocolHost(new HostInformation(String(), maxRequestsInFlightForNonHTTPProtocols))
+ , m_requestTimer(this, &ResourceLoadScheduler::requestTimerFired)
+ , m_isSuspendingPendingRequests(false)
+{
+#if REQUEST_MANAGEMENT_ENABLED
+ maxRequestsInFlightPerHost = initializeMaximumHTTPConnectionCountPerHost();
+#endif
+}
+
+PassRefPtr<SubresourceLoader> ResourceLoadScheduler::scheduleSubresourceLoad(Frame* frame, SubresourceLoaderClient* client, const ResourceRequest& request, Priority priority, SecurityCheckPolicy securityCheck, bool sendResourceLoadCallbacks, bool shouldContentSniff)
+{
+ PassRefPtr<SubresourceLoader> loader = SubresourceLoader::create(frame, client, request, securityCheck, sendResourceLoadCallbacks, shouldContentSniff);
+ if (loader)
+ scheduleLoad(loader.get(), priority);
+ return loader;
+}
+
+PassRefPtr<NetscapePlugInStreamLoader> ResourceLoadScheduler::schedulePluginStreamLoad(Frame* frame, NetscapePlugInStreamLoaderClient* client, const ResourceRequest& request)
+{
+ PassRefPtr<NetscapePlugInStreamLoader> loader = NetscapePlugInStreamLoader::create(frame, client, request);
+ if (loader)
+ scheduleLoad(loader.get(), Low);
+ return loader;
+}
+
+void ResourceLoadScheduler::addMainResourceLoad(ResourceLoader* resourceLoader)
+{
+ hostForURL(resourceLoader->url(), CreateIfNotFound)->addLoadInProgress(resourceLoader);
+}
+
+void ResourceLoadScheduler::scheduleLoad(ResourceLoader* resourceLoader, Priority priority)
+{
+ ASSERT(resourceLoader);
+#if !REQUEST_MANAGEMENT_ENABLED
+ priority = High;
+#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 > Low || !resourceLoader->url().protocolInHTTPFamily() || (priority == Low && !hadRequests)) {
+ // Try to request important resources immediately.
+ servePendingRequests(host, priority);
+ } else {
+ // 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 ResourceLoadScheduler::remove(ResourceLoader* resourceLoader)
+{
+ ASSERT(resourceLoader);
+
+ HostInformation* host = hostForURL(resourceLoader->url());
+ if (host)
+ host->remove(resourceLoader);
+ scheduleServePendingRequests();
+}
+
+void ResourceLoadScheduler::crossOriginRedirectReceived(ResourceLoader* resourceLoader, const KURL& redirectURL)
+{
+ HostInformation* oldHost = hostForURL(resourceLoader->url());
+ ASSERT(oldHost);
+ HostInformation* newHost = hostForURL(redirectURL, CreateIfNotFound);
+
+ if (oldHost->name() == newHost->name())
+ return;
+
+ newHost->addLoadInProgress(resourceLoader);
+ oldHost->remove(resourceLoader);
+}
+
+void ResourceLoadScheduler::servePendingRequests(Priority minimumPriority)
+{
+ LOG(ResourceLoading, "ResourceLoadScheduler::servePendingRequests. m_isSuspendingPendingRequests=%d", m_isSuspendingPendingRequests);
+ if (m_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->second);
+
+ 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::servePendingRequests(HostInformation* host, Priority minimumPriority)
+{
+ LOG(ResourceLoading, "ResourceLoadScheduler::servePendingRequests HostInformation.m_name='%s'", host->name().latin1().data());
+
+ for (int priority = High; priority >= minimumPriority; --priority) {
+ HostInformation::RequestQueue& requestsPending = host->requestsPending((Priority) priority);
+ HostInformation::RequestQueue deferredRequests;
+
+ while (!requestsPending.isEmpty()) {
+ RefPtr<ResourceLoader> resourceLoader = requestsPending.first();
+
+ // For named hosts - which are only http(s) hosts - we should always enforce the connection limit.
+ // For non-named hosts - everything but http(s) - we should only enforce the limit if the document isn't done parsing
+ // and we don't know all stylesheets yet.
+ Document* document = resourceLoader->frameLoader() ? resourceLoader->frameLoader()->frame()->document() : 0;
+ bool shouldLimitRequests = !host->name().isNull() || (document && (document->parsing() || !document->haveStylesheetsLoaded()));
+ if (shouldLimitRequests && host->limitRequests()) {
+ while (!deferredRequests.isEmpty())
+ requestsPending.append(deferredRequests.takeFirst());
+ return;
+ }
+
+ if (resourceLoader->start())
+ host->addLoadInProgress(resourceLoader.get());
+ else
+ deferredRequests.append(resourceLoader);
+ requestsPending.removeFirst();
+ }
+
+ requestsPending.swap(deferredRequests);
+ }
+}
+
+void ResourceLoadScheduler::suspendPendingRequests()
+{
+ ASSERT(!m_isSuspendingPendingRequests);
+ m_isSuspendingPendingRequests = true;
+}
+
+void ResourceLoadScheduler::resumePendingRequests()
+{
+ ASSERT(m_isSuspendingPendingRequests);
+ m_isSuspendingPendingRequests = false;
+ if (!m_hosts.isEmpty() || m_nonHTTPProtocolHost->hasRequests())
+ scheduleServePendingRequests();
+}
+
+void ResourceLoadScheduler::scheduleServePendingRequests()
+{
+ LOG(ResourceLoading, "ResourceLoadScheduler::scheduleServePendingRequests, m_requestTimer.isActive()=%u", m_requestTimer.isActive());
+ if (!m_requestTimer.isActive())
+ m_requestTimer.startOneShot(0);
+}
+
+void ResourceLoadScheduler::requestTimerFired(Timer<ResourceLoadScheduler>*)
+{
+ LOG(ResourceLoading, "ResourceLoadScheduler::requestTimerFired\n");
+ servePendingRequests();
+}
+
+#ifndef NDEBUG
+void ResourceLoadScheduler::assertLoaderBeingCounted(ResourceLoader* resourceLoader)
+{
+ HostInformation* host = hostForURL(resourceLoader->url());
+ ASSERT(host);
+ host->assertLoaderBeingCounted(resourceLoader);
+}
+
+void ResourceLoadScheduler::HostInformation::assertLoaderBeingCounted(ResourceLoader* resourceLoader)
+{
+ // If a load is being started, it should be at the front of the highest priority queue
+ // that actually contains a request.
+ for (int priority = High; priority >= VeryLow; --priority) {
+ if (!m_requestsPending[priority].isEmpty()) {
+ ASSERT(m_requestsPending[priority].first().get() == resourceLoader);
+ return;
+ }
+ }
+
+ ASSERT_NOT_REACHED();
+}
+#endif
+
+ResourceLoadScheduler::HostInformation::HostInformation(const String& name, unsigned maxRequestsInFlight)
+ : m_name(name)
+ , m_maxRequestsInFlight(maxRequestsInFlight)
+{
+}
+
+ResourceLoadScheduler::HostInformation::~HostInformation()
+{
+ ASSERT(m_requestsLoading.isEmpty());
+ for (unsigned p = 0; p <= High; p++)
+ ASSERT(m_requestsPending[p].isEmpty());
+}
+
+void ResourceLoadScheduler::HostInformation::schedule(ResourceLoader* resourceLoader, Priority priority)
+{
+ m_requestsPending[priority].append(resourceLoader);
+}
+
+void ResourceLoadScheduler::HostInformation::addLoadInProgress(ResourceLoader* resourceLoader)
+{
+ LOG(ResourceLoading, "HostInformation '%s' loading '%s'. Current count %d", m_name.latin1().data(), resourceLoader->url().string().latin1().data(), m_requestsLoading.size());
+ m_requestsLoading.add(resourceLoader);
+}
+
+void ResourceLoadScheduler::HostInformation::remove(ResourceLoader* resourceLoader)
+{
+ if (m_requestsLoading.contains(resourceLoader)) {
+ m_requestsLoading.remove(resourceLoader);
+ return;
+ }
+
+ for (int priority = High; priority >= VeryLow; --priority) {
+ RequestQueue::iterator end = m_requestsPending[priority].end();
+ for (RequestQueue::iterator it = m_requestsPending[priority].begin(); it != end; ++it) {
+ if (*it == resourceLoader) {
+ m_requestsPending[priority].remove(it);
+ return;
+ }
+ }
+ }
+}
+
+bool ResourceLoadScheduler::HostInformation::hasRequests() const
+{
+ if (!m_requestsLoading.isEmpty())
+ return true;
+ for (unsigned p = 0; p <= High; p++) {
+ if (!m_requestsPending[p].isEmpty())
+ return true;
+ }
+ return false;
+}
+
+} // namespace WebCore
diff --git a/WebCore/loader/ResourceLoadScheduler.h b/WebCore/loader/ResourceLoadScheduler.h
new file mode 100644
index 0000000..511c1a1
--- /dev/null
+++ b/WebCore/loader/ResourceLoadScheduler.h
@@ -0,0 +1,121 @@
+/*
+ Copyright (C) 1998 Lars Knoll (knoll at mpi-hd.mpg.de)
+ Copyright (C) 2001 Dirk Mueller <mueller at kde.org>
+ Copyright (C) 2004, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ Copyright (C) 2010 Google Inc. All rights reserved.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+ */
+
+#ifndef ResourceLoadScheduler_h
+#define ResourceLoadScheduler_h
+
+#include "FrameLoaderTypes.h"
+#include "PlatformString.h"
+#include "Timer.h"
+#include <wtf/Deque.h>
+#include <wtf/HashMap.h>
+#include <wtf/HashSet.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/text/StringHash.h>
+
+namespace WebCore {
+
+class Frame;
+class KURL;
+class NetscapePlugInStreamLoader;
+class NetscapePlugInStreamLoaderClient;
+class ResourceLoader;
+class ResourceRequest;
+class SubresourceLoader;
+class SubresourceLoaderClient;
+
+class ResourceLoadScheduler : public Noncopyable {
+public:
+ friend ResourceLoadScheduler* resourceLoadScheduler();
+
+ enum Priority { VeryLow, Low, Medium, High };
+ PassRefPtr<SubresourceLoader> scheduleSubresourceLoad(Frame*, SubresourceLoaderClient*, const ResourceRequest&, Priority = Low, SecurityCheckPolicy = DoSecurityCheck, bool sendResourceLoadCallbacks = true, bool shouldContentSniff = true);
+ PassRefPtr<NetscapePlugInStreamLoader> schedulePluginStreamLoad(Frame*, NetscapePlugInStreamLoaderClient*, const ResourceRequest&);
+ void addMainResourceLoad(ResourceLoader*);
+ void remove(ResourceLoader*);
+ void crossOriginRedirectReceived(ResourceLoader*, const KURL& redirectURL);
+
+ void servePendingRequests(Priority minimumPriority = VeryLow);
+ void suspendPendingRequests();
+ void resumePendingRequests();
+
+#ifndef NDEBUG
+ void assertLoaderBeingCounted(ResourceLoader*);
+#endif
+
+private:
+ ResourceLoadScheduler();
+ ~ResourceLoadScheduler();
+
+ void scheduleLoad(ResourceLoader*, Priority);
+ void scheduleServePendingRequests();
+ void requestTimerFired(Timer<ResourceLoadScheduler>*);
+
+ class HostInformation : public Noncopyable {
+ public:
+ HostInformation(const String&, unsigned);
+ ~HostInformation();
+
+ const String& name() const { return m_name; }
+ void schedule(ResourceLoader*, Priority = VeryLow);
+ void addLoadInProgress(ResourceLoader*);
+ void remove(ResourceLoader*);
+ bool hasRequests() const;
+ bool limitRequests() const { return m_requestsLoading.size() >= m_maxRequestsInFlight; }
+
+#ifndef NDEBUG
+ void assertLoaderBeingCounted(ResourceLoader*);
+#endif
+
+ typedef Deque<RefPtr<ResourceLoader> > RequestQueue;
+ RequestQueue& requestsPending(Priority priority) { return m_requestsPending[priority]; }
+
+ private:
+ RequestQueue m_requestsPending[High + 1];
+ typedef HashSet<RefPtr<ResourceLoader> > RequestMap;
+ RequestMap m_requestsLoading;
+ const String m_name;
+ const int m_maxRequestsInFlight;
+ };
+
+ enum CreateHostPolicy {
+ CreateIfNotFound,
+ FindOnly
+ };
+
+ HostInformation* hostForURL(const KURL&, CreateHostPolicy = FindOnly);
+ void servePendingRequests(HostInformation*, Priority);
+
+ typedef HashMap<String, HostInformation*, StringHash> HostMap;
+ HostMap m_hosts;
+ HostInformation* m_nonHTTPProtocolHost;
+
+ Timer<ResourceLoadScheduler> m_requestTimer;
+
+ bool m_isSuspendingPendingRequests;
+};
+
+ResourceLoadScheduler* resourceLoadScheduler();
+
+}
+
+#endif
diff --git a/WebCore/loader/ResourceLoader.cpp b/WebCore/loader/ResourceLoader.cpp
index 3764798..08b3877 100644
--- a/WebCore/loader/ResourceLoader.cpp
+++ b/WebCore/loader/ResourceLoader.cpp
@@ -39,8 +39,9 @@
#include "InspectorInstrumentation.h"
#include "Page.h"
#include "ProgressTracker.h"
-#include "ResourceHandle.h"
#include "ResourceError.h"
+#include "ResourceHandle.h"
+#include "ResourceLoadScheduler.h"
#include "Settings.h"
#include "SharedBuffer.h"
@@ -95,6 +96,8 @@ void ResourceLoader::releaseResources()
m_identifier = 0;
+ resourceLoadScheduler()->remove(this);
+
if (m_handle) {
// Clear out the ResourceHandle's client so that it doesn't try to call
// us back after we release it, unless it has been replaced by someone else.
@@ -131,21 +134,32 @@ bool ResourceLoader::load(const ResourceRequest& r)
return false;
}
- if (m_documentLoader->scheduleArchiveLoad(this, clientRequest, r.url()))
- return true;
-
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
if (m_documentLoader->applicationCacheHost()->maybeLoadResource(this, clientRequest, r.url()))
return true;
#endif
- if (m_defersLoading) {
+ if (m_defersLoading)
m_deferredRequest = clientRequest;
- return true;
- }
+
+ return true;
+}
+
+bool ResourceLoader::start()
+{
+ ASSERT(!m_handle);
+#ifndef NDEBUG
+ resourceLoadScheduler()->assertLoaderBeingCounted(this);
+#endif
- m_handle = ResourceHandle::create(m_frame->loader()->networkingContext(), clientRequest, this, m_defersLoading, m_shouldContentSniff);
+ if (m_documentLoader->scheduleArchiveLoad(this, m_request, m_request.url()))
+ return true;
+
+ if (m_defersLoading)
+ return false;
+ if (!m_reachedTerminalState)
+ m_handle = ResourceHandle::create(m_frame->loader()->networkingContext(), m_request, this, m_defersLoading, m_shouldContentSniff);
return true;
}
@@ -223,6 +237,8 @@ void ResourceLoader::willSendRequest(ResourceRequest& request, const ResourceRes
frameLoader()->notifier()->willSendRequest(this, request, redirectResponse);
}
+ if (!redirectResponse.isNull())
+ resourceLoadScheduler()->crossOriginRedirectReceived(this, request.url());
m_request = request;
}
diff --git a/WebCore/loader/ResourceLoader.h b/WebCore/loader/ResourceLoader.h
index 920e3c2..9b69ccd 100644
--- a/WebCore/loader/ResourceLoader.h
+++ b/WebCore/loader/ResourceLoader.h
@@ -122,9 +122,13 @@ namespace WebCore {
virtual AsyncFileStream* createAsyncFileStream(FileStreamClient*);
#endif
+ const KURL& url() const { return m_request.url(); }
ResourceHandle* handle() const { return m_handle.get(); }
bool sendResourceLoadCallbacks() const { return m_sendResourceLoadCallbacks; }
+ // Called by ResourceLoadScheduler to create a ResourceHandle and actually begin the load.
+ bool start();
+
void setShouldBufferData(bool shouldBufferData);
protected:
diff --git a/WebCore/loader/icon/IconLoader.cpp b/WebCore/loader/icon/IconLoader.cpp
index adfa04b..24562d0 100644
--- a/WebCore/loader/icon/IconLoader.cpp
+++ b/WebCore/loader/icon/IconLoader.cpp
@@ -33,6 +33,7 @@
#include "IconDatabase.h"
#include "Logging.h"
#include "ResourceHandle.h"
+#include "ResourceLoadScheduler.h"
#include "ResourceResponse.h"
#include "ResourceRequest.h"
#include "SharedBuffer.h"
@@ -68,7 +69,7 @@ void IconLoader::startLoading()
// SubresourceLoader::create returns.
m_loadIsInProgress = true;
- RefPtr<SubresourceLoader> loader = SubresourceLoader::create(m_frame, this, m_frame->loader()->iconURL());
+ RefPtr<SubresourceLoader> loader = resourceLoadScheduler()->scheduleSubresourceLoad(m_frame, this, m_frame->loader()->iconURL());
if (!loader)
LOG_ERROR("Failed to start load for icon at url %s", m_frame->loader()->iconURL().string().ascii().data());
diff --git a/WebCore/loader/loader.cpp b/WebCore/loader/loader.cpp
index bd27312..05ad7db 100644
--- a/WebCore/loader/loader.cpp
+++ b/WebCore/loader/loader.cpp
@@ -28,45 +28,20 @@
#include "CachedImage.h"
#include "CachedResource.h"
#include "CachedResourceLoader.h"
-#include "InspectorInstrumentation.h"
#include "Frame.h"
#include "FrameLoader.h"
-#include "HTMLDocument.h"
#include "Logging.h"
#include "Request.h"
#include "ResourceHandle.h"
+#include "ResourceLoadScheduler.h"
#include "ResourceRequest.h"
#include "ResourceResponse.h"
-#include "SecurityOrigin.h"
#include "SharedBuffer.h"
-#include "SubresourceLoader.h"
#include <wtf/Assertions.h>
#include <wtf/Vector.h>
-#define REQUEST_MANAGEMENT_ENABLED 1
-
namespace WebCore {
-#if REQUEST_MANAGEMENT_ENABLED
-// Match the parallel connection count used by the networking layer
-static unsigned maxRequestsInFlightPerHost;
-// Having a limit might still help getting more important resources first
-static const unsigned maxRequestsInFlightForNonHTTPProtocols = 20;
-#else
-static const unsigned maxRequestsInFlightPerHost = 10000;
-static const unsigned maxRequestsInFlightForNonHTTPProtocols = 10000;
-#endif
-
-Loader::Loader()
- : m_requestTimer(this, &Loader::requestTimerFired)
- , m_isSuspendingPendingRequests(false)
-{
- m_nonHTTPProtocolHost = Host::create(AtomicString(), maxRequestsInFlightForNonHTTPProtocols);
-#if REQUEST_MANAGEMENT_ENABLED
- maxRequestsInFlightPerHost = initializeMaximumHTTPConnectionCountPerHost();
-#endif
-}
-
Loader::~Loader()
{
ASSERT_NOT_REACHED();
@@ -95,307 +70,102 @@ static ResourceRequest::TargetType cachedResourceTypeToTargetType(CachedResource
return ResourceRequest::TargetIsSubresource;
}
-Loader::Priority Loader::determinePriority(const CachedResource* resource) const
+static ResourceLoadScheduler::Priority determinePriority(const CachedResource* resource)
{
-#if REQUEST_MANAGEMENT_ENABLED
switch (resource->type()) {
case CachedResource::CSSStyleSheet:
#if ENABLE(XSLT)
case CachedResource::XSLStyleSheet:
#endif
- return High;
- case CachedResource::Script:
+ return ResourceLoadScheduler::High;
+ case CachedResource::Script:
case CachedResource::FontResource:
- return Medium;
+ return ResourceLoadScheduler::Medium;
case CachedResource::ImageResource:
- return Low;
+ return ResourceLoadScheduler::Low;
#if ENABLE(LINK_PREFETCH)
case CachedResource::LinkPrefetch:
- return VeryLow;
+ return ResourceLoadScheduler::VeryLow;
#endif
}
ASSERT_NOT_REACHED();
- return Low;
-#else
- return High;
-#endif
+ return ResourceLoadScheduler::Low;
}
void Loader::load(CachedResourceLoader* cachedResourceLoader, CachedResource* resource, bool incremental, SecurityCheckPolicy securityCheck, bool sendResourceLoadCallbacks)
{
- LOG(ResourceLoading, "Loader::load resource %p '%s'", resource, resource->url().latin1().data());
ASSERT(cachedResourceLoader);
Request* request = new Request(cachedResourceLoader, resource, incremental, securityCheck, sendResourceLoadCallbacks);
- RefPtr<Host> host;
- KURL url(ParsedURLString, resource->url());
- if (url.protocolInHTTPFamily()) {
- m_hosts.checkConsistency();
- AtomicString hostName = url.host();
- host = m_hosts.get(hostName.impl());
- if (!host) {
- host = Host::create(hostName, maxRequestsInFlightPerHost);
- m_hosts.add(hostName.impl(), host);
- }
- } else
- host = m_nonHTTPProtocolHost;
-
- bool hadRequests = host->hasRequests();
- Priority priority = determinePriority(resource);
- host->addRequest(request, priority);
cachedResourceLoader->incrementRequestCount(request->cachedResource());
- if (priority > Low || !url.protocolInHTTPFamily() || (priority == Low && !hadRequests)) {
- // Try to request important resources immediately
- host->servePendingRequests(priority);
- } else {
- // Handle asynchronously so early low priority requests don't get scheduled before later high priority ones
- InspectorInstrumentation::didScheduleResourceRequest(cachedResourceLoader->document(), resource->url());
- scheduleServePendingRequests();
- }
-}
-
-void Loader::scheduleServePendingRequests()
-{
- LOG(ResourceLoading, "Loader::scheduleServePendingRequests, m_requestTimer.isActive()=%u", m_requestTimer.isActive());
- if (!m_requestTimer.isActive())
- m_requestTimer.startOneShot(0);
-}
-
-void Loader::requestTimerFired(Timer<Loader>*)
-{
- LOG(ResourceLoading, "Loader::requestTimerFired\n");
- servePendingRequests();
-}
-
-void Loader::servePendingRequests(Priority minimumPriority)
-{
- LOG(ResourceLoading, "Loader::servePendingRequests. m_isSuspendingPendingRequests=%d", m_isSuspendingPendingRequests);
- if (m_isSuspendingPendingRequests)
- return;
-
- m_requestTimer.stop();
-
- m_nonHTTPProtocolHost->servePendingRequests(minimumPriority);
-
- Vector<Host*> hostsToServe;
- m_hosts.checkConsistency();
- HostMap::iterator i = m_hosts.begin();
- HostMap::iterator end = m_hosts.end();
- for (;i != end; ++i)
- hostsToServe.append(i->second.get());
-
- for (unsigned n = 0; n < hostsToServe.size(); ++n) {
- Host* host = hostsToServe[n];
- if (host->hasRequests())
- host->servePendingRequests(minimumPriority);
- else if (!host->processingResource()){
- AtomicString name = host->name();
- m_hosts.remove(name.impl());
+ ResourceRequest resourceRequest(request->cachedResource()->url());
+ resourceRequest.setTargetType(cachedResourceTypeToTargetType(request->cachedResource()->type()));
+
+ if (!request->cachedResource()->accept().isEmpty())
+ resourceRequest.setHTTPAccept(request->cachedResource()->accept());
+
+ if (request->cachedResource()->isCacheValidator()) {
+ CachedResource* resourceToRevalidate = request->cachedResource()->resourceToRevalidate();
+ ASSERT(resourceToRevalidate->canUseCacheValidator());
+ ASSERT(resourceToRevalidate->isLoaded());
+ const String& lastModified = resourceToRevalidate->response().httpHeaderField("Last-Modified");
+ const String& eTag = resourceToRevalidate->response().httpHeaderField("ETag");
+ if (!lastModified.isEmpty() || !eTag.isEmpty()) {
+ ASSERT(cachedResourceLoader->cachePolicy() != CachePolicyReload);
+ if (cachedResourceLoader->cachePolicy() == CachePolicyRevalidate)
+ resourceRequest.setHTTPHeaderField("Cache-Control", "max-age=0");
+ if (!lastModified.isEmpty())
+ resourceRequest.setHTTPHeaderField("If-Modified-Since", lastModified);
+ if (!eTag.isEmpty())
+ resourceRequest.setHTTPHeaderField("If-None-Match", eTag);
}
}
-}
-
-void Loader::suspendPendingRequests()
-{
- ASSERT(!m_isSuspendingPendingRequests);
- m_isSuspendingPendingRequests = true;
-}
-
-void Loader::resumePendingRequests()
-{
- ASSERT(m_isSuspendingPendingRequests);
- m_isSuspendingPendingRequests = false;
- if (!m_hosts.isEmpty() || m_nonHTTPProtocolHost->hasRequests())
- scheduleServePendingRequests();
-}
-
-void Loader::nonCacheRequestInFlight(const KURL& url)
-{
- if (!url.protocolInHTTPFamily())
- return;
-
- AtomicString hostName = url.host();
- m_hosts.checkConsistency();
- RefPtr<Host> host = m_hosts.get(hostName.impl());
- if (!host) {
- host = Host::create(hostName, maxRequestsInFlightPerHost);
- m_hosts.add(hostName.impl(), host);
- }
-
- host->nonCacheRequestInFlight();
-}
-
-void Loader::nonCacheRequestComplete(const KURL& url)
-{
- if (!url.protocolInHTTPFamily())
- return;
- AtomicString hostName = url.host();
- m_hosts.checkConsistency();
- RefPtr<Host> host = m_hosts.get(hostName.impl());
- ASSERT(host);
- if (!host)
- return;
+#if ENABLE(LINK_PREFETCH)
+ if (request->cachedResource()->type() == CachedResource::LinkPrefetch)
+ resourceRequest.setHTTPHeaderField("X-Purpose", "prefetch");
+#endif
- host->nonCacheRequestComplete();
+ RefPtr<SubresourceLoader> loader = resourceLoadScheduler()->scheduleSubresourceLoad(cachedResourceLoader->document()->frame(),
+ this, resourceRequest, determinePriority(resource), request->shouldDoSecurityCheck(), request->sendResourceLoadCallbacks());
+ if (loader) {
+ m_requestsLoading.add(loader.release(), request);
+ request->cachedResource()->setRequestedFromNetworkingLayer();
+ } else {
+ // FIXME: What if resources in other frames were waiting for this revalidation?
+ LOG(ResourceLoading, "Cannot start loading '%s'", request->cachedResource()->url().latin1().data());
+ cachedResourceLoader->decrementRequestCount(request->cachedResource());
+ cachedResourceLoader->setLoadInProgress(true);
+ if (resource->resourceToRevalidate())
+ cache()->revalidationFailed(resource);
+ resource->error();
+ cachedResourceLoader->setLoadInProgress(false);
+ delete request;
+ }
}
void Loader::cancelRequests(CachedResourceLoader* cachedResourceLoader)
{
cachedResourceLoader->clearPendingPreloads();
- if (m_nonHTTPProtocolHost->hasRequests())
- m_nonHTTPProtocolHost->cancelRequests(cachedResourceLoader);
-
- Vector<Host*> hostsToCancel;
- m_hosts.checkConsistency();
- HostMap::iterator i = m_hosts.begin();
- HostMap::iterator end = m_hosts.end();
- for (;i != end; ++i)
- hostsToCancel.append(i->second.get());
-
- for (unsigned n = 0; n < hostsToCancel.size(); ++n) {
- Host* host = hostsToCancel[n];
- if (host->hasRequests())
- host->cancelRequests(cachedResourceLoader);
- }
-
- scheduleServePendingRequests();
-
- ASSERT(cachedResourceLoader->requestCount() == (cachedResourceLoader->loadInProgress() ? 1 : 0));
-}
-
-Loader::Host::Host(const AtomicString& name, unsigned maxRequestsInFlight)
- : m_name(name)
- , m_maxRequestsInFlight(maxRequestsInFlight)
- , m_numResourcesProcessing(0)
- , m_nonCachedRequestsInFlight(0)
-{
-}
-
-Loader::Host::~Host()
-{
- ASSERT(m_requestsLoading.isEmpty());
- for (unsigned p = 0; p <= High; p++)
- ASSERT(m_requestsPending[p].isEmpty());
-}
-
-void Loader::Host::addRequest(Request* request, Priority priority)
-{
- m_requestsPending[priority].append(request);
-}
-
-void Loader::Host::nonCacheRequestInFlight()
-{
- ++m_nonCachedRequestsInFlight;
-}
-
-void Loader::Host::nonCacheRequestComplete()
-{
- --m_nonCachedRequestsInFlight;
- ASSERT(m_nonCachedRequestsInFlight >= 0);
-
- cache()->loader()->scheduleServePendingRequests();
-}
-
-bool Loader::Host::hasRequests() const
-{
- if (!m_requestsLoading.isEmpty())
- return true;
- for (unsigned p = 0; p <= High; p++) {
- if (!m_requestsPending[p].isEmpty())
- return true;
- }
- return false;
-}
-
-void Loader::Host::servePendingRequests(Loader::Priority minimumPriority)
-{
- LOG(ResourceLoading, "Host::servePendingRequests '%s'", m_name.string().latin1().data());
- if (cache()->loader()->isSuspendingPendingRequests()) {
- LOG(ResourceLoading, "...isSuspendingPendingRequests");
- return;
+ Vector<SubresourceLoader*, 256> loadersToCancel;
+ RequestMap::iterator end = m_requestsLoading.end();
+ for (RequestMap::iterator i = m_requestsLoading.begin(); i != end; ++i) {
+ Request* r = i->second;
+ if (r->cachedResourceLoader() == cachedResourceLoader)
+ loadersToCancel.append(i->first.get());
}
- bool serveMore = true;
- for (int priority = High; priority >= minimumPriority && serveMore; --priority)
- servePendingRequests(m_requestsPending[priority], serveMore);
-}
-
-void Loader::Host::servePendingRequests(RequestQueue& requestsPending, bool& serveLowerPriority)
-{
- while (!requestsPending.isEmpty()) {
- Request* request = requestsPending.first();
- CachedResourceLoader* cachedResourceLoader = request->cachedResourceLoader();
- bool resourceIsCacheValidator = request->cachedResource()->isCacheValidator();
-
- // For named hosts - which are only http(s) hosts - we should always enforce the connection limit.
- // For non-named hosts - everything but http(s) - we should only enforce the limit if the document isn't done parsing
- // and we don't know all stylesheets yet.
- bool shouldLimitRequests = !m_name.isNull() || cachedResourceLoader->document()->parsing() || !cachedResourceLoader->document()->haveStylesheetsLoaded();
- if (shouldLimitRequests && m_requestsLoading.size() + m_nonCachedRequestsInFlight >= m_maxRequestsInFlight) {
- serveLowerPriority = false;
- return;
- }
- requestsPending.removeFirst();
-
- ResourceRequest resourceRequest(request->cachedResource()->url());
- resourceRequest.setTargetType(cachedResourceTypeToTargetType(request->cachedResource()->type()));
-
- if (!request->cachedResource()->accept().isEmpty())
- resourceRequest.setHTTPAccept(request->cachedResource()->accept());
-
- // Do not set the referrer or HTTP origin here. That's handled by SubresourceLoader::create.
-
- if (resourceIsCacheValidator) {
- CachedResource* resourceToRevalidate = request->cachedResource()->resourceToRevalidate();
- ASSERT(resourceToRevalidate->canUseCacheValidator());
- ASSERT(resourceToRevalidate->isLoaded());
- const String& lastModified = resourceToRevalidate->response().httpHeaderField("Last-Modified");
- const String& eTag = resourceToRevalidate->response().httpHeaderField("ETag");
- if (!lastModified.isEmpty() || !eTag.isEmpty()) {
- ASSERT(cachedResourceLoader->cachePolicy() != CachePolicyReload);
- if (cachedResourceLoader->cachePolicy() == CachePolicyRevalidate)
- resourceRequest.setHTTPHeaderField("Cache-Control", "max-age=0");
- if (!lastModified.isEmpty())
- resourceRequest.setHTTPHeaderField("If-Modified-Since", lastModified);
- if (!eTag.isEmpty())
- resourceRequest.setHTTPHeaderField("If-None-Match", eTag);
- }
- }
-
-#if ENABLE(LINK_PREFETCH)
- if (request->cachedResource()->type() == CachedResource::LinkPrefetch)
- resourceRequest.setHTTPHeaderField("Purpose", "prefetch");
-#endif
-
- RefPtr<SubresourceLoader> loader = SubresourceLoader::create(cachedResourceLoader->document()->frame(),
- this, resourceRequest, request->shouldDoSecurityCheck(), request->sendResourceLoadCallbacks());
- if (loader) {
- m_requestsLoading.add(loader.release(), request);
- request->cachedResource()->setRequestedFromNetworkingLayer();
- LOG(ResourceLoading, "Host '%s' loading '%s'. Current count %d", m_name.string().latin1().data(), request->cachedResource()->url().latin1().data(), m_requestsLoading.size());
- } else {
- // FIXME: What if resources in other frames were waiting for this revalidation?
- LOG(ResourceLoading, "Host '%s' cannot start loading '%s'", m_name.string().latin1().data(), request->cachedResource()->url().latin1().data());
- CachedResource* resource = request->cachedResource();
- cachedResourceLoader->decrementRequestCount(resource);
- cachedResourceLoader->setLoadInProgress(true);
- if (resource->resourceToRevalidate())
- cache()->revalidationFailed(resource);
- resource->error();
- cachedResourceLoader->setLoadInProgress(false);
- delete request;
- }
+ for (unsigned i = 0; i < loadersToCancel.size(); ++i) {
+ SubresourceLoader* loader = loadersToCancel[i];
+ didFail(loader, true);
}
}
-void Loader::Host::didFinishLoading(SubresourceLoader* loader)
+void Loader::didFinishLoading(SubresourceLoader* loader)
{
- RefPtr<Host> myProtector(this);
-
RequestMap::iterator i = m_requestsLoading.find(loader);
if (i == m_requestsLoading.end())
return;
@@ -412,7 +182,7 @@ void Loader::Host::didFinishLoading(SubresourceLoader* loader)
CachedResource* resource = request->cachedResource();
ASSERT(!resource->resourceToRevalidate());
- LOG(ResourceLoading, "Host '%s' received %s. Current count %d\n", m_name.string().latin1().data(), resource->url().latin1().data(), m_requestsLoading.size());
+ LOG(ResourceLoading, "Received '%s'.", resource->url().latin1().data());
// 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.
@@ -423,23 +193,17 @@ void Loader::Host::didFinishLoading(SubresourceLoader* loader)
}
delete request;
-
- cachedResourceLoader->setLoadInProgress(false);
-
+ cachedResourceLoader->setLoadInProgress(false);
cachedResourceLoader->checkForPendingPreloads();
-
- servePendingRequests();
}
-void Loader::Host::didFail(SubresourceLoader* loader, const ResourceError&)
+void Loader::didFail(SubresourceLoader* loader, const ResourceError&)
{
didFail(loader);
}
-void Loader::Host::didFail(SubresourceLoader* loader, bool cancelled)
+void Loader::didFail(SubresourceLoader* loader, bool cancelled)
{
- RefPtr<Host> myProtector(this);
-
loader->clearClient();
RequestMap::iterator i = m_requestsLoading.find(loader);
@@ -457,7 +221,7 @@ void Loader::Host::didFail(SubresourceLoader* loader, bool cancelled)
CachedResource* resource = request->cachedResource();
- LOG(ResourceLoading, "Host '%s' failed to load %s (cancelled=%d). Current count %d\n", m_name.string().latin1().data(), resource->url().latin1().data(), cancelled, m_requestsLoading.size());
+ LOG(ResourceLoading, "Failed to load '%s' (cancelled=%d).\n", resource->url().latin1().data(), cancelled);
if (resource->resourceToRevalidate())
cache()->revalidationFailed(resource);
@@ -474,14 +238,10 @@ void Loader::Host::didFail(SubresourceLoader* loader, bool cancelled)
delete request;
cachedResourceLoader->checkForPendingPreloads();
-
- servePendingRequests();
}
-void Loader::Host::didReceiveResponse(SubresourceLoader* loader, const ResourceResponse& response)
+void Loader::didReceiveResponse(SubresourceLoader* loader, const ResourceResponse& response)
{
- RefPtr<Host> protector(this);
-
Request* request = m_requestsLoading.get(loader);
// FIXME: This is a workaround for <rdar://problem/5236843>
@@ -510,7 +270,6 @@ void Loader::Host::didReceiveResponse(SubresourceLoader* loader, const ResourceR
delete request;
- servePendingRequests();
return;
}
// Did not get 304 response, continue as a regular resource load.
@@ -541,10 +300,8 @@ void Loader::Host::didReceiveResponse(SubresourceLoader* loader, const ResourceR
}
}
-void Loader::Host::didReceiveData(SubresourceLoader* loader, const char* data, int size)
+void Loader::didReceiveData(SubresourceLoader* loader, const char* data, int size)
{
- RefPtr<Host> protector(this);
-
Request* request = m_requestsLoading.get(loader);
if (!request)
return;
@@ -570,10 +327,8 @@ void Loader::Host::didReceiveData(SubresourceLoader* loader, const char* data, i
resource->data(loader->resourceData(), false);
}
-void Loader::Host::didReceiveCachedMetadata(SubresourceLoader* loader, const char* data, int size)
+void Loader::didReceiveCachedMetadata(SubresourceLoader* loader, const char* data, int size)
{
- RefPtr<Host> protector(this);
-
Request* request = m_requestsLoading.get(loader);
if (!request)
return;
@@ -583,41 +338,5 @@ void Loader::Host::didReceiveCachedMetadata(SubresourceLoader* loader, const cha
resource->setSerializedCachedMetadata(data, size);
}
-
-void Loader::Host::cancelPendingRequests(RequestQueue& requestsPending, CachedResourceLoader* cachedResourceLoader)
-{
- RequestQueue remaining;
- RequestQueue::iterator end = requestsPending.end();
- for (RequestQueue::iterator it = requestsPending.begin(); it != end; ++it) {
- Request* request = *it;
- if (request->cachedResourceLoader() == cachedResourceLoader) {
- cache()->remove(request->cachedResource());
- cachedResourceLoader->decrementRequestCount(request->cachedResource());
- delete request;
- } else
- remaining.append(request);
- }
- requestsPending.swap(remaining);
-}
-
-void Loader::Host::cancelRequests(CachedResourceLoader* cachedResourceLoader)
-{
- for (unsigned p = 0; p <= High; p++)
- cancelPendingRequests(m_requestsPending[p], cachedResourceLoader);
-
- Vector<SubresourceLoader*, 256> loadersToCancel;
-
- RequestMap::iterator end = m_requestsLoading.end();
- for (RequestMap::iterator i = m_requestsLoading.begin(); i != end; ++i) {
- Request* r = i->second;
- if (r->cachedResourceLoader() == cachedResourceLoader)
- loadersToCancel.append(i->first.get());
- }
-
- for (unsigned i = 0; i < loadersToCancel.size(); ++i) {
- SubresourceLoader* loader = loadersToCancel[i];
- didFail(loader, true);
- }
-}
} //namespace WebCore
diff --git a/WebCore/loader/loader.h b/WebCore/loader/loader.h
index 4d353e0..36c8ed3 100644
--- a/WebCore/loader/loader.h
+++ b/WebCore/loader/loader.h
@@ -23,94 +23,35 @@
#define loader_h
#include "FrameLoaderTypes.h"
-#include "PlatformString.h"
+#include "SubresourceLoader.h"
#include "SubresourceLoaderClient.h"
-#include "Timer.h"
-#include <wtf/Deque.h>
#include <wtf/HashMap.h>
#include <wtf/Noncopyable.h>
-#include <wtf/text/AtomicString.h>
-#include <wtf/text/AtomicStringImpl.h>
+#include <wtf/RefPtr.h>
namespace WebCore {
class CachedResource;
class CachedResourceLoader;
- class KURL;
class Request;
- class Loader : public Noncopyable {
+ class Loader : public Noncopyable, private SubresourceLoaderClient {
public:
- Loader();
~Loader();
void load(CachedResourceLoader*, CachedResource*, bool incremental = true, SecurityCheckPolicy = DoSecurityCheck, bool sendResourceLoadCallbacks = true);
-
void cancelRequests(CachedResourceLoader*);
-
- enum Priority { VeryLow, Low, Medium, High };
- void servePendingRequests(Priority minimumPriority = VeryLow);
-
- bool isSuspendingPendingRequests() { return m_isSuspendingPendingRequests; }
- void suspendPendingRequests();
- void resumePendingRequests();
-
- void nonCacheRequestInFlight(const KURL&);
- void nonCacheRequestComplete(const KURL&);
private:
- Priority determinePriority(const CachedResource*) const;
- void scheduleServePendingRequests();
-
- void requestTimerFired(Timer<Loader>*);
-
- class Host : public RefCounted<Host>, private SubresourceLoaderClient {
- public:
- static PassRefPtr<Host> create(const AtomicString& name, unsigned maxRequestsInFlight)
- {
- return adoptRef(new Host(name, maxRequestsInFlight));
- }
- ~Host();
-
- const AtomicString& name() const { return m_name; }
- void addRequest(Request*, Priority);
- void nonCacheRequestInFlight();
- void nonCacheRequestComplete();
- void servePendingRequests(Priority minimumPriority = VeryLow);
- void cancelRequests(CachedResourceLoader*);
- bool hasRequests() const;
-
- bool processingResource() const { return m_numResourcesProcessing != 0 || m_nonCachedRequestsInFlight !=0; }
-
- private:
- Host(const AtomicString&, unsigned);
-
- virtual void didReceiveResponse(SubresourceLoader*, const ResourceResponse&);
- virtual void didReceiveData(SubresourceLoader*, const char*, int);
- virtual void didReceiveCachedMetadata(SubresourceLoader*, const char*, int);
- virtual void didFinishLoading(SubresourceLoader*);
- virtual void didFail(SubresourceLoader*, const ResourceError&);
-
- typedef Deque<Request*> RequestQueue;
- void servePendingRequests(RequestQueue& requestsPending, bool& serveLowerPriority);
- void didFail(SubresourceLoader*, bool cancelled = false);
- void cancelPendingRequests(RequestQueue& requestsPending, CachedResourceLoader*);
-
- RequestQueue m_requestsPending[High + 1];
- typedef HashMap<RefPtr<SubresourceLoader>, Request*> RequestMap;
- RequestMap m_requestsLoading;
- const AtomicString m_name;
- const int m_maxRequestsInFlight;
- int m_numResourcesProcessing;
- int m_nonCachedRequestsInFlight;
- };
- typedef HashMap<AtomicStringImpl*, RefPtr<Host> > HostMap;
- HostMap m_hosts;
- RefPtr<Host> m_nonHTTPProtocolHost;
+ virtual void didReceiveResponse(SubresourceLoader*, const ResourceResponse&);
+ virtual void didReceiveData(SubresourceLoader*, const char*, int);
+ virtual void didReceiveCachedMetadata(SubresourceLoader*, const char*, int);
+ virtual void didFinishLoading(SubresourceLoader*);
+ virtual void didFail(SubresourceLoader*, const ResourceError&);
+ void didFail(SubresourceLoader*, bool cancelled = false);
- Timer<Loader> m_requestTimer;
-
- bool m_isSuspendingPendingRequests;
+ typedef HashMap<RefPtr<SubresourceLoader>, Request*> RequestMap;
+ RequestMap m_requestsLoading;
};
}
diff --git a/WebCore/page/EventSource.cpp b/WebCore/page/EventSource.cpp
index 5e3141d..a7c715a 100644
--- a/WebCore/page/EventSource.cpp
+++ b/WebCore/page/EventSource.cpp
@@ -116,9 +116,6 @@ void EventSource::connect()
m_loader = ThreadableLoader::create(scriptExecutionContext(), this, request, options);
m_requestInFlight = true;
-
- if (!scriptExecutionContext()->isWorkerContext())
- cache()->loader()->nonCacheRequestInFlight(m_url);
}
void EventSource::endRequest()
@@ -128,9 +125,6 @@ void EventSource::endRequest()
if (!m_failSilently)
dispatchEvent(Event::create(eventNames().errorEvent, false, false));
- if (!scriptExecutionContext()->isWorkerContext())
- cache()->loader()->nonCacheRequestComplete(m_url);
-
if (m_state != CLOSED)
scheduleReconnect();
else
diff --git a/WebCore/plugins/PluginStream.cpp b/WebCore/plugins/PluginStream.cpp
index 3be1da5..3bfc536 100644
--- a/WebCore/plugins/PluginStream.cpp
+++ b/WebCore/plugins/PluginStream.cpp
@@ -31,6 +31,7 @@
#include "Frame.h"
#include "FrameLoader.h"
#include "PluginDebug.h"
+#include "ResourceLoadScheduler.h"
#include "SharedBuffer.h"
#include "SubresourceLoader.h"
#include <StringExtras.h>
@@ -93,12 +94,7 @@ PluginStream::~PluginStream()
void PluginStream::start()
{
ASSERT(!m_loadManually);
-
- m_loader = NetscapePlugInStreamLoader::create(m_frame, this);
-
- m_loader->setShouldBufferData(false);
- m_loader->documentLoader()->addPlugInStreamLoader(m_loader.get());
- m_loader->load(m_resourceRequest);
+ m_loader = resourceLoadScheduler()->schedulePluginStreamLoad(m_frame, this, m_resourceRequest);
}
void PluginStream::stop()
diff --git a/WebCore/xml/XMLHttpRequest.cpp b/WebCore/xml/XMLHttpRequest.cpp
index 43ee8a8..782e159 100644
--- a/WebCore/xml/XMLHttpRequest.cpp
+++ b/WebCore/xml/XMLHttpRequest.cpp
@@ -178,7 +178,6 @@ XMLHttpRequest::XMLHttpRequest(ScriptExecutionContext* context)
, m_uploadEventsAllowed(true)
, m_uploadComplete(false)
, m_sameOriginRequest(true)
- , m_didTellLoaderAboutRequest(false)
, m_receivedLength(0)
, m_lastSendLineNumber(0)
, m_exceptionCode(0)
@@ -192,10 +191,6 @@ XMLHttpRequest::XMLHttpRequest(ScriptExecutionContext* context)
XMLHttpRequest::~XMLHttpRequest()
{
- if (m_didTellLoaderAboutRequest) {
- cache()->loader()->nonCacheRequestComplete(m_url);
- m_didTellLoaderAboutRequest = false;
- }
if (m_upload)
m_upload->disconnectXMLHttpRequest();
@@ -598,16 +593,6 @@ void XMLHttpRequest::createRequest(ExceptionCode& ec)
// a request is in progress because we need to keep the listeners alive,
// and they are referenced by the JavaScript wrapper.
setPendingActivity(this);
-
- // For now we should only balance the nonCached request count for main-thread XHRs and not
- // Worker XHRs, as the MemoryCache is not thread-safe.
- // This will become irrelevant after https://bugs.webkit.org/show_bug.cgi?id=27165 is resolved.
- if (!scriptExecutionContext()->isWorkerContext()) {
- ASSERT(isMainThread());
- ASSERT(!m_didTellLoaderAboutRequest);
- cache()->loader()->nonCacheRequestInFlight(m_url);
- m_didTellLoaderAboutRequest = true;
- }
}
} else
ThreadableLoader::loadResourceSynchronously(scriptExecutionContext(), request, *this, options);
@@ -899,10 +884,6 @@ String XMLHttpRequest::statusText(ExceptionCode& ec) const
void XMLHttpRequest::didFail(const ResourceError& error)
{
- if (m_didTellLoaderAboutRequest) {
- cache()->loader()->nonCacheRequestComplete(m_url);
- m_didTellLoaderAboutRequest = false;
- }
// If we are already in an error state, for instance we called abort(), bail out early.
if (m_error)
@@ -929,11 +910,6 @@ void XMLHttpRequest::didFailRedirectCheck()
void XMLHttpRequest::didFinishLoading(unsigned long identifier)
{
- if (m_didTellLoaderAboutRequest) {
- cache()->loader()->nonCacheRequestComplete(m_url);
- m_didTellLoaderAboutRequest = false;
- }
-
if (m_error)
return;
diff --git a/WebCore/xml/XMLHttpRequest.h b/WebCore/xml/XMLHttpRequest.h
index cb4e1cf..1b983e6 100644
--- a/WebCore/xml/XMLHttpRequest.h
+++ b/WebCore/xml/XMLHttpRequest.h
@@ -186,7 +186,6 @@ private:
bool m_uploadComplete;
bool m_sameOriginRequest;
- bool m_didTellLoaderAboutRequest;
// Used for onprogress tracking
long long m_receivedLength;
diff --git a/WebKit/mac/ChangeLog b/WebKit/mac/ChangeLog
index 8d54870..a822a18 100644
--- a/WebKit/mac/ChangeLog
+++ b/WebKit/mac/ChangeLog
@@ -1,3 +1,16 @@
+2010-11-08 Nate Chapin <japhet at chromium.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ Interface changes in https://bugs.webkit.org/show_bug.cgi?id=27165
+
+ * Plugins/Hosted/HostedNetscapePluginStream.mm:
+ (WebKit::HostedNetscapePluginStream::start): Move duplicate code into NetscapePluginStreamLoader
+ * Plugins/WebNetscapePluginStream.mm:
+ (WebNetscapePluginStream::start): Move duplicate code into NetscapePluginStreamLoader
+ * WebView/WebView.mm:
+ (-[WebView _dispatchPendingLoadRequests]): Use resourceLoadScheduler() instead of cache()->loader().
+
2010-11-08 Anders Carlsson <andersca at apple.com>
Reviewed by Dan Bernstein.
diff --git a/WebKit/mac/Plugins/Hosted/HostedNetscapePluginStream.mm b/WebKit/mac/Plugins/Hosted/HostedNetscapePluginStream.mm
index 876a556..937459f 100644
--- a/WebKit/mac/Plugins/Hosted/HostedNetscapePluginStream.mm
+++ b/WebKit/mac/Plugins/Hosted/HostedNetscapePluginStream.mm
@@ -39,6 +39,7 @@
#import <WebCore/DocumentLoader.h>
#import <WebCore/Frame.h>
#import <WebCore/FrameLoader.h>
+#import <WebCore/ResourceLoadScheduler.h>
#import <WebCore/SecurityOrigin.h>
#import <WebCore/WebCoreURLResponse.h>
#import <wtf/RefCountedLeakCounter.h>
@@ -213,11 +214,7 @@ void HostedNetscapePluginStream::start()
ASSERT(!m_frameLoader);
ASSERT(!m_loader);
- m_loader = NetscapePlugInStreamLoader::create(core([m_instance->pluginView() webFrame]), this);
- m_loader->setShouldBufferData(false);
-
- m_loader->documentLoader()->addPlugInStreamLoader(m_loader.get());
- m_loader->load(m_request.get());
+ m_loader = resourceLoadScheduler()->schedulePluginStreamLoad([m_instance->pluginView() webFrame]), this, m_request.get());
}
void HostedNetscapePluginStream::stop()
diff --git a/WebKit/mac/Plugins/WebNetscapePluginStream.mm b/WebKit/mac/Plugins/WebNetscapePluginStream.mm
index f39b104..c677973 100644
--- a/WebKit/mac/Plugins/WebNetscapePluginStream.mm
+++ b/WebKit/mac/Plugins/WebNetscapePluginStream.mm
@@ -42,6 +42,7 @@
#import <WebCore/DocumentLoader.h>
#import <WebCore/Frame.h>
#import <WebCore/FrameLoader.h>
+#import <WebCore/ResourceLoadScheduler.h>
#import <WebCore/SecurityOrigin.h>
#import <WebCore/WebCoreObjCExtras.h>
#import <WebCore/WebCoreURLResponse.h>
@@ -282,11 +283,7 @@ void WebNetscapePluginStream::start()
ASSERT(!m_frameLoader);
ASSERT(!m_loader);
- m_loader = NetscapePlugInStreamLoader::create(core([m_pluginView.get() webFrame]), this);
- m_loader->setShouldBufferData(false);
-
- m_loader->documentLoader()->addPlugInStreamLoader(m_loader.get());
- m_loader->load(m_request.get());
+ m_loader = resourceLoadScheduler()->schedulePluginStreamLoad(core([m_pluginView.get() webFrame]), this, m_request.get());
}
void WebNetscapePluginStream::stop()
diff --git a/WebKit/mac/WebView/WebView.mm b/WebKit/mac/WebView/WebView.mm
index 49bb451..4687cda 100644
--- a/WebKit/mac/WebView/WebView.mm
+++ b/WebKit/mac/WebView/WebView.mm
@@ -147,6 +147,7 @@
#import <WebCore/RenderView.h>
#import <WebCore/RenderWidget.h>
#import <WebCore/ResourceHandle.h>
+#import <WebCore/ResourceLoadScheduler.h>
#import <WebCore/RuntimeApplicationChecks.h>
#import <WebCore/SchemeRegistry.h>
#import <WebCore/ScriptController.h>
@@ -621,7 +622,7 @@ static bool shouldEnableLoadDeferring()
- (void)_dispatchPendingLoadRequests
{
- cache()->loader()->servePendingRequests();
+ resourceLoadScheduler()->servePendingRequests();
}
- (void)_registerDraggedTypes
diff --git a/WebKit2/ChangeLog b/WebKit2/ChangeLog
index c4859a7..d4c3907 100644
--- a/WebKit2/ChangeLog
+++ b/WebKit2/ChangeLog
@@ -1,3 +1,13 @@
+2010-11-08 Nate Chapin <japhet at chromium.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ Function call update for
+ https://bugs.webkit.org/show_bug.cgi?id=27165.
+
+ * WebProcess/Plugins/PluginView.cpp:
+ (WebKit::PluginView::Stream::start):
+
2010-11-08 Anders Carlsson <andersca at apple.com>
Reviewed by Adam Roben.
diff --git a/WebKit2/WebProcess/Plugins/PluginView.cpp b/WebKit2/WebProcess/Plugins/PluginView.cpp
index 0219c73..42721f4 100644
--- a/WebKit2/WebProcess/Plugins/PluginView.cpp
+++ b/WebKit2/WebProcess/Plugins/PluginView.cpp
@@ -45,6 +45,7 @@
#include <WebCore/ProxyServer.h>
#include <WebCore/RenderEmbeddedObject.h>
#include <WebCore/RenderLayer.h>
+#include <WebCore/ResourceLoadScheduler.h>
#include <WebCore/ScrollView.h>
#include <WebCore/Settings.h>
@@ -129,11 +130,7 @@ void PluginView::Stream::start()
Frame* frame = m_pluginView->m_pluginElement->document()->frame();
ASSERT(frame);
- m_loader = NetscapePlugInStreamLoader::create(frame, this);
- m_loader->setShouldBufferData(false);
-
- m_loader->documentLoader()->addPlugInStreamLoader(m_loader.get());
- m_loader->load(m_request);
+ m_loader = resourceLoadScheduler()->schedulePluginStreamLoad(frame, this, m_request);
}
void PluginView::Stream::cancel()
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list