2008-05-07 Anders Carlsson <andersca@apple.com>
authorandersca@apple.com <andersca@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 7 May 2008 20:41:34 +0000 (20:41 +0000)
committerandersca@apple.com <andersca@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 7 May 2008 20:41:34 +0000 (20:41 +0000)
        Reviewed by John.

        When no document loaders are associated with an application cache group,
        release the reference to the newest cache group. This prevents reference cycles.

        * loader/appcache/ApplicationCacheGroup.cpp:
        (WebCore::ApplicationCacheGroup::ApplicationCacheGroup):
        (WebCore::ApplicationCacheGroup::documentLoaderDestroyed):
        (WebCore::ApplicationCacheGroup::cacheDestroyed):
        * loader/appcache/ApplicationCacheGroup.h:

        * loader/appcache/ApplicationCacheStorage.cpp:
        (WebCore::ApplicationCacheStorage::cacheGroupForURL):
        Return early if the datbase wasn't open.

        (WebCore::ApplicationCacheStorage::loadCache):
        Add error.

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

WebCore/ChangeLog
WebCore/loader/appcache/ApplicationCacheGroup.cpp
WebCore/loader/appcache/ApplicationCacheGroup.h
WebCore/loader/appcache/ApplicationCacheStorage.cpp

index 6eaaf1e..6093948 100644 (file)
@@ -1,5 +1,25 @@
 2008-05-07  Anders Carlsson  <andersca@apple.com>
 
+        Reviewed by John.
+
+        When no document loaders are associated with an application cache group,
+        release the reference to the newest cache group. This prevents reference cycles.
+        
+        * loader/appcache/ApplicationCacheGroup.cpp:
+        (WebCore::ApplicationCacheGroup::ApplicationCacheGroup):
+        (WebCore::ApplicationCacheGroup::documentLoaderDestroyed):
+        (WebCore::ApplicationCacheGroup::cacheDestroyed):
+        * loader/appcache/ApplicationCacheGroup.h:
+        
+        * loader/appcache/ApplicationCacheStorage.cpp:
+        (WebCore::ApplicationCacheStorage::cacheGroupForURL):
+        Return early if the datbase wasn't open.
+        
+        (WebCore::ApplicationCacheStorage::loadCache):
+        Add error.
+
+2008-05-07  Anders Carlsson  <andersca@apple.com>
+
         Reviewed by Adam.
 
         Don't put pages with an application cache in the BF cache.
index fc6a574..25703f1 100644 (file)
@@ -47,7 +47,7 @@ namespace WebCore {
 ApplicationCacheGroup::ApplicationCacheGroup(const KURL& manifestURL)
     : m_manifestURL(manifestURL)
     , m_status(Idle)
-    , m_newestCache(0)
+    , m_savedNewestCachePointer(0)
     , m_frame(0)
     , m_storageID(0)
 {
@@ -237,9 +237,12 @@ void ApplicationCacheGroup::documentLoaderDestroyed(DocumentLoader* loader)
         // We should only have the newest cache remaining.
         ASSERT(m_caches.size() == 1);
         ASSERT(m_caches.contains(m_newestCache.get()));
-
-        // This should cause us to be deleted.
-        m_newestCache = 0;        
+        
+        // Release our reference to the newest cache.
+        m_savedNewestCachePointer = m_newestCache.get();
+        
+        // This could cause us to be deleted.
+        m_newestCache = 0;
     }    
 }    
 
@@ -249,7 +252,7 @@ void ApplicationCacheGroup::cacheDestroyed(ApplicationCache* cache)
     
     m_caches.remove(cache);
     
-    if (cache != newestCache())
+    if (cache != m_savedNewestCachePointer)
         cacheStorage().remove(cache);
 
     if (m_caches.isEmpty())
index 0f54268..bb30e3a 100644 (file)
@@ -104,6 +104,9 @@ private:
     // This is the newest cache in the group.
     RefPtr<ApplicationCache> m_newestCache;
     
+    // During tear-down we save the pointer to the newest cache to prevent reference cycles.
+    ApplicationCache* m_savedNewestCachePointer;
+    
     // The caches in this cache group.
     HashSet<ApplicationCache*> m_caches;
     
index 8ce1f18..f6b7156 100644 (file)
@@ -153,6 +153,9 @@ ApplicationCacheGroup* ApplicationCacheStorage::cacheGroupForURL(const KURL& url
         }
     }
     
+    if (!m_database.isOpen())
+        return 0;
+        
     // Check the database. Look for all cache groups with a newest cache.
     SQLiteStatement statement(m_database, "SELECT id, manifestURL, newestCache FROM CacheGroups WHERE newestCache IS NOT NULL");
     if (statement.prepare() != SQLResultOk)
@@ -460,8 +463,11 @@ PassRefPtr<ApplicationCache> ApplicationCacheStorage::loadCache(unsigned storage
     SQLiteStatement cacheStatement(m_database, 
                                    "SELECT url, type, CacheResourceData.data FROM CacheEntries INNER JOIN CacheResources ON CacheEntries.resource=CacheResources.id "
                                    "INNER JOIN CacheResourceData ON CacheResourceData.id=CacheResources.data WHERE CacheEntries.cache=?");
-    if (cacheStatement.prepare() != SQLResultOk)
+    if (cacheStatement.prepare() != SQLResultOk) {
+        LOG_ERROR("Could not prepare cache statement, error \"%s\"", m_database.lastErrorMsg());
         return 0;
+    }
+    
     cacheStatement.bindInt64(1, storageID);
 
     RefPtr<ApplicationCache> cache = ApplicationCache::create();