2008-12-25  Antti Koivisto  <antti@apple.com>

        Reviewed by Oliver Hunt.

        <rdar://problem/6465669> Frequent !isPurgeable() assertion in WebCore::CachedResource::addClient
        
        Disallow turning resources that are being revalidated to purgable state.
        
        No test, the condition is difficult to produce in DRT.

        * loader/CachedCSSStyleSheet.cpp:
        (WebCore::CachedCSSStyleSheet::allClientsRemoved):
        * loader/CachedImage.cpp:
        (WebCore::CachedImage::destroyDecodedData):
        * loader/CachedResource.cpp:
        (WebCore::CachedResource::isSafeToMakePurgeable):
        (WebCore::CachedResource::makePurgeable):
        * loader/CachedResource.h:
        * loader/CachedScript.cpp:
        (WebCore::CachedScript::destroyDecodedData):



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@39473 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 3070ff2..fd94028 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,24 @@
+2008-12-25  Antti Koivisto  <antti@apple.com>
+
+        Reviewed by Oliver Hunt.
+
+        <rdar://problem/6465669> Frequent !isPurgeable() assertion in WebCore::CachedResource::addClient
+        
+        Disallow turning resources that are being revalidated to purgable state.
+        
+        No test, the condition is difficult to produce in DRT.
+
+        * loader/CachedCSSStyleSheet.cpp:
+        (WebCore::CachedCSSStyleSheet::allClientsRemoved):
+        * loader/CachedImage.cpp:
+        (WebCore::CachedImage::destroyDecodedData):
+        * loader/CachedResource.cpp:
+        (WebCore::CachedResource::isSafeToMakePurgeable):
+        (WebCore::CachedResource::makePurgeable):
+        * loader/CachedResource.h:
+        * loader/CachedScript.cpp:
+        (WebCore::CachedScript::destroyDecodedData):
+
 2008-12-25  Alexey Proskuryakov  <ap@webkit.org>
 
         Qt build fix.
diff --git a/WebCore/loader/CachedCSSStyleSheet.cpp b/WebCore/loader/CachedCSSStyleSheet.cpp
index 2bedf7f..10d566e 100644
--- a/WebCore/loader/CachedCSSStyleSheet.cpp
+++ b/WebCore/loader/CachedCSSStyleSheet.cpp
@@ -58,7 +58,8 @@
     
 void CachedCSSStyleSheet::allClientsRemoved()
 {
-    makePurgeable(true);
+    if (isSafeToMakePurgeable())
+        makePurgeable(true);
 }
 
 void CachedCSSStyleSheet::setEncoding(const String& chs)
diff --git a/WebCore/loader/CachedImage.cpp b/WebCore/loader/CachedImage.cpp
index a928ffa..e7399fc 100644
--- a/WebCore/loader/CachedImage.cpp
+++ b/WebCore/loader/CachedImage.cpp
@@ -321,7 +321,7 @@
 void CachedImage::destroyDecodedData()
 {
     bool canDeleteImage = !m_image || (m_image->hasOneRef() && m_image->isBitmapImage());
-    if (!hasClients() && canDeleteImage && !m_loading) {
+    if (isSafeToMakePurgeable() && canDeleteImage && !m_loading) {
         // Image refs the data buffer so we should not make it purgeable while the image is alive. 
         // Invoking addClient() will reconstruct the image object.
         m_image = 0;
diff --git a/WebCore/loader/CachedResource.cpp b/WebCore/loader/CachedResource.cpp
index a481223..c1e7191 100644
--- a/WebCore/loader/CachedResource.cpp
+++ b/WebCore/loader/CachedResource.cpp
@@ -316,10 +316,15 @@
     return isExpired() || m_response.cacheControlContainsNoCache();
 }
 
+bool CachedResource::isSafeToMakePurgeable() const
+{ 
+    return !hasClients() && !m_isBeingRevalidated && !m_resourceToRevalidate; 
+}
+
 bool CachedResource::makePurgeable(bool purgeable) 
 { 
     if (purgeable) {
-        ASSERT(!hasClients());
+        ASSERT(isSafeToMakePurgeable());
 
         if (m_purgeableData) {
             ASSERT(!m_data);
diff --git a/WebCore/loader/CachedResource.h b/WebCore/loader/CachedResource.h
index 1eae33e..70e092f 100644
--- a/WebCore/loader/CachedResource.h
+++ b/WebCore/loader/CachedResource.h
@@ -176,6 +176,7 @@
     void didAccessDecodedData(double timeStamp);
 
     bool makePurgeable(bool purgeable);
+    bool isSafeToMakePurgeable() const;
     
     HashCountedSet<CachedResourceClient*> m_clients;
 
diff --git a/WebCore/loader/CachedScript.cpp b/WebCore/loader/CachedScript.cpp
index 8b9d4c9..1eba743 100644
--- a/WebCore/loader/CachedScript.cpp
+++ b/WebCore/loader/CachedScript.cpp
@@ -121,7 +121,7 @@
 {
     m_script = String();
     setDecodedSize(0);
-    if (!hasClients())
+    if (isSafeToMakePurgeable())
         makePurgeable(true);
 }