Changeset 36109 in webkit


Ignore:
Timestamp:
Sep 5, 2008 2:28:11 AM (16 years ago)
Author:
Antti Koivisto
Message:

2008-09-05 Antti Koivisto <Antti Koivisto>

Reviewed by Darin.

Most of the implementation for https://bugs.webkit.org/show_bug.cgi?id=17998
When a resource is cached locally, WebKit should follow RFC 2616 "Specific end-to-end revalidation" instead of "Unspecified end-to-end revalidation"

Implement HTTP 1.1 "Specific end-to-end revalidation" for WebCore memory cache. This patch does
not yet enable it for the biggest use case, reloading. However it is good for general browsing as
well. Doing this in WebCore level as opposed to relying on disk cache has big benefit that
we avoid re-decoding resources, especially images.


To be exact the enabled case is not actually the "Specific end-to-end revalidation" since it does not include
CacheControl: max-age=0 header. That would be added in reload case.


The approach for revalidation is to kick the original resource out from the memory cache
and create a new CachedResource that represents the revalidation request. In case
we get 304 back for the request we put the original resource back to the cache, update
its expiration date and switch the clients registered to revalidation resource to be
clients of the original resource.


All heap allocated CachedImage pointers now use CachedResourceHandle<CachedImage> (and so on) instead.
This allows updating the handles to point to the original resource when the revalidation succeeds. It
also acts as refcounting smart pointer.

  • WebCore.pro:
  • WebCore.vcproj/WebCore.vcproj:
  • WebCore.xcodeproj/project.pbxproj:
  • css/CSSFontFaceSource.h:
  • css/CSSImportRule.h:
  • dom/Clipboard.h: (WebCore::Clipboard::dragImage):
  • dom/ProcessingInstruction.h:
  • dom/ScriptElement.h:
  • dom/XMLTokenizer.cpp: (WebCore::XMLTokenizer::isWaitingForScripts):
  • dom/XMLTokenizer.h:
  • html/HTMLImageLoader.cpp: (WebCore::HTMLImageLoader::setImage): (WebCore::HTMLImageLoader::updateFromElement): (WebCore::HTMLImageLoader::notifyFinished):
  • html/HTMLImageLoader.h: (WebCore::HTMLImageLoader::image):
  • html/HTMLLinkElement.h:
  • html/HTMLTokenizer.cpp: (WebCore::HTMLTokenizer::reset): (WebCore::HTMLTokenizer::scriptHandler): (WebCore::HTMLTokenizer::notifyFinished):
  • html/HTMLTokenizer.h:
  • loader/Cache.cpp: (WebCore::Cache::revalidateResource): (WebCore::Cache::revalidationSucceeded): (WebCore::Cache::revalidationFailed):
  • loader/Cache.h:
  • loader/CachedResource.cpp: (WebCore::CachedResource::CachedResource): (WebCore::CachedResource::~CachedResource): (WebCore::CachedResource::isExpired): (WebCore::CachedResource::setResponse): (WebCore::CachedResource::deleteIfPossible): (WebCore::CachedResource::setResourceToRevalidate): (WebCore::CachedResource::clearResourceToRevalidate): (WebCore::CachedResource::switchClientsToRevalidatedResource): (WebCore::CachedResource::canUseCacheValidator): (WebCore::CachedResource::mustRevalidate):
  • loader/CachedResource.h: (WebCore::CachedResource::canDelete): (WebCore::CachedResource::registerHandle): (WebCore::CachedResource::unregisterHandle): (WebCore::CachedResource::isCacheValidator): (WebCore::CachedResource::resourceToRevalidate): (WebCore::CachedResource::setExpirationDate):
  • loader/CachedResourceHandle.cpp: Added. (WebCore::CachedResourceHandleBase::setResource):
  • loader/CachedResourceHandle.h: Added. (WebCore::CachedResourceHandleBase::~CachedResourceHandleBase): (WebCore::CachedResourceHandleBase::get): (WebCore::CachedResourceHandleBase::operator!): (WebCore::CachedResourceHandleBase::operator UnspecifiedBoolType): (WebCore::CachedResourceHandleBase::CachedResourceHandleBase): (WebCore::CachedResourceHandleBase::operator=): (WebCore::CachedResourceHandle::CachedResourceHandle): (WebCore::CachedResourceHandle::get): (WebCore::CachedResourceHandle::operator->): (WebCore::CachedResourceHandle::operator=): (WebCore::CachedResourceHandle::operator==): (WebCore::CachedResourceHandle::operator!=): (WebCore::operator==): (WebCore::operator!=):
  • loader/DocLoader.cpp: (WebCore::DocLoader::checkForReload):
  • loader/UserStyleSheetLoader.h:
  • loader/loader.cpp: (WebCore::Loader::Host::servePendingRequests): (WebCore::Loader::Host::didFinishLoading): (WebCore::Loader::Host::didFail): (WebCore::Loader::Host::didReceiveResponse): (WebCore::Loader::Host::didReceiveData):
  • page/EventHandler.cpp: (WebCore::EventHandler::selectCursor):
  • rendering/RenderImage.cpp: (WebCore::RenderImage::setCachedImage): (WebCore::RenderImage::imageChanged):
  • rendering/RenderImage.h: (WebCore::RenderImage::cachedImage): (WebCore::RenderImage::imagePtr):
  • rendering/style/RenderStyle.h:
  • rendering/style/StyleCachedImage.h: (WebCore::StyleCachedImage::data): (WebCore::StyleCachedImage::cachedImage):
  • svg/SVGFEImageElement.h:
  • svg/graphics/filters/SVGFEImage.h:
  • xml/XSLImportRule.h:
