Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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_)) { | |
|
kinuko
2014/01/29 07:40:30
nit: no space between if and '('
| |
| 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 Loading... | |
| 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 Loading... | |
| 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 namespace { |
| 1827 service_->Reinitialize(); | 1841 |
| 1828 // note: 'this' may be deleted during reinit. | 1842 void Noop() { |
| 1843 // Function body is intentionally empty. | |
| 1844 } | |
| 1845 | |
| 1846 } | |
| 1847 | |
| 1848 void AppCacheStorageImpl::DeleteAndStartOver() { | |
| 1849 DCHECK(is_disabled_); | |
| 1850 if (!is_incognito_) { | |
| 1851 VLOG(1) << "Deleting existing appcache data and starting over."; | |
| 1852 // We can have tasks in flight to close file handles on both the db | |
| 1853 // and cache threads, we need to allow those tasks to cycle thru | |
| 1854 // prior to deleting the files and calling reinit. | |
| 1855 cache_thread_->PostTaskAndReply( | |
| 1856 FROM_HERE, | |
| 1857 base::Bind(&Noop), | |
|
kinuko
2014/01/29 07:40:30
You can use base::DoNothing() in base/bind_helpers
michaeln
2014/01/29 20:44:16
oh, nice, thnx
| |
| 1858 base::Bind(&AppCacheStorageImpl::DeleteAndStartOverPart2, | |
| 1859 weak_factory_.GetWeakPtr())); | |
| 1860 } | |
| 1861 } | |
| 1862 | |
| 1863 void AppCacheStorageImpl::DeleteAndStartOverPart2() { | |
| 1864 db_thread_->PostTaskAndReply( | |
| 1865 FROM_HERE, | |
| 1866 base::Bind(base::IgnoreResult(&base::DeleteFile), | |
| 1867 cache_directory_, true), | |
| 1868 base::Bind(&AppCacheStorageImpl::CallScheduleReinitialize, | |
| 1869 weak_factory_.GetWeakPtr())); | |
| 1870 } | |
| 1871 | |
| 1872 void AppCacheStorageImpl::CallScheduleReinitialize() { | |
| 1873 service_->ScheduleReinitialize(); | |
| 1874 // note: 'this' may be deleted at this point. | |
| 1829 } | 1875 } |
| 1830 | 1876 |
| 1831 } // namespace appcache | 1877 } // namespace appcache |
| OLD | NEW |