[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