Changeset 64399 in webkit
- Timestamp:
- Jul 30, 2010 7:22:25 PM (14 years ago)
- Location:
- trunk/WebCore
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog
r64398 r64399 1 2010-07-30 Joseph Pecoraro <joepeck@webkit.org> 2 3 Reviewed by David Kilzer. 4 5 Limit ApplicationCache Total and Per-Origin Storage Capacity (Quotas) 6 https://bugs.webkit.org/show_bug.cgi?id=40627 7 8 Part 3 - Refactor storeNewestCache to allow Failure Reason Output 9 10 Storing can result in an error in a number of reasons. Previously 11 the reasons were global and binary and could be determined by 12 checking ApplicationCacheStorage state. Now, with per-origin quotas 13 a per-origin quota can cause a failure that is not in global state. 14 Current failure reasons are: 15 16 OriginQuotaReached = per-origin quota reached, no storage is allowed. 17 TotalQuotaReached = database quota reached, no storage is allowed. 18 DiskOrOperationFailure = SQL error such as failed prepare or query. Not expected to happen. 19 20 This part provides an implementation of storeNewestCache for those 21 that care about the failure reason, and not just if it succeeded 22 or not. This moves the final origin quota check into the transaction. 23 24 * loader/appcache/ApplicationCache.h: style fix for forwarding headers. 25 * loader/appcache/ApplicationCacheGroup.cpp: 26 (WebCore::ApplicationCacheGroup::checkIfLoadIsComplete): move origin quota check into storeNewestCache's SQL transaction. 27 * loader/appcache/ApplicationCacheStorage.cpp: 28 (WebCore::ApplicationCacheStorage::storeNewestCache): old implementation calls the new implementation ignoring failure reason. 29 (WebCore::ApplicationCacheStorage::storeNewestCache): new implementation provides a failure reason in case of failure. 30 * loader/appcache/ApplicationCacheStorage.h: 31 (WebCore::ApplicationCacheStorage::): added FailureReason enum and storeNewestCache allowing it. 32 1 33 2010-07-30 Joseph Pecoraro <joepeck@webkit.org> 2 34 -
trunk/WebCore/loader/appcache/ApplicationCache.h
r50625 r64399 42 42 class DocumentLoader; 43 43 class KURL; 44 45 44 class ResourceRequest; 46 45 -
trunk/WebCore/loader/appcache/ApplicationCacheGroup.cpp
r64398 r64399 881 881 } 882 882 883 ApplicationCacheStorage::FailureReason failureReason; 883 884 RefPtr<ApplicationCache> oldNewestCache = (m_newestCache == m_cacheBeingUpdated) ? 0 : m_newestCache; 884 885 // Check one more time, before committing to the new cache, if the cache will fit in the quota.886 int64_t remainingSpaceInOrigin;887 if (cacheStorage().remainingSizeForOriginExcludingCache(m_origin.get(), oldNewestCache.get(), remainingSpaceInOrigin)) {888 if (m_cacheBeingUpdated->estimatedSizeInStorage() > remainingSpaceInOrigin) {889 cacheUpdateFailed();890 break;891 }892 }893 894 885 setNewestCache(m_cacheBeingUpdated.release()); 895 if (cacheStorage().storeNewestCache(this )) {886 if (cacheStorage().storeNewestCache(this, oldNewestCache.get(), failureReason)) { 896 887 // New cache stored, now remove the old cache. 897 888 if (oldNewestCache) … … 905 896 postListenerTask(isUpgradeAttempt ? ApplicationCacheHost::UPDATEREADY_EVENT : ApplicationCacheHost::CACHED_EVENT, m_associatedDocumentLoaders); 906 897 } else { 907 if (cacheStorage().isMaximumSizeReached() && !m_calledReachedMaxAppCacheSize) { 898 if (failureReason == ApplicationCacheStorage::OriginQuotaReached) { 899 // We ran out of space for this origin. Roll back to previous state. 900 if (oldNewestCache) 901 setNewestCache(oldNewestCache.release()); 902 cacheUpdateFailed(); 903 return; 904 } 905 906 if (failureReason == ApplicationCacheStorage::TotalQuotaReached && !m_calledReachedMaxAppCacheSize) { 908 907 // We ran out of space. All the changes in the cache storage have 909 908 // been rolled back. We roll back to the previous state in here, … … 919 918 scheduleReachedMaxAppCacheSizeCallback(); 920 919 return; 920 } 921 922 // Run the "cache failure steps" 923 // Fire the error events to all pending master entries, as well any other cache hosts 924 // currently associated with a cache in this group. 925 postListenerTask(ApplicationCacheHost::ERROR_EVENT, m_associatedDocumentLoaders); 926 // Disassociate the pending master entries from the failed new cache. Note that 927 // all other loaders in the m_associatedDocumentLoaders are still associated with 928 // some other cache in this group. They are not associated with the failed new cache. 929 930 // Need to copy loaders, because the cache group may be destroyed at the end of iteration. 931 Vector<DocumentLoader*> loaders; 932 copyToVector(m_pendingMasterResourceLoaders, loaders); 933 size_t count = loaders.size(); 934 for (size_t i = 0; i != count; ++i) 935 disassociateDocumentLoader(loaders[i]); // This can delete this group. 936 937 // Reinstate the oldNewestCache, if there was one. 938 if (oldNewestCache) { 939 // This will discard the failed new cache. 940 setNewestCache(oldNewestCache.release()); 921 941 } else { 922 // Run the "cache failure steps" 923 // Fire the error events to all pending master entries, as well any other cache hosts 924 // currently associated with a cache in this group. 925 postListenerTask(ApplicationCacheHost::ERROR_EVENT, m_associatedDocumentLoaders); 926 // Disassociate the pending master entries from the failed new cache. Note that 927 // all other loaders in the m_associatedDocumentLoaders are still associated with 928 // some other cache in this group. They are not associated with the failed new cache. 929 930 // Need to copy loaders, because the cache group may be destroyed at the end of iteration. 931 Vector<DocumentLoader*> loaders; 932 copyToVector(m_pendingMasterResourceLoaders, loaders); 933 size_t count = loaders.size(); 934 for (size_t i = 0; i != count; ++i) 935 disassociateDocumentLoader(loaders[i]); // This can delete this group. 936 937 // Reinstate the oldNewestCache, if there was one. 938 if (oldNewestCache) { 939 // This will discard the failed new cache. 940 setNewestCache(oldNewestCache.release()); 941 } else { 942 // We must have been deleted by the last call to disassociateDocumentLoader(). 943 return; 944 } 942 // We must have been deleted by the last call to disassociateDocumentLoader(). 943 return; 945 944 } 946 945 } -
trunk/WebCore/loader/appcache/ApplicationCacheStorage.cpp
r64398 r64399 859 859 } 860 860 861 bool ApplicationCacheStorage::storeNewestCache(ApplicationCacheGroup* group )861 bool ApplicationCacheStorage::storeNewestCache(ApplicationCacheGroup* group, ApplicationCache* oldCache, FailureReason& failureReason) 862 862 { 863 863 openDatabase(true); … … 872 872 873 873 storeCacheTransaction.begin(); 874 875 // Check if this would reach the per-origin quota. 876 int64_t remainingSpaceInOrigin; 877 if (remainingSizeForOriginExcludingCache(group->origin(), oldCache, remainingSpaceInOrigin)) { 878 if (remainingSpaceInOrigin < group->newestCache()->estimatedSizeInStorage()) { 879 failureReason = OriginQuotaReached; 880 return false; 881 } 882 } 874 883 875 884 GroupStorageIDJournal groupStorageIDJournal; … … 878 887 if (!store(group, &groupStorageIDJournal)) { 879 888 checkForMaxSizeReached(); 889 failureReason = isMaximumSizeReached() ? TotalQuotaReached : DiskOrOperationFailure; 880 890 return false; 881 891 } … … 894 904 if (!store(group->newestCache(), &resourceStorageIDJournal)) { 895 905 checkForMaxSizeReached(); 906 failureReason = isMaximumSizeReached() ? TotalQuotaReached : DiskOrOperationFailure; 896 907 return false; 897 908 } … … 900 911 901 912 SQLiteStatement statement(m_database, "UPDATE CacheGroups SET newestCache=? WHERE id=?"); 902 if (statement.prepare() != SQLResultOk) 903 return false; 913 if (statement.prepare() != SQLResultOk) { 914 failureReason = DiskOrOperationFailure; 915 return false; 916 } 904 917 905 918 statement.bindInt64(1, group->newestCache()->storageID()); 906 919 statement.bindInt64(2, group->storageID()); 907 920 908 if (!executeStatement(statement)) 909 return false; 921 if (!executeStatement(statement)) { 922 failureReason = DiskOrOperationFailure; 923 return false; 924 } 910 925 911 926 groupStorageIDJournal.commit(); … … 913 928 storeCacheTransaction.commit(); 914 929 return true; 930 } 931 932 bool ApplicationCacheStorage::storeNewestCache(ApplicationCacheGroup* group) 933 { 934 // Ignore the reason for failing, just attempt the store. 935 FailureReason ignoredFailureReason; 936 return storeNewestCache(group, 0, ignoredFailureReason); 915 937 } 916 938 -
trunk/WebCore/loader/appcache/ApplicationCacheStorage.h
r64398 r64399 48 48 class ApplicationCacheStorage : public Noncopyable { 49 49 public: 50 enum FailureReason { 51 OriginQuotaReached, 52 TotalQuotaReached, 53 DiskOrOperationFailure 54 }; 55 50 56 void setCacheDirectory(const String&); 51 57 const String& cacheDirectory() const; … … 69 75 void cacheGroupMadeObsolete(ApplicationCacheGroup*); 70 76 77 bool storeNewestCache(ApplicationCacheGroup*, ApplicationCache* oldCache, FailureReason& failureReason); 71 78 bool storeNewestCache(ApplicationCacheGroup*); // Updates the cache group, but doesn't remove old cache. 72 79 bool store(ApplicationCacheResource*, ApplicationCache*);
Note: See TracChangeset
for help on using the changeset viewer.