Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(154)

Side by Side Diff: webkit/browser/appcache/appcache_storage_impl.cc

Issue 137493003: Appcache::OnCorruptionDetected handling (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "webkit/browser/appcache/appcache_storage_impl.h" 5 #include "webkit/browser/appcache/appcache_storage_impl.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <functional> 8 #include <functional>
9 #include <set> 9 #include <set>
10 #include <vector> 10 #include <vector>
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
167 friend class base::RefCountedThreadSafe<DatabaseTask>; 167 friend class base::RefCountedThreadSafe<DatabaseTask>;
168 virtual ~DatabaseTask() {} 168 virtual ~DatabaseTask() {}
169 169
170 AppCacheStorageImpl* storage_; 170 AppCacheStorageImpl* storage_;
171 AppCacheDatabase* database_; 171 AppCacheDatabase* database_;
172 DelegateReferenceVector delegates_; 172 DelegateReferenceVector delegates_;
173 173
174 private: 174 private:
175 void CallRun(base::TimeTicks schedule_time); 175 void CallRun(base::TimeTicks schedule_time);
176 void CallRunCompleted(base::TimeTicks schedule_time); 176 void CallRunCompleted(base::TimeTicks schedule_time);
177 void CallDisableStorage(); 177 void OnFatalError();
178 178
179 scoped_refptr<base::MessageLoopProxy> io_thread_; 179 scoped_refptr<base::MessageLoopProxy> io_thread_;
180 }; 180 };
181 181
182 void AppCacheStorageImpl::DatabaseTask::Schedule() { 182 void AppCacheStorageImpl::DatabaseTask::Schedule() {
183 DCHECK(storage_); 183 DCHECK(storage_);
184 DCHECK(io_thread_->BelongsToCurrentThread()); 184 DCHECK(io_thread_->BelongsToCurrentThread());
185 if (!storage_->database_) 185 if (!storage_->database_)
186 return; 186 return;
187 187
(...skipping 14 matching lines...) Expand all
202 202
203 void AppCacheStorageImpl::DatabaseTask::CallRun( 203 void AppCacheStorageImpl::DatabaseTask::CallRun(
204 base::TimeTicks schedule_time) { 204 base::TimeTicks schedule_time) {
205 AppCacheHistograms::AddTaskQueueTimeSample( 205 AppCacheHistograms::AddTaskQueueTimeSample(
206 base::TimeTicks::Now() - schedule_time); 206 base::TimeTicks::Now() - schedule_time);
207 if (!database_->is_disabled()) { 207 if (!database_->is_disabled()) {
208 base::TimeTicks run_time = base::TimeTicks::Now(); 208 base::TimeTicks run_time = base::TimeTicks::Now();
209 Run(); 209 Run();
210 AppCacheHistograms::AddTaskRunTimeSample( 210 AppCacheHistograms::AddTaskRunTimeSample(
211 base::TimeTicks::Now() - run_time); 211 base::TimeTicks::Now() - run_time);
212
213 if (database_->was_corruption_detected()) {
214 AppCacheHistograms::CountCorruptionDetected();
215 database_->Disable();
216 }
212 if (database_->is_disabled()) { 217 if (database_->is_disabled()) {
213 io_thread_->PostTask( 218 io_thread_->PostTask(
214 FROM_HERE, 219 FROM_HERE,
215 base::Bind(&DatabaseTask::CallDisableStorage, this)); 220 base::Bind(&DatabaseTask::OnFatalError, this));
216 } 221 }
217 } 222 }
218 io_thread_->PostTask( 223 io_thread_->PostTask(
219 FROM_HERE, 224 FROM_HERE,
220 base::Bind(&DatabaseTask::CallRunCompleted, this, 225 base::Bind(&DatabaseTask::CallRunCompleted, this,
221 base::TimeTicks::Now())); 226 base::TimeTicks::Now()));
222 } 227 }
223 228
224 void AppCacheStorageImpl::DatabaseTask::CallRunCompleted( 229 void AppCacheStorageImpl::DatabaseTask::CallRunCompleted(
225 base::TimeTicks schedule_time) { 230 base::TimeTicks schedule_time) {
226 AppCacheHistograms::AddCompletionQueueTimeSample( 231 AppCacheHistograms::AddCompletionQueueTimeSample(
227 base::TimeTicks::Now() - schedule_time); 232 base::TimeTicks::Now() - schedule_time);
228 if (storage_) { 233 if (storage_) {
229 DCHECK(io_thread_->BelongsToCurrentThread()); 234 DCHECK(io_thread_->BelongsToCurrentThread());
230 DCHECK(storage_->scheduled_database_tasks_.front() == this); 235 DCHECK(storage_->scheduled_database_tasks_.front() == this);
231 storage_->scheduled_database_tasks_.pop_front(); 236 storage_->scheduled_database_tasks_.pop_front();
232 base::TimeTicks run_time = base::TimeTicks::Now(); 237 base::TimeTicks run_time = base::TimeTicks::Now();
233 RunCompleted(); 238 RunCompleted();
234 AppCacheHistograms::AddCompletionRunTimeSample( 239 AppCacheHistograms::AddCompletionRunTimeSample(
235 base::TimeTicks::Now() - run_time); 240 base::TimeTicks::Now() - run_time);
236 delegates_.clear(); 241 delegates_.clear();
237 } 242 }
238 } 243 }
239 244
240 void AppCacheStorageImpl::DatabaseTask::CallDisableStorage() { 245 void AppCacheStorageImpl::DatabaseTask::OnFatalError() {
241 if (storage_) { 246 if (storage_) {
242 DCHECK(io_thread_->BelongsToCurrentThread()); 247 DCHECK(io_thread_->BelongsToCurrentThread());
243 storage_->Disable(); 248 storage_->Disable();
249 storage_->DeleteAndStartOver();
244 } 250 }
245 } 251 }
246 252
247 // InitTask ------- 253 // InitTask -------
248 254
249 class AppCacheStorageImpl::InitTask : public DatabaseTask { 255 class AppCacheStorageImpl::InitTask : public DatabaseTask {
250 public: 256 public:
251 explicit InitTask(AppCacheStorageImpl* storage) 257 explicit InitTask(AppCacheStorageImpl* storage)
252 : DatabaseTask(storage), last_group_id_(0), 258 : DatabaseTask(storage), last_group_id_(0),
253 last_cache_id_(0), last_response_id_(0), 259 last_cache_id_(0), last_response_id_(0),
254 last_deletable_response_rowid_(0) {} 260 last_deletable_response_rowid_(0) {
261 if (!storage->is_incognito_) {
262 db_file_path_ =
263 storage->cache_directory_.Append(kAppCacheDatabaseName);
264 disk_cache_directory_ =
265 storage->cache_directory_.Append(kDiskCacheDirectoryName);
266 }
267 }
255 268
256 // DatabaseTask: 269 // DatabaseTask:
257 virtual void Run() OVERRIDE; 270 virtual void Run() OVERRIDE;
258 virtual void RunCompleted() OVERRIDE; 271 virtual void RunCompleted() OVERRIDE;
259 272
260 protected: 273 protected:
261 virtual ~InitTask() {} 274 virtual ~InitTask() {}
262 275
263 private: 276 private:
277 base::FilePath db_file_path_;
278 base::FilePath disk_cache_directory_;
264 int64 last_group_id_; 279 int64 last_group_id_;
265 int64 last_cache_id_; 280 int64 last_cache_id_;
266 int64 last_response_id_; 281 int64 last_response_id_;
267 int64 last_deletable_response_rowid_; 282 int64 last_deletable_response_rowid_;
268 std::map<GURL, int64> usage_map_; 283 std::map<GURL, int64> usage_map_;
269 }; 284 };
270 285
271 void AppCacheStorageImpl::InitTask::Run() { 286 void AppCacheStorageImpl::InitTask::Run() {
287 // If there is no sql database, ensure there is no disk cache either.
288 if (!db_file_path_.empty() &&
289 !base::PathExists(db_file_path_) &&
290 base::DirectoryExists(disk_cache_directory_)) {
291 base::DeleteFile(disk_cache_directory_, true);
292 if (base::DirectoryExists(disk_cache_directory_)) {
293 database_->Disable(); // This triggers OnFatalError handling.
294 return;
295 }
296 }
297
272 database_->FindLastStorageIds( 298 database_->FindLastStorageIds(
273 &last_group_id_, &last_cache_id_, &last_response_id_, 299 &last_group_id_, &last_cache_id_, &last_response_id_,
274 &last_deletable_response_rowid_); 300 &last_deletable_response_rowid_);
275 database_->GetAllOriginUsage(&usage_map_); 301 database_->GetAllOriginUsage(&usage_map_);
276 } 302 }
277 303
278 void AppCacheStorageImpl::InitTask::RunCompleted() { 304 void AppCacheStorageImpl::InitTask::RunCompleted() {
279 storage_->last_group_id_ = last_group_id_; 305 storage_->last_group_id_ = last_group_id_;
280 storage_->last_cache_id_ = last_cache_id_; 306 storage_->last_cache_id_ = last_cache_id_;
281 storage_->last_response_id_ = last_response_id_; 307 storage_->last_response_id_ = last_response_id_;
(...skipping 624 matching lines...) Expand 10 before | Expand all | Expand 10 after
906 GURL preferred_manifest_url_; 932 GURL preferred_manifest_url_;
907 std::set<int64> cache_ids_in_use_; 933 std::set<int64> cache_ids_in_use_;
908 AppCacheEntry entry_; 934 AppCacheEntry entry_;
909 AppCacheEntry fallback_entry_; 935 AppCacheEntry fallback_entry_;
910 GURL namespace_entry_url_; 936 GURL namespace_entry_url_;
911 int64 cache_id_; 937 int64 cache_id_;
912 int64 group_id_; 938 int64 group_id_;
913 GURL manifest_url_; 939 GURL manifest_url_;
914 }; 940 };
915 941
916
917
918 void AppCacheStorageImpl::FindMainResponseTask::Run() { 942 void AppCacheStorageImpl::FindMainResponseTask::Run() {
919 // NOTE: The heuristics around choosing amoungst multiple candidates 943 // NOTE: The heuristics around choosing amoungst multiple candidates
920 // is underspecified, and just plain not fully understood. This needs 944 // is underspecified, and just plain not fully understood. This needs
921 // to be refined. 945 // to be refined.
922 946
923 // The 'preferred_manifest_url' is the url of the manifest associated 947 // The 'preferred_manifest_url' is the url of the manifest associated
924 // with the page that opened or embedded the page being loaded now. 948 // with the page that opened or embedded the page being loaded now.
925 // We have a strong preference to use resources from that cache. 949 // We have a strong preference to use resources from that cache.
926 // We also have a lesser bias to use resources from caches that are currently 950 // We also have a lesser bias to use resources from caches that are currently
927 // being used by other unrelated pages. 951 // being used by other unrelated pages.
(...skipping 858 matching lines...) Expand 10 before | Expand all | Expand 10 after
1786 } else { 1810 } else {
1787 rv = disk_cache_->InitWithDiskBackend( 1811 rv = disk_cache_->InitWithDiskBackend(
1788 cache_directory_.Append(kDiskCacheDirectoryName), 1812 cache_directory_.Append(kDiskCacheDirectoryName),
1789 kMaxDiskCacheSize, 1813 kMaxDiskCacheSize,
1790 false, 1814 false,
1791 cache_thread_.get(), 1815 cache_thread_.get(),
1792 base::Bind(&AppCacheStorageImpl::OnDiskCacheInitialized, 1816 base::Bind(&AppCacheStorageImpl::OnDiskCacheInitialized,
1793 base::Unretained(this))); 1817 base::Unretained(this)));
1794 } 1818 }
1795 1819
1796 // We should not keep this reference around.
1797 cache_thread_ = NULL;
1798
1799 if (rv != net::ERR_IO_PENDING) 1820 if (rv != net::ERR_IO_PENDING)
1800 OnDiskCacheInitialized(rv); 1821 OnDiskCacheInitialized(rv);
1801 } 1822 }
1802 return disk_cache_.get(); 1823 return disk_cache_.get();
1803 } 1824 }
1804 1825
1805 void AppCacheStorageImpl::OnDiskCacheInitialized(int rv) { 1826 void AppCacheStorageImpl::OnDiskCacheInitialized(int rv) {
1806 if (rv != net::OK) { 1827 if (rv != net::OK) {
1807 LOG(ERROR) << "Failed to open the appcache diskcache."; 1828 LOG(ERROR) << "Failed to open the appcache diskcache.";
1808 AppCacheHistograms::CountInitResult(AppCacheHistograms::DISK_CACHE_ERROR); 1829 AppCacheHistograms::CountInitResult(AppCacheHistograms::DISK_CACHE_ERROR);
1809 1830
1810 // We're unable to open the disk cache, this is a fatal error that we can't 1831 // We're unable to open the disk cache, this is a fatal error that we can't
1811 // really recover from. We handle it by temporarily disabling the appcache 1832 // really recover from. We handle it by temporarily disabling the appcache
1812 // deleting the directory on disk and reinitializing the appcache system. 1833 // deleting the directory on disk and reinitializing the appcache system.
1813 Disable(); 1834 Disable();
1814 if (!is_incognito_ && rv != net::ERR_ABORTED) { 1835 if (rv != net::ERR_ABORTED)
1815 VLOG(1) << "Deleting existing appcache data and starting over."; 1836 DeleteAndStartOver();
1816 db_thread_->PostTaskAndReply(
1817 FROM_HERE,
1818 base::Bind(base::IgnoreResult(&base::DeleteFile),
1819 cache_directory_, true),
1820 base::Bind(&AppCacheStorageImpl::CallReinitialize,
1821 weak_factory_.GetWeakPtr()));
1822 }
1823 } 1837 }
1824 } 1838 }
1825 1839
1826 void AppCacheStorageImpl::CallReinitialize() { 1840 void AppCacheStorageImpl::DeleteAndStartOver() {
1827 service_->Reinitialize(); 1841 DCHECK(is_disabled_);
1828 // note: 'this' may be deleted during reinit. 1842 if (!is_incognito_) {
1843 VLOG(1) << "Deleting existing appcache data and starting over.";
1844 // We can have tasks in flight to close file handles on both the db
1845 // and cache threads, we need to allow those tasks to cycle thru
1846 // prior to deleting the files and calling reinit.
1847 cache_thread_->PostTaskAndReply(
1848 FROM_HERE,
1849 base::Bind(&base::DoNothing),
1850 base::Bind(&AppCacheStorageImpl::DeleteAndStartOverPart2,
1851 weak_factory_.GetWeakPtr()));
1852 }
1853 }
1854
1855 void AppCacheStorageImpl::DeleteAndStartOverPart2() {
1856 db_thread_->PostTaskAndReply(
1857 FROM_HERE,
1858 base::Bind(base::IgnoreResult(&base::DeleteFile),
1859 cache_directory_, true),
1860 base::Bind(&AppCacheStorageImpl::CallScheduleReinitialize,
1861 weak_factory_.GetWeakPtr()));
1862 }
1863
1864 void AppCacheStorageImpl::CallScheduleReinitialize() {
1865 service_->ScheduleReinitialize();
1866 // note: 'this' may be deleted at this point.
1829 } 1867 }
1830 1868
1831 } // namespace appcache 1869 } // namespace appcache
OLDNEW
« no previous file with comments | « webkit/browser/appcache/appcache_storage_impl.h ('k') | webkit/browser/appcache/appcache_storage_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698