| 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_)) { | 
|  | 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 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 | 
| OLD | NEW | 
|---|