WebCore:
authorandersca@apple.com <andersca@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 13 May 2008 18:14:39 +0000 (18:14 +0000)
committerandersca@apple.com <andersca@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 13 May 2008 18:14:39 +0000 (18:14 +0000)
2008-05-13  Anders Carlsson  <andersca@apple.com>

        Reviewed by Darin.

        Don't crash when a document loader is destroyed while an initial caching attempt
        is in progress.

        * loader/appcache/ApplicationCacheGroup.cpp:
        (WebCore::ApplicationCacheGroup::~ApplicationCacheGroup):
        Stop loading.

        (WebCore::ApplicationCacheGroup::stopLoading):
        New method that stops a cache update.

        (WebCore::ApplicationCacheGroup::documentLoaderDestroyed):
        Delete ourselves here.

        * loader/appcache/ApplicationCacheGroup.h:

LayoutTests:

2008-05-13  Anders Carlsson  <andersca@apple.com>

        Reviewed by Darin.

        Add testcase.

        * http/tests/appcache/navigating-away-while-cache-attempt-in-progress-expected.txt: Added.
        * http/tests/appcache/navigating-away-while-cache-attempt-in-progress.html: Added.
        * http/tests/appcache/resources/navigating-away-while-cache-attempt-in-progress.manifest: Added.
        * http/tests/appcache/resources/slow-resource.php: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@33378 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/http/tests/appcache/navigating-away-while-cache-attempt-in-progress-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/appcache/navigating-away-while-cache-attempt-in-progress.html [new file with mode: 0644]
LayoutTests/http/tests/appcache/resources/navigating-away-while-cache-attempt-in-progress.manifest [new file with mode: 0644]
LayoutTests/http/tests/appcache/resources/slow-resource.php [new file with mode: 0644]
WebCore/ChangeLog
WebCore/loader/appcache/ApplicationCacheGroup.cpp
WebCore/loader/appcache/ApplicationCacheGroup.h

index 518b092..f3aca26 100644 (file)
@@ -1,3 +1,14 @@
+2008-05-13  Anders Carlsson  <andersca@apple.com>
+
+        Reviewed by Darin.
+
+        Add testcase.
+        
+        * http/tests/appcache/navigating-away-while-cache-attempt-in-progress-expected.txt: Added.
+        * http/tests/appcache/navigating-away-while-cache-attempt-in-progress.html: Added.
+        * http/tests/appcache/resources/navigating-away-while-cache-attempt-in-progress.manifest: Added.
+        * http/tests/appcache/resources/slow-resource.php: Added.
+
 2008-05-13  Alexey Proskuryakov  <ap@webkit.org>
 
         Reviewed by Darin.
diff --git a/LayoutTests/http/tests/appcache/navigating-away-while-cache-attempt-in-progress-expected.txt b/LayoutTests/http/tests/appcache/navigating-away-while-cache-attempt-in-progress-expected.txt
new file mode 100644 (file)
index 0000000..ca09f7e
--- /dev/null
@@ -0,0 +1,2 @@
+This tests that navigating away while a cache is loading does not crash.
+SUCCESS - did not crash
diff --git a/LayoutTests/http/tests/appcache/navigating-away-while-cache-attempt-in-progress.html b/LayoutTests/http/tests/appcache/navigating-away-while-cache-attempt-in-progress.html
new file mode 100644 (file)
index 0000000..451133f
--- /dev/null
@@ -0,0 +1,21 @@
+<html manifest="resources/navigating-away-while-cache-attempt-in-progress.manifest">
+
+<script>
+if (window.layoutTestController) {
+    layoutTestController.dumpAsText()
+    layoutTestController.waitUntilDone();
+}
+
+function navigateAway() {
+    if (layoutTestController)
+        layoutTestController.notifyDone();
+    else
+        window.location.href = "about:blank"
+}
+
+setTimeout(navigateAway, 1000);
+
+</script>
+<div>This tests that navigating away while a cache is loading does not crash.</div>
+<div>SUCCESS - did not crash</div>
+</html>
diff --git a/LayoutTests/http/tests/appcache/resources/navigating-away-while-cache-attempt-in-progress.manifest b/LayoutTests/http/tests/appcache/resources/navigating-away-while-cache-attempt-in-progress.manifest
new file mode 100644 (file)
index 0000000..10f6ddb
--- /dev/null
@@ -0,0 +1,2 @@
+CACHE MANIFEST
+slow-resource.php
diff --git a/LayoutTests/http/tests/appcache/resources/slow-resource.php b/LayoutTests/http/tests/appcache/resources/slow-resource.php
new file mode 100644 (file)
index 0000000..b720ba1
--- /dev/null
@@ -0,0 +1,3 @@
+<?php
+sleep(10);
+?>
index 5d38afd..7b729a9 100644 (file)
@@ -1,3 +1,22 @@
+2008-05-13  Anders Carlsson  <andersca@apple.com>
+
+        Reviewed by Darin.
+
+        Don't crash when a document loader is destroyed while an initial caching attempt
+        is in progress.
+
+        * loader/appcache/ApplicationCacheGroup.cpp:
+        (WebCore::ApplicationCacheGroup::~ApplicationCacheGroup):
+        Stop loading.
+        
+        (WebCore::ApplicationCacheGroup::stopLoading):
+        New method that stops a cache update.
+        
+        (WebCore::ApplicationCacheGroup::documentLoaderDestroyed):
+        Delete ourselves here.
+        
+        * loader/appcache/ApplicationCacheGroup.h:
+
 2008-05-13  Alexey Proskuryakov  <ap@webkit.org>
 
         Reviewed by Darin.
