[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc

joepeck at webkit.org joepeck at webkit.org
Wed Dec 22 11:37:10 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit a204a319f0791b1c54b428a8f1880b4f77db8860
Author: joepeck at webkit.org <joepeck at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Sat Jul 31 02:22:25 2010 +0000

    2010-07-30  Joseph Pecoraro  <joepeck at webkit.org>
    
            Reviewed by David Kilzer.
    
            Limit ApplicationCache Total and Per-Origin Storage Capacity (Quotas)
            https://bugs.webkit.org/show_bug.cgi?id=40627
    
            Part 3 - Refactor storeNewestCache to allow Failure Reason Output
    
            Storing can result in an error in a number of reasons. Previously
            the reasons were global and binary and could be determined by
            checking ApplicationCacheStorage state. Now, with per-origin quotas
            a per-origin quota can cause a failure that is not in global state.
            Current failure reasons are:
    
              OriginQuotaReached = per-origin quota reached, no storage is allowed.
              TotalQuotaReached  = database quota reached, no storage is allowed.
              DiskOrOperationFailure = SQL error such as failed prepare or query. Not expected to happen.
    
            This part provides an implementation of storeNewestCache for those
            that care about the failure reason, and not just if it succeeded
            or not. This moves the final origin quota check into the transaction.
    
            * loader/appcache/ApplicationCache.h: style fix for forwarding headers.
            * loader/appcache/ApplicationCacheGroup.cpp:
            (WebCore::ApplicationCacheGroup::checkIfLoadIsComplete): move origin quota check into storeNewestCache's SQL transaction.
            * loader/appcache/ApplicationCacheStorage.cpp:
            (WebCore::ApplicationCacheStorage::storeNewestCache): old implementation calls the new implementation ignoring failure reason.
            (WebCore::ApplicationCacheStorage::storeNewestCache): new implementation provides a failure reason in case of failure.
            * loader/appcache/ApplicationCacheStorage.h:
            (WebCore::ApplicationCacheStorage::): added FailureReason enum and storeNewestCache allowing it.
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@64399 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index dcf78b0..915bdda 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -5,6 +5,38 @@
         Limit ApplicationCache Total and Per-Origin Storage Capacity (Quotas)
         https://bugs.webkit.org/show_bug.cgi?id=40627
 
+        Part 3 - Refactor storeNewestCache to allow Failure Reason Output
+
+        Storing can result in an error in a number of reasons. Previously
+        the reasons were global and binary and could be determined by
+        checking ApplicationCacheStorage state. Now, with per-origin quotas
+        a per-origin quota can cause a failure that is not in global state.
+        Current failure reasons are:
+
+          OriginQuotaReached = per-origin quota reached, no storage is allowed.
+          TotalQuotaReached  = database quota reached, no storage is allowed.
+          DiskOrOperationFailure = SQL error such as failed prepare or query. Not expected to happen.
+
+        This part provides an implementation of storeNewestCache for those
+        that care about the failure reason, and not just if it succeeded
+        or not. This moves the final origin quota check into the transaction.
+
+        * loader/appcache/ApplicationCache.h: style fix for forwarding headers.
+        * loader/appcache/ApplicationCacheGroup.cpp:
+        (WebCore::ApplicationCacheGroup::checkIfLoadIsComplete): move origin quota check into storeNewestCache's SQL transaction.
+        * loader/appcache/ApplicationCacheStorage.cpp:
+        (WebCore::ApplicationCacheStorage::storeNewestCache): old implementation calls the new implementation ignoring failure reason.
+        (WebCore::ApplicationCacheStorage::storeNewestCache): new implementation provides a failure reason in case of failure.
+        * loader/appcache/ApplicationCacheStorage.h:
+        (WebCore::ApplicationCacheStorage::): added FailureReason enum and storeNewestCache allowing it.
+
+2010-07-30  Joseph Pecoraro  <joepeck at webkit.org>
+
+        Reviewed by David Kilzer.
+
+        Limit ApplicationCache Total and Per-Origin Storage Capacity (Quotas)
+        https://bugs.webkit.org/show_bug.cgi?id=40627
+
         Part 2 - Update Schema and enforce Per-Origin Quotas
 
         Added an "Origins" table to the application cache databases.
diff --git a/WebCore/loader/appcache/ApplicationCache.h b/WebCore/loader/appcache/ApplicationCache.h
index 08e2dd3..d6e15ed 100644
--- a/WebCore/loader/appcache/ApplicationCache.h
+++ b/WebCore/loader/appcache/ApplicationCache.h
@@ -41,7 +41,6 @@ class ApplicationCacheGroup;
 class ApplicationCacheResource;
 class DocumentLoader;
 class KURL;
-
 class ResourceRequest;
 
 typedef Vector<std::pair<KURL, KURL> > FallbackURLVector;
diff --git a/WebCore/loader/appcache/ApplicationCacheGroup.cpp b/WebCore/loader/appcache/ApplicationCacheGroup.cpp
index a8687c6..bbfc676 100644
--- a/WebCore/loader/appcache/ApplicationCacheGroup.cpp
+++ b/WebCore/loader/appcache/ApplicationCacheGroup.cpp
@@ -880,19 +880,10 @@ void ApplicationCacheGroup::checkIfLoadIsComplete()
             ASSERT(cacheStorage().isMaximumSizeReached() && m_calledReachedMaxAppCacheSize);
         }
 