Location:
trunk/WebCore
Files:
2 added
31 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r36108 r36109  
     12008-09-05  Antti Koivisto  <antti@apple.com>
     2
     3        Reviewed by Darin.
     4
     5        Most of the implementation for https://bugs.webkit.org/show_bug.cgi?id=17998
     6        When a resource is cached locally, WebKit should follow RFC 2616 "Specific end-to-end revalidation" instead of "Unspecified end-to-end revalidation"
     7
     8        Implement HTTP 1.1 "Specific end-to-end revalidation" for WebCore memory cache. This patch does
     9        not yet enable it for the biggest use case, reloading. However it is good for general browsing as
     10        well. Doing this in WebCore level as opposed to relying on disk cache has big benefit that
     11        we avoid re-decoding resources, especially images.
     12       
     13        To be exact the enabled case is not actually the "Specific end-to-end revalidation" since it does not include
     14        CacheControl: max-age=0 header. That would be added in reload case.
     15       
     16        The approach for revalidation is to kick the original resource out from the memory cache
     17        and create a new CachedResource that represents the revalidation request. In case
     18        we get 304 back for the request we put the original resource back to the cache, update
     19        its expiration date and switch the clients registered to revalidation resource to be
     20        clients of the original resource.
     21       
     22        All heap allocated CachedImage pointers now use CachedResourceHandle<CachedImage> (and so on) instead.
     23        This allows updating the handles to point to the original resource when the revalidation succeeds. It
     24        also acts as refcounting smart pointer.
     25
     26        * WebCore.pro:
     27        * WebCore.vcproj/WebCore.vcproj:
     28        * WebCore.xcodeproj/project.pbxproj:
     29        * css/CSSFontFaceSource.h:
     30        * css/CSSImportRule.h:
     31        * dom/Clipboard.h:
     32        (WebCore::Clipboard::dragImage):
     33        * dom/ProcessingInstruction.h:
     34        * dom/ScriptElement.h:
     35        * dom/XMLTokenizer.cpp:
     36        (WebCore::XMLTokenizer::isWaitingForScripts):
     37        * dom/XMLTokenizer.h:
     38        * html/HTMLImageLoader.cpp:
     39        (WebCore::HTMLImageLoader::setImage):
     40        (WebCore::HTMLImageLoader::updateFromElement):
     41        (WebCore::HTMLImageLoader::notifyFinished):
     42        * html/HTMLImageLoader.h:
     43        (WebCore::HTMLImageLoader::image):
     44        * html/HTMLLinkElement.h:
     45        * html/HTMLTokenizer.cpp:
     46        (WebCore::HTMLTokenizer::reset):
     47        (WebCore::HTMLTokenizer::scriptHandler):
     48        (WebCore::HTMLTokenizer::notifyFinished):
     49        * html/HTMLTokenizer.h:
     50        * loader/Cache.cpp:
     51        (WebCore::Cache::revalidateResource):
     52        (WebCore::Cache::revalidationSucceeded):
     53        (WebCore::Cache::revalidationFailed):
     54        * loader/Cache.h:
     55        * loader/CachedResource.cpp:
     56        (WebCore::CachedResource::CachedResource):
     57        (WebCore::CachedResource::~CachedResource):
     58        (WebCore::CachedResource::isExpired):
     59        (WebCore::CachedResource::setResponse):
     60        (WebCore::CachedResource::deleteIfPossible):
     61        (WebCore::CachedResource::setResourceToRevalidate):
     62        (WebCore::CachedResource::clearResourceToRevalidate):
     63        (WebCore::CachedResource::switchClientsToRevalidatedResource):
     64        (WebCore::CachedResource::canUseCacheValidator):
     65        (WebCore::CachedResource::mustRevalidate):
     66        * loader/CachedResource.h:
     67        (WebCore::CachedResource::canDelete):
     68        (WebCore::CachedResource::registerHandle):
     69        (WebCore::CachedResource::unregisterHandle):
     70        (WebCore::CachedResource::isCacheValidator):
     71        (WebCore::CachedResource::resourceToRevalidate):
     72        (WebCore::CachedResource::setExpirationDate):
     73        * loader/CachedResourceHandle.cpp: Added.
     74        (WebCore::CachedResourceHandleBase::setResource):
     75        * loader/CachedResourceHandle.h: Added.
     76        (WebCore::CachedResourceHandleBase::~CachedResourceHandleBase):
     77        (WebCore::CachedResourceHandleBase::get):
     78        (WebCore::CachedResourceHandleBase::operator!):
     79        (WebCore::CachedResourceHandleBase::operator UnspecifiedBoolType):
     80        (WebCore::CachedResourceHandleBase::CachedResourceHandleBase):
     81        (WebCore::CachedResourceHandleBase::operator=):
     82        (WebCore::CachedResourceHandle::CachedResourceHandle):
     83        (WebCore::CachedResourceHandle::get):
     84        (WebCore::CachedResourceHandle::operator->):
     85        (WebCore::CachedResourceHandle::operator=):
     86        (WebCore::CachedResourceHandle::operator==):
     87        (WebCore::CachedResourceHandle::operator!=):
     88        (WebCore::operator==):
     89        (WebCore::operator!=):
     90        * loader/DocLoader.cpp:
     91        (WebCore::DocLoader::checkForReload):
     92        * loader/UserStyleSheetLoader.h:
     93        * loader/loader.cpp:
     94        (WebCore::Loader::Host::servePendingRequests):
     95        (WebCore::Loader::Host::didFinishLoading):
     96        (WebCore::Loader::Host::didFail):
     97        (WebCore::Loader::Host::didReceiveResponse):
     98        (WebCore::Loader::Host::didReceiveData):
     99        * page/EventHandler.cpp:
     100        (WebCore::EventHandler::selectCursor):
     101        * rendering/RenderImage.cpp:
     102        (WebCore::RenderImage::setCachedImage):
     103        (WebCore::RenderImage::imageChanged):
     104        * rendering/RenderImage.h:
     105        (WebCore::RenderImage::cachedImage):
     106        (WebCore::RenderImage::imagePtr):
     107        * rendering/style/RenderStyle.h:
     108        * rendering/style/StyleCachedImage.h:
     109        (WebCore::StyleCachedImage::data):
     110        (WebCore::StyleCachedImage::cachedImage):
     111        * svg/SVGFEImageElement.h:
     112        * svg/graphics/filters/SVGFEImage.h:
     113        * xml/XSLImportRule.h:
     114
    11152008-09-04  Brady Eidson  <beidson@apple.com>
    2116
  • trunk/WebCore/WebCore.pro

    r36089 r36109  
    702702    loader/CachedImage.cpp \
    703703    loader/CachedResourceClientWalker.cpp \
     704    loader/CachedResourceHandle.cpp \
    704705    loader/CachedResource.cpp \
    705706    loader/CachedScript.cpp \
  • trunk/WebCore/WebCore.vcproj/WebCore.vcproj

    r36091 r36109  
    27892789                        </File>
    27902790                        <File
     2791                                RelativePath="..\loader\CachedResourceHandle.cpp"
     2792                                >
     2793                        </File>
     2794                        <File
     2795                                RelativePath="..\loader\CachedResourceHandle.h"
     2796                                >
     2797                        </File>
     2798                        <File
    27912799                                RelativePath="..\loader\CachedScript.cpp"
    27922800                                >
  • trunk/WebCore/WebCore.xcodeproj/project.pbxproj

    r36088 r36109  
    40864086                E44614510CD68A3500FADA75 /* RenderVideo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4B41E330CBFB60900AF2ECE /* RenderVideo.cpp */; };
    40874087                E44614520CD68A3500FADA75 /* RenderVideo.h in Headers */ = {isa = PBXBuildFile; fileRef = E4B41E340CBFB60900AF2ECE /* RenderVideo.h */; };
     4088                E47B4BE80E71241600038854 /* CachedResourceHandle.h in Headers */ = {isa = PBXBuildFile; fileRef = E47B4BE60E71241600038854 /* CachedResourceHandle.h */; };
     4089                E47B4BE90E71241600038854 /* CachedResourceHandle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E47B4BE70E71241600038854 /* CachedResourceHandle.cpp */; };
    40884090                E49626C20D80D94800E3405C /* PreloadScanner.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4D4ABE00D7542F000F96869 /* PreloadScanner.cpp */; };
    40894091                E49626C30D80D94900E3405C /* PreloadScanner.h in Headers */ = {isa = PBXBuildFile; fileRef = E4D4ABE10D7542F100F96869 /* PreloadScanner.h */; };
     
    85298531                E44614120CD6826900FADA75 /* JSTimeRanges.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSTimeRanges.cpp; sourceTree = "<group>"; };
    85308532                E44614130CD6826900FADA75 /* JSTimeRanges.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSTimeRanges.h; sourceTree = "<group>"; };
     8533                E472053A0E5A053A0006BB4D /* CachedResourceHandle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CachedResourceHandle.h; sourceTree = "<group>"; };
     8534                E47B4BE60E71241600038854 /* CachedResourceHandle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CachedResourceHandle.h; sourceTree = "<group>"; };
     8535                E47B4BE70E71241600038854 /* CachedResourceHandle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CachedResourceHandle.cpp; sourceTree = "<group>"; };
    85318536                E4AFCFA40DAF29A300F5F55C /* UnitBezier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnitBezier.h; sourceTree = "<group>"; };
    85328537                E4AFD0050DAF335400F5F55C /* SMILTime.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SMILTime.cpp; sourceTree = "<group>"; };
     
    1270812713                                BCB16C080979C3BD00467741 /* CachedResourceClientWalker.cpp */,
    1270912714                                BCB16C090979C3BD00467741 /* CachedResourceClientWalker.h */,
     12715                                E47B4BE60E71241600038854 /* CachedResourceHandle.h */,
     12716                                E47B4BE70E71241600038854 /* CachedResourceHandle.cpp */,
    1271012717                                BCB16C0A0979C3BD00467741 /* CachedScript.cpp */,
    1271112718                                BCB16C0B0979C3BD00467741 /* CachedScript.h */,
     
    1271412721                                BCB16C0E0979C3BD00467741 /* CachedXSLStyleSheet.cpp */,
    1271512722                                BCB16C0F0979C3BD00467741 /* CachedXSLStyleSheet.h */,
     12723                                E472053A0E5A053A0006BB4D /* CachedResourceHandle.h */,
    1271612724                                F587864902DE3A9A01EA4122 /* CachePolicy.h */,
    1271712725                                BCB16C100979C3BD00467741 /* DocLoader.cpp */,
     
    1555015558                                316FE0820E6CCC2800BF6088 /* DOMWebKitCSSKeyframesRuleInternal.h in Headers */,
    1555115559                                7284ADDE0E6FEB31002EEFBD /* UserStyleSheetLoader.h in Headers */,
     15560                                E47B4BE80E71241600038854 /* CachedResourceHandle.h in Headers */,
    1555215561                        );
    1555315562                        runOnlyForDeploymentPostprocessing = 0;
     
    1734917358                                316FE0810E6CCC2800BF6088 /* DOMWebKitCSSKeyframesRule.mm in Sources */,
    1735017359                                7284ADDD0E6FEB31002EEFBD /* UserStyleSheetLoader.cpp in Sources */,
     17360                                E47B4BE90E71241600038854 /* CachedResourceHandle.cpp in Sources */,
    1735117361                        );
    1735217362                        runOnlyForDeploymentPostprocessing = 0;
  • trunk/WebCore/css/CSSFontFaceSource.h

    r34794 r36109  
    2929#include "AtomicString.h"
    3030#include "CachedResourceClient.h"
     31#include "CachedResourceHandle.h"
    3132#include <wtf/HashMap.h>
    3233
     
    6869private:
    6970    AtomicString m_string; // URI for remote, built-in font name for local.
    70     CachedFont* m_font; // For remote fonts, a pointer to our cached resource.
     71    CachedResourceHandle<CachedFont> m_font; // For remote fonts, a pointer to our cached resource.
    7172    CSSFontFace* m_face; // Our owning font face.
    7273    HashMap<unsigned, SimpleFontData*> m_fontDataTable; // The hash key is composed of size synthetic styles.
  • trunk/WebCore/css/CSSImportRule.h

    r34627 r36109  
    2525#include "CSSRule.h"
    2626#include "CachedResourceClient.h"
     27#include "CachedResourceHandle.h"
    2728#include "MediaList.h"
    2829#include "PlatformString.h"
     
    6667    RefPtr<MediaList> m_lstMedia;
    6768    RefPtr<CSSStyleSheet> m_styleSheet;
    68     CachedCSSStyleSheet* m_cachedSheet;
     69    CachedResourceHandle<CachedCSSStyleSheet> m_cachedSheet;
    6970    bool m_loading;
    7071};
  • trunk/WebCore/dom/Clipboard.h

    r34432 r36109  
    2525#define Clipboard_h
    2626
     27#include "CachedResourceHandle.h"
    2728#include "ClipboardAccessPolicy.h"
    2829#include "DragActions.h"
     
    5556   
    5657        IntPoint dragLocation() const { return m_dragLoc; }
    57         CachedImage* dragImage() const { return m_dragImage; }
     58        CachedImage* dragImage() const { return m_dragImage.get(); }
    5859        virtual void setDragImage(CachedImage*, const IntPoint&) = 0;
    5960        Node* dragImageElement() { return m_dragImageElement.get(); }
     
    9192        bool m_forDragging;
    9293        IntPoint m_dragLoc;
    93         CachedImage* m_dragImage;
     94        CachedResourceHandle<CachedImage> m_dragImage;
    9495        RefPtr<Node> m_dragImageElement;
    9596    };
  • trunk/WebCore/dom/ProcessingInstruction.h

    r35172 r36109  
    2626
    2727#include "CachedResourceClient.h"
     28#include "CachedResourceHandle.h"
    2829#include "ContainerNode.h"
    2930
     
    8586    String m_title;
    8687    String m_media;
    87     CachedResource* m_cachedSheet;
     88    CachedResourceHandle<CachedResource> m_cachedSheet;
    8889    RefPtr<StyleSheet> m_sheet;
    8990    bool m_loading;
  • trunk/WebCore/dom/ScriptElement.h

    r35744 r36109  
    2323
    2424#include "CachedResourceClient.h"
     25#include "CachedResourceHandle.h"
    2526
    2627namespace WebCore {
     
    8182    ScriptElement* m_scriptElement;
    8283    Element* m_element;
    83     CachedScript* m_cachedScript;
     84    CachedResourceHandle<CachedScript> m_cachedScript;
    8485    bool m_createdByParser;
    8586    bool m_evaluated;
  • trunk/WebCore/dom/XMLTokenizer.cpp

    r36099 r36109  
    15421542bool XMLTokenizer::isWaitingForScripts() const
    15431543{
    1544     return m_pendingScript != 0;
     1544    return m_pendingScript;
    15451545}
    15461546
  • trunk/WebCore/dom/XMLTokenizer.h

    r31860 r36109  
    2626
    2727#include "CachedResourceClient.h"
     28#include "CachedResourceHandle.h"
    2829#include "SegmentedString.h"
    2930#include "StringHash.h"
     
    155156        String m_errorMessages;
    156157
    157         CachedScript* m_pendingScript;
     158        CachedResourceHandle<CachedScript> m_pendingScript;
    158159        RefPtr<Element> m_scriptElement;
    159160        int m_scriptStartLine;
  • trunk/WebCore/html/HTMLImageLoader.cpp

    r34853 r36109  
    5858void HTMLImageLoader::setImage(CachedImage *newImage)
    5959{
    60     CachedImage *oldImage = m_image;
     60    CachedImage *oldImage = m_image.get();
    6161    if (newImage != oldImage) {
    6262        setLoadingImage(newImage);
     
    108108    }
    109109   
    110     CachedImage *oldImage = m_image;
     110    CachedImage *oldImage = m_image.get();
    111111    if (newImage != oldImage) {
    112112#ifdef INSTRUMENT_LAYOUT_SCHEDULING
     
    146146    if (RenderObject* renderer = elem->renderer())
    147147        if (renderer->isImage())
    148             static_cast<RenderImage*>(renderer)->setCachedImage(m_image);
     148            static_cast<RenderImage*>(renderer)->setCachedImage(m_image.get());
    149149           
    150150    if (image->errorOccurred() && elem->hasTagName(objectTag))
  • trunk/WebCore/html/HTMLImageLoader.h

    r26992 r36109  
    2727
    2828#include "CachedResourceClient.h"
     29#include "CachedResourceHandle.h"
    2930
    3031namespace WebCore {
     
    4445    bool imageComplete() const { return m_imageComplete; }
    4546
    46     CachedImage* image() const { return m_image; }
     47    CachedImage* image() const { return m_image.get(); }
    4748    void setImage(CachedImage*);
    4849
     
    6061private:
    6162    Element* m_element;
    62     CachedImage* m_image;
     63    CachedResourceHandle<CachedImage> m_image;
    6364    bool m_firedLoad : 1;
    6465    bool m_imageComplete : 1;
  • trunk/WebCore/html/HTMLLinkElement.h

    r35172 r36109  
    2626#include "CSSStyleSheet.h"
    2727#include "CachedResourceClient.h"
     28#include "CachedResourceHandle.h"
    2829#include "HTMLElement.h"
    2930
     
    101102
    102103protected:
    103     CachedCSSStyleSheet* m_cachedSheet;
     104    CachedResourceHandle<CachedCSSStyleSheet> m_cachedSheet;
    104105    RefPtr<CSSStyleSheet> m_sheet;
    105106    String m_url;
  • trunk/WebCore/html/HTMLTokenizer.cpp

    r35767 r36109  
    211211
    212212    while (!pendingScripts.isEmpty()) {
    213       CachedScript *cs = pendingScripts.dequeue();
    214       ASSERT(cache()->disabled() || cs->accessCount() > 0);
    215       cs->removeClient(this);
     213        CachedScript *cs = pendingScripts.first().get();
     214        pendingScripts.removeFirst();
     215        ASSERT(cache()->disabled() || cs->accessCount() > 0);
     216        cs->removeClient(this);
    216217    }
    217218   
     
    431432                // If so, we don't want to load scripts.
    432433                if (!m_parserStopped && (cs = m_doc->docLoader()->requestScript(scriptSrc, scriptSrcCharset)))
    433                     pendingScripts.enqueue(cs);
     434                    pendingScripts.append(cs);
    434435                else
    435436                    scriptNode = 0;
     
    19811982
    19821983    bool finished = false;
    1983     while (!finished && pendingScripts.head()->isLoaded()) {
    1984         CachedScript* cs = pendingScripts.dequeue();
     1984    while (!finished && pendingScripts.first()->isLoaded()) {
     1985        CachedScript *cs = pendingScripts.first().get();
     1986        pendingScripts.removeFirst();
    19851987        ASSERT(cache()->disabled() || cs->accessCount() > 0);
    19861988
  • trunk/WebCore/html/HTMLTokenizer.h

    r35767 r36109  
    2525#define HTMLTokenizer_h
    2626
    27 #include "DeprecatedPtrQueue.h"
     27#include "CachedResourceClient.h"
     28#include "CachedResourceHandle.h"
    2829#include "NamedMappedAttrMap.h"
    2930#include "SegmentedString.h"
    3031#include "Timer.h"
    3132#include "Tokenizer.h"
    32 #include "CachedResourceClient.h"
     33#include <wtf/Deque.h>
     34#include <wtf/OwnPtr.h>
    3335#include <wtf/Vector.h>
    34 #include <wtf/OwnPtr.h>
    3536
    3637namespace WebCore {
     
    374375    // the output of the script to be postponed until after the script has finished executing
    375376    int m_executingScript;
    376     DeprecatedPtrQueue<CachedScript> pendingScripts;
     377    Deque<CachedResourceHandle<CachedScript> > pendingScripts;
    377378    RefPtr<Node> scriptNode;
    378379
  • trunk/WebCore/loader/Cache.cpp

    r35921 r36109  
    187187
    188188    return userSheet;
     189}
     190   
     191void Cache::revalidateResource(CachedResource* resource, DocLoader* docLoader)
     192{
     193    ASSERT(resource);
     194    ASSERT(!disabled());
     195    if (resource->resourceToRevalidate())
     196        return;
     197    if (!resource->canUseCacheValidator()) {
     198        remove(resource);
     199        return;
     200    }
     201    const String& url = resource->url();
     202    CachedResource* newResource = createResource(resource->type(), KURL(url), resource->encoding());
     203    newResource->setResourceToRevalidate(resource);
     204    remove(resource);
     205    m_resources.set(url, newResource);
     206    newResource->setInCache(true);
     207    resourceAccessed(newResource);
     208    newResource->load(docLoader);
     209}
     210   
     211void Cache::revalidationSucceeded(CachedResource* revalidatingResource, const ResourceResponse& response)
     212{
     213    CachedResource* resource = revalidatingResource->resourceToRevalidate();
     214    ASSERT(resource);
     215    ASSERT(!resource->inCache());
     216    ASSERT(resource->isLoaded());
     217   
     218    remove(revalidatingResource);
     219
     220    ASSERT(!m_resources.get(resource->url()));
     221    m_resources.set(resource->url(), resource);
     222    resource->setInCache(true);
     223    resource->setExpirationDate(response.expirationDate());
     224    insertInLRUList(resource);
     225    int delta = resource->size();
     226    if (resource->decodedSize() && resource->hasClients())
     227        insertInLiveDecodedResourcesList(resource);
     228    if (delta)
     229        adjustSize(resource->hasClients(), delta);
     230   
     231    revalidatingResource->switchClientsToRevalidatedResource();
     232    // this deletes the revalidating resource
     233    revalidatingResource->clearResourceToRevalidate();
     234}
     235
     236void Cache::revalidationFailed(CachedResource* revalidatingResource)
     237{
     238    ASSERT(revalidatingResource->resourceToRevalidate());
     239    revalidatingResource->clearResourceToRevalidate();
    189240}
    190241
  • trunk/WebCore/loader/Cache.h

    r31287 r36109  
    44    Copyright (C) 1998 Lars Knoll (knoll@mpi-hd.mpg.de)
    55    Copyright (C) 2001 Dirk Mueller <mueller@kde.org>
    6     Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
     6    Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
    77
    88    This library is free software; you can redistribute it and/or
     
    100100    CachedCSSStyleSheet* requestUserCSSStyleSheet(DocLoader*, const String& url, const String& charset);
    101101   
     102    void revalidateResource(CachedResource*, DocLoader*);
     103    void revalidationSucceeded(CachedResource* revalidatingResource, const ResourceResponse&);
     104    void revalidationFailed(CachedResource* revalidatingResource);
     105   
    102106    // Sets the cache's memory capacities, in bytes. These will hold only approximately,
    103107    // since the decoded cost of resources like scripts and stylesheets is not known.
  • trunk/WebCore/loader/CachedResource.cpp

    r36096 r36109  
    2626
    2727#include "Cache.h"
     28#include "CachedResourceHandle.h"
    2829#include "DocLoader.h"
    2930#include "Frame.h"
     
    4647    , m_loading(false)
    4748    , m_docLoader(0)
     49    , m_handleCount(0)
     50    , m_resourceToRevalidate(0)
     51    , m_isBeingRevalidated(false)
     52    , m_expirationDate(0)
    4853{
    4954    m_type = type;
     
    7782    m_deleted = true;
    7883#endif
    79    
     84
     85    ASSERT(cache()->resourceForURL(url()) != this);
     86   
     87    if (m_resourceToRevalidate)
     88        m_resourceToRevalidate->m_isBeingRevalidated = false;   
     89   
    8090    if (m_docLoader)
    8191        m_docLoader->removeCachedResource(this);
     
    96106bool CachedResource::isExpired() const
    97107{
    98     if (!m_response.expirationDate())
     108    if (!m_expirationDate)
    99109        return false;
    100110    time_t now = time(0);
    101     return (difftime(now, m_response.expirationDate()) >= 0);
    102 }
    103 
     111    return difftime(now, m_expirationDate) >= 0;
     112}
     113 
     114void CachedResource::setResponse(const ResourceResponse& response)
     115{
     116    m_response = response;
     117    m_expirationDate = response.expirationDate();
     118}
     119   
    104120void CachedResource::setRequest(Request* request)
    105121{
     
    140156}
    141157
     158void CachedResource::deleteIfPossible()
     159{
     160    if (canDelete() && !inCache())
     161        delete this;
     162}
     163   
    142164void CachedResource::setDecodedSize(unsigned size)
    143165{
     
    209231    }
    210232}
    211 
    212 }
     233   
     234void CachedResource::setResourceToRevalidate(CachedResource* resource)
     235{
     236    ASSERT(resource);
     237    ASSERT(!m_resourceToRevalidate);
     238    ASSERT(resource != this);
     239    ASSERT(!resource->m_isBeingRevalidated);
     240    ASSERT(m_handlesToRevalidate.isEmpty());
     241    ASSERT(resource->type() == type());
     242    resource->m_isBeingRevalidated = true;
     243    m_resourceToRevalidate = resource;
     244}
     245
     246void CachedResource::clearResourceToRevalidate()
     247{
     248    ASSERT(m_resourceToRevalidate);
     249    ASSERT(m_resourceToRevalidate->m_isBeingRevalidated);
     250    m_resourceToRevalidate->m_isBeingRevalidated = false;
     251    m_resourceToRevalidate->deleteIfPossible();
     252    m_handlesToRevalidate.clear();
     253    m_resourceToRevalidate = 0;
     254    deleteIfPossible();
     255}
     256   
     257void CachedResource::switchClientsToRevalidatedResource()
     258{
     259    ASSERT(m_resourceToRevalidate);
     260    ASSERT(!inCache());
     261
     262    HashSet<CachedResourceHandleBase*>::iterator end = m_handlesToRevalidate.end();
     263    for (HashSet<CachedResourceHandleBase*>::iterator it = m_handlesToRevalidate.begin(); it != end; ++it) {
     264        CachedResourceHandleBase* handle = *it;
     265        handle->m_resource = m_resourceToRevalidate;
     266        m_resourceToRevalidate->registerHandle(handle);
     267        --m_handleCount;
     268    }
     269    ASSERT(!m_handleCount);
     270    m_handlesToRevalidate.clear();
     271
     272    Vector<CachedResourceClient*> clientsToMove;
     273    HashCountedSet<CachedResourceClient*>::iterator end2 = m_clients.end();
     274    for (HashCountedSet<CachedResourceClient*>::iterator it = m_clients.begin(); it != end2; ++it) {
     275        CachedResourceClient* client = it->first;
     276        unsigned count = it->second;
     277        while (count) {
     278            clientsToMove.append(client);
     279            --count;
     280        }
     281    }
     282    // Equivalent of calling removeClient() for all clients
     283    m_clients.clear();
     284   
     285    unsigned moveCount = clientsToMove.size();
     286    for (unsigned n = 0; n < moveCount; ++n)
     287        m_resourceToRevalidate->addClient(clientsToMove[n]);
     288}
     289   
     290bool CachedResource::canUseCacheValidator() const
     291{
     292    return !m_loading && (!m_response.httpHeaderField("Last-Modified").isEmpty() || !m_response.httpHeaderField("ETag").isEmpty());
     293}
     294   
     295bool CachedResource::mustRevalidate(CachePolicy cachePolicy) const
     296{
     297    if (m_loading)
     298        return false;   
     299    String cacheControl = m_response.httpHeaderField("Cache-Control");
     300    // FIXME: It would be better to tokenize the field.
     301    if (cachePolicy == CachePolicyCache)
     302        return !cacheControl.isEmpty() && (cacheControl.contains("no-cache", false) || (isExpired() && cacheControl.contains("must-revalidate", false)));
     303    return isExpired() || cacheControl.contains("no-cache", false);
     304}
     305
     306}
  • trunk/WebCore/loader/CachedResource.h

    r36096 r36109  
    2424#define CachedResource_h
    2525
     26#include "CachePolicy.h"
    2627#include "PlatformString.h"
    2728#include "ResourceResponse.h"
    2829#include "SharedBuffer.h"
    2930#include <wtf/HashCountedSet.h>
     31#include <wtf/HashSet.h>
    3032#include <wtf/Vector.h>
    3133#include <time.h>
     
    3537class Cache;
    3638class CachedResourceClient;
    37 class CacheHandleBase;
     39class CachedResourceHandleBase;
    3840class DocLoader;
    3941class Request;
     
    8486    void removeClient(CachedResourceClient*);
    8587    bool hasClients() const { return !m_clients.isEmpty(); }
     88    void deleteIfPossible();
    8689
    8790    enum PreloadResult {
     
    129132    SharedBuffer* data() const { return m_data.get(); }
    130133
    131     void setResponse(const ResourceResponse& response) { m_response = response; }
     134    void setResponse(const ResourceResponse&);
    132135    const ResourceResponse& response() const { return m_response; }
    133    
    134     bool canDelete() const { return !hasClients() && !m_request && !m_preloadCount; }
     136
     137    bool canDelete() const { return !hasClients() && !m_request && !m_preloadCount && !m_handleCount && !m_resourceToRevalidate && !m_isBeingRevalidated; }
    135138
    136139    bool isExpired() const;
     
    154157    void decreasePreloadCount() { ASSERT(m_preloadCount); --m_preloadCount; }
    155158   
     159    void registerHandle(CachedResourceHandleBase* h) { ++m_handleCount; if (m_resourceToRevalidate) m_handlesToRevalidate.add(h); }
     160    void unregisterHandle(CachedResourceHandleBase* h) { --m_handleCount; if (m_resourceToRevalidate) m_handlesToRevalidate.remove(h); if (!m_handleCount) deleteIfPossible(); }
     161   
     162    bool canUseCacheValidator() const;
     163    bool mustRevalidate(CachePolicy) const;
     164    bool isCacheValidator() const { return m_resourceToRevalidate; }
     165    CachedResource* resourceToRevalidate() const { return m_resourceToRevalidate; }
     166   
    156167protected:
    157168    void setEncodedSize(unsigned);
     
    174185
    175186private:
     187    // These are called by the friendly Cache only
     188    void setResourceToRevalidate(CachedResource*);
     189    void switchClientsToRevalidatedResource();
     190    void clearResourceToRevalidate();
     191    void setExpirationDate(time_t expirationDate) { m_expirationDate = expirationDate; }
     192
    176193    unsigned m_encodedSize;
    177194    unsigned m_decodedSize;
     
    203220
    204221    DocLoader* m_docLoader; // only non-0 for resources that are not in the cache
     222   
     223    unsigned m_handleCount;
     224    // If this field is non-null we are using the resource as a proxy for checking whether an existing resource is still up to date
     225    // using HTTP If-Modified-Since/If-None-Match headers. If the response is 304 all clients of this resource are moved
     226    // to to be clients of m_resourceToRevalidate and the resource is deleted. If not, the field is zeroed and this
     227    // resources becomes normal resource load.
     228    CachedResource* m_resourceToRevalidate;
     229    bool m_isBeingRevalidated;
     230    // These handles will need to be updated to point to the m_resourceToRevalidate in case we get 304 response.
     231    HashSet<CachedResourceHandleBase*> m_handlesToRevalidate;
     232   
     233    time_t m_expirationDate;
    205234};
    206235
  • trunk/WebCore/loader/DocLoader.cpp

    r35801 r36109  
    8181        return;
    8282
    83     if (m_cachePolicy == CachePolicyVerify) {
     83    if (m_cachePolicy == CachePolicyVerify || m_cachePolicy == CachePolicyCache) {
    8484       if (!m_reloadedURLs.contains(fullURL.string())) {
    8585          CachedResource* existing = cache()->resourceForURL(fullURL.string());
    86           if (existing && existing->isExpired() && !existing->isPreloaded()) {
    87              cache()->remove(existing);
    88              m_reloadedURLs.add(fullURL.string());
     86          if (existing && !existing->isPreloaded() && existing->mustRevalidate(m_cachePolicy)) {
     87              cache()->revalidateResource(existing, this);
     88              m_reloadedURLs.add(fullURL.string());
    8989          }
    9090       }
     
    9393           CachedResource* existing = cache()->resourceForURL(fullURL.string());
    9494           if (existing && !existing->isPreloaded()) {
     95               // FIXME: Use revalidateResource() to implement HTTP 1.1 "Specific end-to-end revalidation" for regular reloading
    9596               cache()->remove(existing);
    9697               m_reloadedURLs.add(fullURL.string());
  • trunk/WebCore/loader/UserStyleSheetLoader.h

    r36088 r36109  
    3131
    3232#include "CachedResourceClient.h"
     33#include "CachedResourceHandle.h"
    3334
    3435#include "Document.h"
     
    4950
    5051        RefPtr<Document> m_document;
    51         CachedCSSStyleSheet* m_cachedSheet;
     52        CachedResourceHandle<CachedCSSStyleSheet> m_cachedSheet;
    5253    };
    5354
  • trunk/WebCore/loader/loader.cpp

    r35801 r36109  
    219219        Request* request = requestsPending.first();
    220220        DocLoader* docLoader = request->docLoader();
     221        bool resourceIsCacheValidator = request->cachedResource()->isCacheValidator();
    221222        // If the document is fully parsed and there are no pending stylesheets there won't be any more
    222223        // resources that we would want to push to the front of the queue. Just hand off the remaining resources
    223224        // to the networking layer.
    224225        bool parsedAndStylesheetsKnown = !docLoader->doc()->parsing() && docLoader->doc()->haveStylesheetsLoaded();
    225         if (!parsedAndStylesheetsKnown && m_requestsLoading.size() >= m_maxRequestsInFlight) {
     226        if (!parsedAndStylesheetsKnown && !resourceIsCacheValidator && m_requestsLoading.size() >= m_maxRequestsInFlight) {
    226227            serveLowerPriority = false;
    227228            return;
     
    238239            referrer.setPath("/");
    239240        resourceRequest.setHTTPReferrer(referrer.string());
     241       
     242        if (resourceIsCacheValidator) {
     243            CachedResource* resourceToRevalidate = request->cachedResource()->resourceToRevalidate();
     244            ASSERT(resourceToRevalidate->canUseCacheValidator());
     245            ASSERT(resourceToRevalidate->isLoaded());
     246            const String& lastModified = resourceToRevalidate->response().httpHeaderField("Last-Modified");
     247            const String& eTag = resourceToRevalidate->response().httpHeaderField("ETag");
     248            if (!lastModified.isEmpty() || !eTag.isEmpty()) {
     249                if (docLoader->cachePolicy() == CachePolicyReload || docLoader->cachePolicy() == CachePolicyRefresh)
     250                    resourceRequest.setHTTPHeaderField("Cache-Control", "max-age=0");
     251                if (!lastModified.isEmpty())
     252                    resourceRequest.setHTTPHeaderField("If-Modified-Since", lastModified);
     253                if (!eTag.isEmpty())
     254                    resourceRequest.setHTTPHeaderField("If-None-Match", eTag);
     255            }
     256        }
    240257
    241258        RefPtr<SubresourceLoader> loader = SubresourceLoader::create(docLoader->doc()->frame(),
     
    270287
    271288    CachedResource* resource = request->cachedResource();
     289    ASSERT(!resource->resourceToRevalidate());
    272290
    273291    // If we got a 4xx response, we're pretending to have received a network
     
    312330
    313331    CachedResource* resource = request->cachedResource();
     332   
     333    if (resource->resourceToRevalidate())
     334        cache()->revalidationFailed(resource);
    314335
    315336    if (!cancelled) {
     
    341362    if (!request)
    342363        return;
    343     request->cachedResource()->setResponse(response);
     364   
     365    CachedResource* resource = request->cachedResource();
     366   
     367    if (resource->isCacheValidator()) {
     368        if (response.httpStatusCode() == 304) {
     369            // 304 Not modified / Use local copy
     370            m_requestsLoading.remove(loader);
     371            request->docLoader()->decrementRequestCount();
     372
     373            // Existing resource is ok, just use it updating the expiration time.
     374            cache()->revalidationSucceeded(resource, response);
     375            delete request;
     376
     377            servePendingRequests();
     378            return;
     379        }
     380        // Did not get 304 response, continue as a regular resource load.
     381        cache()->revalidationFailed(resource);
     382    }
     383   
     384    resource->setResponse(response);
    344385   
    345386    String encoding = response.textEncodingName();
     
    372413
    373414    CachedResource* resource = request->cachedResource();   
     415    ASSERT(!resource->isCacheValidator());
     416   
    374417    if (resource->errorOccurred())
    375418        return;
  • trunk/WebCore/page/EventHandler.cpp

    r36000 r36109  
    840840        const CursorList* cursors = style->cursors();
    841841        for (unsigned i = 0; i < cursors->size(); ++i) {
    842             CachedImage* cimage = (*cursors)[i].cursorImage;
     842            CachedImage* cimage = (*cursors)[i].cursorImage.get();
    843843            IntPoint hotSpot = (*cursors)[i].hotSpot;
    844844            if (!cimage)
  • trunk/WebCore/rendering/RenderImage.cpp

    r35828 r36109  
    197197        m_cachedImage->addClient(this);
    198198        if (m_cachedImage->errorOccurred())
    199             imageChanged(m_cachedImage);
     199            imageChanged(m_cachedImage.get());
    200200    }
    201201}
     
    260260    // Set image dimensions, taking into account the size of the alt text.
    261261    if (errorOccurred())
    262         imageSizeChanged = setImageSizeForAltText(m_cachedImage);
     262        imageSizeChanged = setImageSizeForAltText(m_cachedImage.get());
    263263   
    264264    bool shouldRepaint = true;
  • trunk/WebCore/rendering/RenderImage.h

    r35828 r36109  
    2727
    2828#include "CachedImage.h"
     29#include "CachedResourceHandle.h"
    2930#include "RenderReplaced.h"
    3031
     
    5455
    5556    void setCachedImage(CachedImage*);
    56     CachedImage* cachedImage() const { return m_cachedImage; }
     57    CachedImage* cachedImage() const { return m_cachedImage.get(); }
    5758
    5859    virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction);
     
    7980    virtual bool imageHasRelativeHeight() const { return m_cachedImage ? m_cachedImage->imageHasRelativeHeight() : false; }
    8081    virtual IntSize imageSize(float multiplier) const { return m_cachedImage ? m_cachedImage->imageSize(multiplier) : IntSize(); }
    81     virtual WrappedImagePtr imagePtr() const { return m_cachedImage; }
     82    virtual WrappedImagePtr imagePtr() const { return m_cachedImage.get(); }
    8283
    8384    virtual void intrinsicSizeChanged() { imageChanged(imagePtr()); }
     
    9293protected:
    9394    // The image we are rendering.
    94     CachedImage* m_cachedImage;
     95    CachedResourceHandle<CachedImage> m_cachedImage;
    9596
    9697    // Text to display as long as the image isn't available.
  • trunk/WebCore/rendering/style/RenderStyle.h

    r35996 r36109  
    4141#include "CSSReflectionDirection.h"
    4242#include "CSSValueList.h"
     43#include "CachedImage.h"
     44#include "CachedResourceHandle.h"
    4345#include "Color.h"
    4446#include "DataRef.h"
     
    14211423
    14221424    IntPoint hotSpot; // for CSS3 support
    1423     CachedImage* cursorImage; // weak pointer, the CSSValueImage takes care of deleting cursorImage
     1425    CachedResourceHandle<CachedImage> cursorImage;
    14241426};
    14251427
  • trunk/WebCore/rendering/style/StyleCachedImage.h

    r35979 r36109  
    2525#define StyleCachedImage_h
    2626
     27#include "CachedResourceHandle.h"
    2728#include "StyleImage.h"
    2829
     
    3536public:
    3637    static PassRefPtr<StyleCachedImage> create(CachedImage* image) { return adoptRef(new StyleCachedImage(image)); }
    37     virtual WrappedImagePtr data() const { return m_image; }
     38    virtual WrappedImagePtr data() const { return m_image.get(); }
    3839
    3940    virtual bool isCachedImage() const { return true; }
     
    4142    virtual PassRefPtr<CSSValue> cssValue();
    4243   
    43     CachedImage* cachedImage() const { return m_image; }
     44    CachedImage* cachedImage() const { return m_image.get(); }
    4445
    4546    virtual bool canRender(float multiplier) const;
     
    6162    }
    6263   
    63     CachedImage* m_image;
     64    CachedResourceHandle<CachedImage> m_image;
    6465};
    6566
  • trunk/WebCore/svg/SVGFEImageElement.h

    r35248 r36109  
    2525
    2626#if ENABLE(SVG) && ENABLE(SVG_FILTERS)
     27#include "CachedResourceHandle.h"
    2728#include "SVGFilterPrimitiveStandardAttributes.h"
    2829#include "SVGURIReference.h"
     
    5657        ANIMATED_PROPERTY_DECLARATIONS(SVGFEImageElement, SVGNames::feImageTagString, SVGNames::preserveAspectRatioAttrString, SVGPreserveAspectRatio, PreserveAspectRatio, preserveAspectRatio)
    5758
    58         CachedImage* m_cachedImage;
     59        CachedResourceHandle<CachedImage> m_cachedImage;
    5960        mutable RefPtr<FEImage> m_filterEffect;
    6061    };
  • trunk/WebCore/svg/graphics/filters/SVGFEImage.h

    r35094 r36109  
    2626#include "CachedImage.h"
    2727#include "CachedResourceClient.h"
     28#include "CachedResourceHandle.h"
    2829#include "FilterEffect.h"
    2930
     
    4849        FEImage(CachedImage*);
    4950
    50         CachedImage* m_cachedImage;
     51        CachedResourceHandle<CachedImage> m_cachedImage;
    5152    };
    5253
  • trunk/WebCore/xml/XSLImportRule.h

    r34627 r36109  
    2727
    2828#include "CachedResourceClient.h"
     29#include "CachedResourceHandle.h"
    2930#include "StyleBase.h"
    3031#include "XSLStyleSheet.h"
     
    6162    String m_strHref;
    6263    RefPtr<XSLStyleSheet> m_styleSheet;
    63     CachedXSLStyleSheet* m_cachedSheet;
     64    CachedResourceHandle<CachedXSLStyleSheet> m_cachedSheet;
    6465    bool m_loading;
    6566};
Note: See TracChangeset for help on using the changeset viewer.