index 14bb969..e990caf 100644 (file)
@@ -58,6 +58,9 @@ ApplicationCacheGroup::~ApplicationCacheGroup()
     ASSERT(!m_newestCache);
     ASSERT(m_caches.isEmpty());
     
+    if (m_cacheBeingUpdated)
+        stopLoading();
+    
     cacheStorage().cacheGroupDestroyed(this);
 }
     
@@ -220,6 +223,29 @@ void ApplicationCacheGroup::finishedLoadingMainResource(DocumentLoader* loader)
     checkIfLoadIsComplete();
 }
 
+void ApplicationCacheGroup::stopLoading()
+{
+    ASSERT(m_cacheBeingUpdated);
+    
+    if (m_manifestHandle) {
+        ASSERT(!m_currentHandle);
+        
+        m_manifestHandle->setClient(0);
+        m_manifestHandle->cancel();
+        m_manifestHandle = 0;
+    }
+    
+    if (m_currentHandle) {
+        ASSERT(!m_manifestHandle);
+        
+        m_currentHandle->setClient(0);
+        m_currentHandle->cancel();
+        m_currentHandle = 0;
+    }    
+    
+    m_cacheBeingUpdated = 0;
+}    
+
 void ApplicationCacheGroup::documentLoaderDestroyed(DocumentLoader* loader)
 {
     HashSet<DocumentLoader*>::iterator it = m_associatedDocumentLoaders.find(loader);
@@ -233,9 +259,14 @@ void ApplicationCacheGroup::documentLoaderDestroyed(DocumentLoader* loader)
         m_cacheCandidates.remove(loader);
     }
     
-    if (m_associatedDocumentLoaders.isEmpty() && m_cacheCandidates.isEmpty()) {
-        // We should only have the newest cache remaining.
-        ASSERT(m_caches.size() == 1);
+    if (!m_associatedDocumentLoaders.isEmpty() || !m_cacheCandidates.isEmpty())
+        return;
+    
+    // We should only have the newest cache remaining, or there is an initial cache attempt in progress.
+    ASSERT(m_caches.size() == 1 || m_cacheBeingUpdated);
+        
+    // If a cache update is in progress, stop it.
+    if (m_caches.size() == 1) {
         ASSERT(m_caches.contains(m_newestCache.get()));
         
         // Release our reference to the newest cache.
@@ -243,7 +274,16 @@ void ApplicationCacheGroup::documentLoaderDestroyed(DocumentLoader* loader)
         
         // This could cause us to be deleted.
         m_newestCache = 0;
-    }    
+        
+        return;
+    }
+    
+    // There is an initial cache attempt in progress
+    ASSERT(m_cacheBeingUpdated);
+    ASSERT(m_caches.size() == 0);
+    
+    // Delete ourselves, causing the cache attempt to be stopped.
+    delete this;
 }    
 
 void ApplicationCacheGroup::cacheDestroyed(ApplicationCache* cache)
index fb60dca..40d3ab8 100644 (file)
@@ -99,6 +99,8 @@ private:
     
     void associateDocumentLoaderWithCache(DocumentLoader*, ApplicationCache*);
     
+    void stopLoading();
+    
     KURL m_manifestURL;
     Status m_status;