+        ApplicationCacheStorage::FailureReason failureReason;
         RefPtr<ApplicationCache> oldNewestCache = (m_newestCache == m_cacheBeingUpdated) ? 0 : m_newestCache;
-
-        // Check one more time, before committing to the new cache, if the cache will fit in the quota.
-        int64_t remainingSpaceInOrigin;
-        if (cacheStorage().remainingSizeForOriginExcludingCache(m_origin.get(), oldNewestCache.get(), remainingSpaceInOrigin)) {
-            if (m_cacheBeingUpdated->estimatedSizeInStorage() > remainingSpaceInOrigin) {
-                cacheUpdateFailed();
-                break;
-            }
-        }
-
         setNewestCache(m_cacheBeingUpdated.release());
-        if (cacheStorage().storeNewestCache(this)) {
+        if (cacheStorage().storeNewestCache(this, oldNewestCache.get(), failureReason)) {
             // New cache stored, now remove the old cache.
             if (oldNewestCache)
                 cacheStorage().remove(oldNewestCache.get());
@@ -904,7 +895,15 @@ void ApplicationCacheGroup::checkIfLoadIsComplete()
             // Fire the success event.
             postListenerTask(isUpgradeAttempt ? ApplicationCacheHost::UPDATEREADY_EVENT : ApplicationCacheHost::CACHED_EVENT, m_associatedDocumentLoaders);
         } else {
-            if (cacheStorage().isMaximumSizeReached() && !m_calledReachedMaxAppCacheSize) {
+            if (failureReason == ApplicationCacheStorage::OriginQuotaReached) {
+                // We ran out of space for this origin. Roll back to previous state.
+                if (oldNewestCache)
+                    setNewestCache(oldNewestCache.release());
+                cacheUpdateFailed();
+                return;
+            }
+
+            if (failureReason == ApplicationCacheStorage::TotalQuotaReached && !m_calledReachedMaxAppCacheSize) {
                 // We ran out of space. All the changes in the cache storage have
                 // been rolled back. We roll back to the previous state in here,
                 // as well, call the chrome client asynchronously and retry to
@@ -918,30 +917,30 @@ void ApplicationCacheGroup::checkIfLoadIsComplete()
                 }
                 scheduleReachedMaxAppCacheSizeCallback();
                 return;
+            }
+
+            // Run the "cache failure steps"
+            // Fire the error events to all pending master entries, as well any other cache hosts
+            // currently associated with a cache in this group.
+            postListenerTask(ApplicationCacheHost::ERROR_EVENT, m_associatedDocumentLoaders);
+            // Disassociate the pending master entries from the failed new cache. Note that
+            // all other loaders in the m_associatedDocumentLoaders are still associated with
+            // some other cache in this group. They are not associated with the failed new cache.
+
+            // Need to copy loaders, because the cache group may be destroyed at the end of iteration.
+            Vector<DocumentLoader*> loaders;
+            copyToVector(m_pendingMasterResourceLoaders, loaders);
+            size_t count = loaders.size();
+            for (size_t i = 0; i != count; ++i)
+                disassociateDocumentLoader(loaders[i]); // This can delete this group.
+
+            // Reinstate the oldNewestCache, if there was one.
+            if (oldNewestCache) {
+                // This will discard the failed new cache.
+                setNewestCache(oldNewestCache.release());
             } else {
-                // Run the "cache failure steps"
-                // Fire the error events to all pending master entries, as well any other cache hosts
-                // currently associated with a cache in this group.
-                postListenerTask(ApplicationCacheHost::ERROR_EVENT, m_associatedDocumentLoaders);
-                // Disassociate the pending master entries from the failed new cache. Note that
-                // all other loaders in the m_associatedDocumentLoaders are still associated with
-                // some other cache in this group. They are not associated with the failed new cache.
-
-                // Need to copy loaders, because the cache group may be destroyed at the end of iteration.
-                Vector<DocumentLoader*> loaders;
-                copyToVector(m_pendingMasterResourceLoaders, loaders);
-                size_t count = loaders.size();
-                for (size_t i = 0; i != count; ++i)
-                    disassociateDocumentLoader(loaders[i]); // This can delete this group.
-
-                // Reinstate the oldNewestCache, if there was one.
-                if (oldNewestCache) {
-                    // This will discard the failed new cache.
-                    setNewestCache(oldNewestCache.release());
-                } else {
-                    // We must have been deleted by the last call to disassociateDocumentLoader().
-                    return;
-                }
+                // We must have been deleted by the last call to disassociateDocumentLoader().
+                return;
             }
         }
         break;
diff --git a/WebCore/loader/appcache/ApplicationCacheStorage.cpp b/WebCore/loader/appcache/ApplicationCacheStorage.cpp
index 8842142..eb72331 100644
--- a/WebCore/loader/appcache/ApplicationCacheStorage.cpp
+++ b/WebCore/loader/appcache/ApplicationCacheStorage.cpp
@@ -858,7 +858,7 @@ bool ApplicationCacheStorage::store(ApplicationCacheResource* resource, Applicat
     return true;
 }
 
-bool ApplicationCacheStorage::storeNewestCache(ApplicationCacheGroup* group)
+bool ApplicationCacheStorage::storeNewestCache(ApplicationCacheGroup* group, ApplicationCache* oldCache, FailureReason& failureReason)
 {
     openDatabase(true);
 
@@ -872,11 +872,21 @@ bool ApplicationCacheStorage::storeNewestCache(ApplicationCacheGroup* group)
     
     storeCacheTransaction.begin();
 
+    // Check if this would reach the per-origin quota.
+    int64_t remainingSpaceInOrigin;
+    if (remainingSizeForOriginExcludingCache(group->origin(), oldCache, remainingSpaceInOrigin)) {
+        if (remainingSpaceInOrigin < group->newestCache()->estimatedSizeInStorage()) {
+            failureReason = OriginQuotaReached;
+            return false;
+        }
+    }
+
     GroupStorageIDJournal groupStorageIDJournal;
     if (!group->storageID()) {
         // Store the group
         if (!store(group, &groupStorageIDJournal)) {
             checkForMaxSizeReached();
+            failureReason = isMaximumSizeReached() ? TotalQuotaReached : DiskOrOperationFailure;
             return false;
         }
     }
@@ -893,20 +903,25 @@ bool ApplicationCacheStorage::storeNewestCache(ApplicationCacheGroup* group)
     // Store the newest cache
     if (!store(group->newestCache(), &resourceStorageIDJournal)) {
         checkForMaxSizeReached();
+        failureReason = isMaximumSizeReached() ? TotalQuotaReached : DiskOrOperationFailure;
         return false;
     }
     
     // Update the newest cache in the group.
     
     SQLiteStatement statement(m_database, "UPDATE CacheGroups SET newestCache=? WHERE id=?");
-    if (statement.prepare() != SQLResultOk)
+    if (statement.prepare() != SQLResultOk) {
+        failureReason = DiskOrOperationFailure;
         return false;
+    }
     
     statement.bindInt64(1, group->newestCache()->storageID());
     statement.bindInt64(2, group->storageID());
     
-    if (!executeStatement(statement))
+    if (!executeStatement(statement)) {
+        failureReason = DiskOrOperationFailure;
         return false;
+    }
     
     groupStorageIDJournal.commit();
     resourceStorageIDJournal.commit();
@@ -914,6 +929,13 @@ bool ApplicationCacheStorage::storeNewestCache(ApplicationCacheGroup* group)
     return true;
 }
 
+bool ApplicationCacheStorage::storeNewestCache(ApplicationCacheGroup* group)
+{
+    // Ignore the reason for failing, just attempt the store.
+    FailureReason ignoredFailureReason;
+    return storeNewestCache(group, 0, ignoredFailureReason);
+}
+
 static inline void parseHeader(const UChar* header, size_t headerLength, ResourceResponse& response)
 {
     int pos = find(header, headerLength, ':');
diff --git a/WebCore/loader/appcache/ApplicationCacheStorage.h b/WebCore/loader/appcache/ApplicationCacheStorage.h
index 1d43084..ec22800 100644
--- a/WebCore/loader/appcache/ApplicationCacheStorage.h
+++ b/WebCore/loader/appcache/ApplicationCacheStorage.h
@@ -47,6 +47,12 @@ class SecurityOrigin;
 
 class ApplicationCacheStorage : public Noncopyable {
 public:
+    enum FailureReason {
+        OriginQuotaReached,
+        TotalQuotaReached,
+        DiskOrOperationFailure
+    };
+
     void setCacheDirectory(const String&);
     const String& cacheDirectory() const;
     
@@ -68,6 +74,7 @@ public:
     void cacheGroupDestroyed(ApplicationCacheGroup*);
     void cacheGroupMadeObsolete(ApplicationCacheGroup*);
         
+    bool storeNewestCache(ApplicationCacheGroup*, ApplicationCache* oldCache, FailureReason& failureReason);
     bool storeNewestCache(ApplicationCacheGroup*); // Updates the cache group, but doesn't remove old cache.
     bool store(ApplicationCacheResource*, ApplicationCache*);
     bool storeUpdatedType(ApplicationCacheResource*, ApplicationCache*);

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list