diff options
author | Leon Clarke <leonclarke@google.com> | 2010-03-09 14:12:21 +0000 |
---|---|---|
committer | Leon Clarke <leonclarke@google.com> | 2010-05-04 10:59:37 +0100 |
commit | f91ac8eab3399adb5325701bebe0590a77e49df7 (patch) | |
tree | 04ff055963cf2bfe147998ca3396134b243be38d /WebCore/loader | |
parent | b97e8541004c77ec0c85f74b896b9d3bdb6de6b4 (diff) | |
download | external_webkit-f91ac8eab3399adb5325701bebe0590a77e49df7.zip external_webkit-f91ac8eab3399adb5325701bebe0590a77e49df7.tar.gz external_webkit-f91ac8eab3399adb5325701bebe0590a77e49df7.tar.bz2 |
Link prefetch support
http://b/issue?id=2268353
Diffstat (limited to 'WebCore/loader')
-rw-r--r-- | WebCore/loader/Cache.cpp | 7 | ||||
-rw-r--r-- | WebCore/loader/CachedCSSStyleSheet.cpp | 8 | ||||
-rw-r--r-- | WebCore/loader/CachedLinkPrefetch.h | 67 | ||||
-rw-r--r-- | WebCore/loader/CachedResource.h | 4 | ||||
-rw-r--r-- | WebCore/loader/DocLoader.cpp | 26 | ||||
-rw-r--r-- | WebCore/loader/DocLoader.h | 10 | ||||
-rw-r--r-- | WebCore/loader/loader.cpp | 31 | ||||
-rw-r--r-- | WebCore/loader/loader.h | 6 |
8 files changed, 143 insertions, 16 deletions
diff --git a/WebCore/loader/Cache.cpp b/WebCore/loader/Cache.cpp index fdd9b25..5f4d0e7 100644 --- a/WebCore/loader/Cache.cpp +++ b/WebCore/loader/Cache.cpp @@ -38,6 +38,9 @@ #include "SecurityOrigin.h" #include <stdio.h> #include <wtf/CurrentTime.h> +#if ENABLE(LINK_PREFETCH) +#include "CachedLinkPrefetch.h" +#endif using namespace std; @@ -86,6 +89,10 @@ static CachedResource* createResource(CachedResource::Type type, const KURL& url case CachedResource::XBLStyleSheet: return new CachedXBLDocument(url.string()); #endif +#if ENABLE(LINK_PREFETCH) + case CachedResource::LinkPrefetch: + return new CachedLinkPrefetch(url.string()); +#endif default: break; } diff --git a/WebCore/loader/CachedCSSStyleSheet.cpp b/WebCore/loader/CachedCSSStyleSheet.cpp index b2e03b9..3fc28ff 100644 --- a/WebCore/loader/CachedCSSStyleSheet.cpp +++ b/WebCore/loader/CachedCSSStyleSheet.cpp @@ -51,8 +51,10 @@ CachedCSSStyleSheet::~CachedCSSStyleSheet() void CachedCSSStyleSheet::didAddClient(CachedResourceClient *c) { - if (!m_loading) + if (!m_loading) { c->setCSSStyleSheet(m_url, m_response.url(), m_decoder->encoding().name(), this); + c->notifyFinished(this); + } } void CachedCSSStyleSheet::allClientsRemoved() @@ -103,6 +105,10 @@ void CachedCSSStyleSheet::data(PassRefPtr<SharedBuffer> data, bool allDataReceiv checkNotify(); // Clear the decoded text as it is unlikely to be needed immediately again and is cheap to regenerate. m_decodedSheetText = String(); + + CachedResourceClientWalker w(m_clients); + while (CachedResourceClient* c = w.next()) + c->notifyFinished(this); } void CachedCSSStyleSheet::checkNotify() diff --git a/WebCore/loader/CachedLinkPrefetch.h b/WebCore/loader/CachedLinkPrefetch.h new file mode 100644 index 0000000..4ffa5fe --- /dev/null +++ b/WebCore/loader/CachedLinkPrefetch.h @@ -0,0 +1,67 @@ +/* + * Copyright 2010, The Android Open Source Project + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + +#ifndef CachedLinkPrefetch_h +#define CachedLinkPrefetch_h + +#include "CachedResource.h" +#include "CachedResourceClient.h" +#include "CachedResourceClientWalker.h" + +namespace WebCore { + +class DocLoader; + +class CachedLinkPrefetch : public CachedResource { +public: + CachedLinkPrefetch(const String& URL) : CachedResource(URL, LinkPrefetch) { }; + virtual ~CachedLinkPrefetch() { }; + + virtual void didAddClient(CachedResourceClient* c) { + if (!m_loading) + c->notifyFinished(this); + }; + + virtual void data(PassRefPtr<SharedBuffer> data, bool allDataReceived) { + if (!allDataReceived) + return; + + m_data = data; + + CachedResourceClientWalker w(m_clients); + while (CachedResourceClient* c = w.next()) + c->notifyFinished(this); + }; + virtual void error() { }; + + virtual bool schedule() const { return true; } + + virtual bool isPrefetch() const { return true; } +}; +} + +#endif + diff --git a/WebCore/loader/CachedResource.h b/WebCore/loader/CachedResource.h index 0f46a62..bad632b 100644 --- a/WebCore/loader/CachedResource.h +++ b/WebCore/loader/CachedResource.h @@ -63,6 +63,9 @@ public: #if ENABLE(XBL) , XBL #endif +#if ENABLE(LINK_PREFETCH) + , LinkPrefetch +#endif }; enum Status { @@ -118,6 +121,7 @@ public: void setLoading(bool b) { m_loading = b; } virtual bool isImage() const { return false; } + virtual bool isPrefetch() const { return false; } unsigned accessCount() const { return m_accessCount; } void increaseAccessCount() { m_accessCount++; } diff --git a/WebCore/loader/DocLoader.cpp b/WebCore/loader/DocLoader.cpp index 8c0a1b2..08dfa33 100644 --- a/WebCore/loader/DocLoader.cpp +++ b/WebCore/loader/DocLoader.cpp @@ -44,6 +44,9 @@ #include "loader.h" #include "SecurityOrigin.h" #include "Settings.h" +#if ENABLE(LINK_PREFETCH) +#include "CachedLinkPrefetch.h" +#endif #define PRELOAD_DEBUG 0 @@ -176,6 +179,13 @@ CachedXBLDocument* DocLoader::requestXBLDocument(const String& url) } #endif +#if ENABLE(LINK_PREFETCH) +CachedLinkPrefetch* DocLoader::requestLinkPrefetch(const String& url) +{ + return static_cast<CachedLinkPrefetch*>(requestResource(CachedResource::LinkPrefetch, url, String())); +} +#endif + bool DocLoader::canRequest(CachedResource::Type type, const KURL& url) { // Some types of resources can be loaded only from the same origin. Other @@ -186,6 +196,9 @@ bool DocLoader::canRequest(CachedResource::Type type, const KURL& url) case CachedResource::CSSStyleSheet: case CachedResource::Script: case CachedResource::FontResource: +#if ENABLE(LINK_PREFETCH) + case CachedResource::LinkPrefetch: +#endif // These types of resources can be loaded from any origin. // FIXME: Are we sure about CachedResource::FontResource? break; @@ -228,6 +241,9 @@ bool DocLoader::canRequest(CachedResource::Type type, const KURL& url) break; case CachedResource::ImageResource: case CachedResource::CSSStyleSheet: +#if ENABLE(LINK_PREFETCH) + case CachedResource::LinkPrefetch: +#endif case CachedResource::FontResource: { // These resources can corrupt only the frame's pixels. if (Frame* f = frame()) { @@ -402,13 +418,19 @@ void DocLoader::checkCacheObjectStatus(CachedResource* resource) frame()->loader()->loadedResourceFromMemoryCache(resource); } -void DocLoader::incrementRequestCount() +void DocLoader::incrementRequestCount(const CachedResource* res) { + if (res->isPrefetch()) + return; + ++m_requestCount; } -void DocLoader::decrementRequestCount() +void DocLoader::decrementRequestCount(const CachedResource* res) { + if (res->isPrefetch()) + return; + --m_requestCount; ASSERT(m_requestCount > -1); } diff --git a/WebCore/loader/DocLoader.h b/WebCore/loader/DocLoader.h index 06d8a47..2f8f639 100644 --- a/WebCore/loader/DocLoader.h +++ b/WebCore/loader/DocLoader.h @@ -45,6 +45,9 @@ class Document; class Frame; class ImageLoader; class KURL; +#if ENABLE(LINK_PREFETCH) +class CachedLinkPrefetch; +#endif // The DocLoader manages the loading of scripts/images/stylesheets for a single document. class DocLoader : public Noncopyable @@ -68,6 +71,9 @@ public: #if ENABLE(XBL) CachedXBLDocument* requestXBLDocument(const String &url); #endif +#if ENABLE(LINK_PREFETCH) + CachedLinkPrefetch* requestLinkPrefetch(const String &url); +#endif // Logs an access denied message to the console for the specified URL. void printAccessDeniedMessage(const KURL& url) const; @@ -98,8 +104,8 @@ public: void setAllowStaleResources(bool allowStaleResources) { m_allowStaleResources = allowStaleResources; } - void incrementRequestCount(); - void decrementRequestCount(); + void incrementRequestCount(const CachedResource*); + void decrementRequestCount(const CachedResource*); int requestCount(); void clearPreloads(); diff --git a/WebCore/loader/loader.cpp b/WebCore/loader/loader.cpp index 4d2b474..24f141f 100644 --- a/WebCore/loader/loader.cpp +++ b/WebCore/loader/loader.cpp @@ -88,7 +88,12 @@ static ResourceRequest::TargetType cachedResourceTypeToTargetType(CachedResource return ResourceRequest::TargetIsFontResource; case CachedResource::ImageResource: return ResourceRequest::TargetIsImage; +#if ENABLE(LINK_PREFETCH) + case CachedResource::LinkPrefetch: + return ResourceRequest::TargetIsSubresource; +#endif } + ASSERT_NOT_REACHED(); return ResourceRequest::TargetIsSubresource; } @@ -109,6 +114,10 @@ Loader::Priority Loader::determinePriority(const CachedResource* resource) const return Medium; case CachedResource::ImageResource: return Low; +#if ENABLE(LINK_PREFETCH) + case CachedResource::LinkPrefetch: + return VeryLow; +#endif } ASSERT_NOT_REACHED(); return Low; @@ -138,9 +147,9 @@ void Loader::load(DocLoader* docLoader, CachedResource* resource, bool increment bool hadRequests = host->hasRequests(); Priority priority = determinePriority(resource); host->addRequest(request, priority); - docLoader->incrementRequestCount(); + docLoader->incrementRequestCount(request->cachedResource()); - if (priority > Low || !url.protocolInHTTPFamily() || !hadRequests) { + if (priority > Low || !url.protocolInHTTPFamily() || (priority == Low && !hadRequests)) { // Try to request important resources immediately host->servePendingRequests(priority); } else { @@ -352,6 +361,12 @@ void Loader::Host::servePendingRequests(RequestQueue& requestsPending, bool& ser } } +#if ENABLE(LINK_PREFETCH) + if (request->cachedResource()->type() == CachedResource::LinkPrefetch) { + resourceRequest.setHTTPHeaderField("X-Moz", "prefetch"); + } +#endif + RefPtr<SubresourceLoader> loader = SubresourceLoader::create(docLoader->doc()->frame(), this, resourceRequest, request->shouldDoSecurityCheck(), request->sendResourceLoadCallbacks()); if (loader) { @@ -361,7 +376,7 @@ void Loader::Host::servePendingRequests(RequestQueue& requestsPending, bool& ser printf("HOST %s COUNT %d LOADING %s\n", resourceRequest.url().host().latin1().data(), m_requestsLoading.size(), request->cachedResource()->url().latin1().data()); #endif } else { - docLoader->decrementRequestCount(); + docLoader->decrementRequestCount(request->cachedResource()); docLoader->setLoadInProgress(true); request->cachedResource()->error(); docLoader->setLoadInProgress(false); @@ -385,7 +400,7 @@ void Loader::Host::didFinishLoading(SubresourceLoader* loader) // the docLoader that it will delete when the document gets deleted. RefPtr<Document> protector(docLoader->doc()); if (!request->isMultipart()) - docLoader->decrementRequestCount(); + docLoader->decrementRequestCount(request->cachedResource()); CachedResource* resource = request->cachedResource(); ASSERT(!resource->resourceToRevalidate()); @@ -433,7 +448,7 @@ void Loader::Host::didFail(SubresourceLoader* loader, bool cancelled) // the docLoader that it will delete when the document gets deleted. RefPtr<Document> protector(docLoader->doc()); if (!request->isMultipart()) - docLoader->decrementRequestCount(); + docLoader->decrementRequestCount(request->cachedResource()); CachedResource* resource = request->cachedResource(); @@ -478,7 +493,7 @@ void Loader::Host::didReceiveResponse(SubresourceLoader* loader, const ResourceR // 304 Not modified / Use local copy m_requestsLoading.remove(loader); loader->clearClient(); - request->docLoader()->decrementRequestCount(); + request->docLoader()->decrementRequestCount(request->cachedResource()); // Existing resource is ok, just use it updating the expiration time. cache()->revalidationSucceeded(resource, response); @@ -510,7 +525,7 @@ void Loader::Host::didReceiveResponse(SubresourceLoader* loader, const ResourceR request->setIsMultipart(true); // We don't count multiParts in a DocLoader's request count - request->docLoader()->decrementRequestCount(); + request->docLoader()->decrementRequestCount(request->cachedResource()); // If we get a multipart response, we must have a handle ASSERT(loader->handle()); @@ -559,7 +574,7 @@ void Loader::Host::cancelPendingRequests(RequestQueue& requestsPending, DocLoade if (request->docLoader() == docLoader) { cache()->remove(request->cachedResource()); delete request; - docLoader->decrementRequestCount(); + docLoader->decrementRequestCount(request->cachedResource()); } else remaining.append(request); } diff --git a/WebCore/loader/loader.h b/WebCore/loader/loader.h index a9de032..9393a60 100644 --- a/WebCore/loader/loader.h +++ b/WebCore/loader/loader.h @@ -48,8 +48,8 @@ namespace WebCore { void cancelRequests(DocLoader*); - enum Priority { Low, Medium, High }; - void servePendingRequests(Priority minimumPriority = Low); + enum Priority { VeryLow, Low, Medium, High }; + void servePendingRequests(Priority minimumPriority = VeryLow); bool isSuspendingPendingRequests() { return m_isSuspendingPendingRequests; } void suspendPendingRequests(); @@ -76,7 +76,7 @@ namespace WebCore { void addRequest(Request*, Priority); void nonCacheRequestInFlight(); void nonCacheRequestComplete(); - void servePendingRequests(Priority minimumPriority = Low); + void servePendingRequests(Priority minimumPriority = VeryLow); void cancelRequests(DocLoader*); bool hasRequests() const; |