| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/appcache/appcache_storage_impl.h" | 5 #include "webkit/appcache/appcache_storage_impl.h" |
| 6 | 6 |
| 7 #include <set> | 7 #include <set> |
| 8 | 8 |
| 9 #include "base/file_util.h" | 9 #include "base/file_util.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/message_loop.h" | 11 #include "base/message_loop.h" |
| 12 #include "base/stl_util.h" | 12 #include "base/stl_util.h" |
| 13 #include "base/string_util.h" | 13 #include "base/string_util.h" |
| 14 #include "net/base/cache_type.h" | 14 #include "net/base/cache_type.h" |
| 15 #include "net/base/net_errors.h" | 15 #include "net/base/net_errors.h" |
| 16 #include "sql/connection.h" | 16 #include "sql/connection.h" |
| 17 #include "sql/transaction.h" | 17 #include "sql/transaction.h" |
| 18 #include "webkit/appcache/appcache.h" | 18 #include "webkit/appcache/appcache.h" |
| 19 #include "webkit/appcache/appcache_database.h" | 19 #include "webkit/appcache/appcache_database.h" |
| 20 #include "webkit/appcache/appcache_entry.h" | 20 #include "webkit/appcache/appcache_entry.h" |
| 21 #include "webkit/appcache/appcache_group.h" | 21 #include "webkit/appcache/appcache_group.h" |
| 22 #include "webkit/appcache/appcache_histograms.h" | 22 #include "webkit/appcache/appcache_histograms.h" |
| 23 #include "webkit/appcache/appcache_quota_client.h" | 23 #include "webkit/appcache/appcache_quota_client.h" |
| 24 #include "webkit/appcache/appcache_response.h" | 24 #include "webkit/appcache/appcache_response.h" |
| 25 #include "webkit/appcache/appcache_service.h" | 25 #include "webkit/appcache/appcache_service.h" |
| 26 #include "webkit/appcache/appcache_thread.h" | |
| 27 #include "webkit/quota/quota_client.h" | 26 #include "webkit/quota/quota_client.h" |
| 28 #include "webkit/quota/quota_manager.h" | 27 #include "webkit/quota/quota_manager.h" |
| 29 #include "webkit/quota/special_storage_policy.h" | 28 #include "webkit/quota/special_storage_policy.h" |
| 30 | 29 |
| 31 namespace appcache { | 30 namespace appcache { |
| 32 | 31 |
| 33 // Hard coded default when not using quota management. | 32 // Hard coded default when not using quota management. |
| 34 static const int kDefaultQuota = 5 * 1024 * 1024; | 33 static const int kDefaultQuota = 5 * 1024 * 1024; |
| 35 | 34 |
| 36 static const int kMaxDiskCacheSize = 250 * 1024 * 1024; | 35 static const int kMaxDiskCacheSize = 250 * 1024 * 1024; |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 118 } | 117 } |
| 119 | 118 |
| 120 } // namespace | 119 } // namespace |
| 121 | 120 |
| 122 // DatabaseTask ----------------------------------------- | 121 // DatabaseTask ----------------------------------------- |
| 123 | 122 |
| 124 class AppCacheStorageImpl::DatabaseTask | 123 class AppCacheStorageImpl::DatabaseTask |
| 125 : public base::RefCountedThreadSafe<DatabaseTask> { | 124 : public base::RefCountedThreadSafe<DatabaseTask> { |
| 126 public: | 125 public: |
| 127 explicit DatabaseTask(AppCacheStorageImpl* storage) | 126 explicit DatabaseTask(AppCacheStorageImpl* storage) |
| 128 : storage_(storage), database_(storage->database_) {} | 127 : storage_(storage), database_(storage->database_), |
| 128 io_thread_(base::MessageLoopProxy::current()) { |
| 129 DCHECK(io_thread_); |
| 130 } |
| 129 | 131 |
| 130 virtual ~DatabaseTask() {} | 132 virtual ~DatabaseTask() {} |
| 131 | 133 |
| 132 void AddDelegate(DelegateReference* delegate_reference) { | 134 void AddDelegate(DelegateReference* delegate_reference) { |
| 133 delegates_.push_back(make_scoped_refptr(delegate_reference)); | 135 delegates_.push_back(make_scoped_refptr(delegate_reference)); |
| 134 } | 136 } |
| 135 | 137 |
| 136 // Schedules a task to be Run() on the DB thread. Tasks | 138 // Schedules a task to be Run() on the DB thread. Tasks |
| 137 // are run in the order in which they are scheduled. | 139 // are run in the order in which they are scheduled. |
| 138 void Schedule(); | 140 void Schedule(); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 155 | 157 |
| 156 protected: | 158 protected: |
| 157 AppCacheStorageImpl* storage_; | 159 AppCacheStorageImpl* storage_; |
| 158 AppCacheDatabase* database_; | 160 AppCacheDatabase* database_; |
| 159 DelegateReferenceVector delegates_; | 161 DelegateReferenceVector delegates_; |
| 160 | 162 |
| 161 private: | 163 private: |
| 162 void CallRun(); | 164 void CallRun(); |
| 163 void CallRunCompleted(); | 165 void CallRunCompleted(); |
| 164 void CallDisableStorage(); | 166 void CallDisableStorage(); |
| 167 |
| 168 scoped_refptr<base::MessageLoopProxy> io_thread_; |
| 165 }; | 169 }; |
| 166 | 170 |
| 167 void AppCacheStorageImpl::DatabaseTask::Schedule() { | 171 void AppCacheStorageImpl::DatabaseTask::Schedule() { |
| 168 DCHECK(storage_); | 172 DCHECK(storage_); |
| 169 DCHECK(AppCacheThread::CurrentlyOn(AppCacheThread::io())); | 173 DCHECK(io_thread_->BelongsToCurrentThread()); |
| 170 if (AppCacheThread::PostTask(AppCacheThread::db(), FROM_HERE, | 174 if (storage_->db_thread_->PostTask(FROM_HERE, |
| 171 NewRunnableMethod(this, &DatabaseTask::CallRun))) { | 175 NewRunnableMethod(this, &DatabaseTask::CallRun))) { |
| 172 storage_->scheduled_database_tasks_.push_back(this); | 176 storage_->scheduled_database_tasks_.push_back(this); |
| 173 } else { | 177 } else { |
| 174 NOTREACHED() << "The database thread is not running."; | 178 NOTREACHED() << "The database thread is not running."; |
| 175 } | 179 } |
| 176 } | 180 } |
| 177 | 181 |
| 178 void AppCacheStorageImpl::DatabaseTask::CancelCompletion() { | 182 void AppCacheStorageImpl::DatabaseTask::CancelCompletion() { |
| 179 DCHECK(AppCacheThread::CurrentlyOn(AppCacheThread::io())); | 183 DCHECK(io_thread_->BelongsToCurrentThread()); |
| 180 delegates_.clear(); | 184 delegates_.clear(); |
| 181 storage_ = NULL; | 185 storage_ = NULL; |
| 182 } | 186 } |
| 183 | 187 |
| 184 void AppCacheStorageImpl::DatabaseTask::CallRun() { | 188 void AppCacheStorageImpl::DatabaseTask::CallRun() { |
| 185 DCHECK(AppCacheThread::CurrentlyOn(AppCacheThread::db())); | 189 DCHECK(!io_thread_->BelongsToCurrentThread()); |
| 186 if (!database_->is_disabled()) { | 190 if (!database_->is_disabled()) { |
| 187 Run(); | 191 Run(); |
| 188 if (database_->is_disabled()) { | 192 if (database_->is_disabled()) { |
| 189 AppCacheThread::PostTask(AppCacheThread::io(), FROM_HERE, | 193 io_thread_->PostTask(FROM_HERE, |
| 190 NewRunnableMethod(this, &DatabaseTask::CallDisableStorage)); | 194 NewRunnableMethod(this, &DatabaseTask::CallDisableStorage)); |
| 191 } | 195 } |
| 192 } | 196 } |
| 193 AppCacheThread::PostTask(AppCacheThread::io(), FROM_HERE, | 197 io_thread_->PostTask(FROM_HERE, |
| 194 NewRunnableMethod(this, &DatabaseTask::CallRunCompleted)); | 198 NewRunnableMethod(this, &DatabaseTask::CallRunCompleted)); |
| 195 } | 199 } |
| 196 | 200 |
| 197 void AppCacheStorageImpl::DatabaseTask::CallRunCompleted() { | 201 void AppCacheStorageImpl::DatabaseTask::CallRunCompleted() { |
| 198 if (storage_) { | 202 if (storage_) { |
| 199 DCHECK(AppCacheThread::CurrentlyOn(AppCacheThread::io())); | 203 DCHECK(io_thread_->BelongsToCurrentThread()); |
| 200 DCHECK(storage_->scheduled_database_tasks_.front() == this); | 204 DCHECK(storage_->scheduled_database_tasks_.front() == this); |
| 201 storage_->scheduled_database_tasks_.pop_front(); | 205 storage_->scheduled_database_tasks_.pop_front(); |
| 202 RunCompleted(); | 206 RunCompleted(); |
| 203 delegates_.clear(); | 207 delegates_.clear(); |
| 204 } | 208 } |
| 205 } | 209 } |
| 206 | 210 |
| 207 void AppCacheStorageImpl::DatabaseTask::CallDisableStorage() { | 211 void AppCacheStorageImpl::DatabaseTask::CallDisableStorage() { |
| 208 if (storage_) { | 212 if (storage_) { |
| 209 DCHECK(AppCacheThread::CurrentlyOn(AppCacheThread::io())); | 213 DCHECK(io_thread_->BelongsToCurrentThread()); |
| 210 storage_->Disable(); | 214 storage_->Disable(); |
| 211 } | 215 } |
| 212 } | 216 } |
| 213 | 217 |
| 214 // InitTask ------- | 218 // InitTask ------- |
| 215 | 219 |
| 216 class AppCacheStorageImpl::InitTask : public DatabaseTask { | 220 class AppCacheStorageImpl::InitTask : public DatabaseTask { |
| 217 public: | 221 public: |
| 218 explicit InitTask(AppCacheStorageImpl* storage) | 222 explicit InitTask(AppCacheStorageImpl* storage) |
| 219 : DatabaseTask(storage), last_group_id_(0), | 223 : DatabaseTask(storage), last_group_id_(0), |
| (...skipping 931 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1151 STLDeleteElements(&pending_simple_tasks_); | 1155 STLDeleteElements(&pending_simple_tasks_); |
| 1152 | 1156 |
| 1153 std::for_each(pending_quota_queries_.begin(), | 1157 std::for_each(pending_quota_queries_.begin(), |
| 1154 pending_quota_queries_.end(), | 1158 pending_quota_queries_.end(), |
| 1155 std::mem_fun(&DatabaseTask::CancelCompletion)); | 1159 std::mem_fun(&DatabaseTask::CancelCompletion)); |
| 1156 std::for_each(scheduled_database_tasks_.begin(), | 1160 std::for_each(scheduled_database_tasks_.begin(), |
| 1157 scheduled_database_tasks_.end(), | 1161 scheduled_database_tasks_.end(), |
| 1158 std::mem_fun(&DatabaseTask::CancelCompletion)); | 1162 std::mem_fun(&DatabaseTask::CancelCompletion)); |
| 1159 | 1163 |
| 1160 if (database_) { | 1164 if (database_) { |
| 1161 AppCacheThread::PostTask( | 1165 db_thread_->PostTask( |
| 1162 AppCacheThread::db(), | |
| 1163 FROM_HERE, | 1166 FROM_HERE, |
| 1164 NewRunnableFunction( | 1167 NewRunnableFunction( |
| 1165 CleanUpOnDatabaseThread, | 1168 CleanUpOnDatabaseThread, |
| 1166 database_, | 1169 database_, |
| 1167 make_scoped_refptr(service_->special_storage_policy()), | 1170 make_scoped_refptr(service_->special_storage_policy()), |
| 1168 service()->clear_local_state_on_exit())); | 1171 service()->clear_local_state_on_exit())); |
| 1169 } | 1172 } |
| 1170 } | 1173 } |
| 1171 | 1174 |
| 1172 void AppCacheStorageImpl::Initialize(const FilePath& cache_directory, | 1175 void AppCacheStorageImpl::Initialize(const FilePath& cache_directory, |
| 1176 base::MessageLoopProxy* db_thread, |
| 1173 base::MessageLoopProxy* cache_thread) { | 1177 base::MessageLoopProxy* cache_thread) { |
| 1178 DCHECK(db_thread); |
| 1179 |
| 1174 cache_directory_ = cache_directory; | 1180 cache_directory_ = cache_directory; |
| 1175 cache_thread_ = cache_thread; | |
| 1176 is_incognito_ = cache_directory_.empty(); | 1181 is_incognito_ = cache_directory_.empty(); |
| 1177 | 1182 |
| 1178 FilePath db_file_path; | 1183 FilePath db_file_path; |
| 1179 if (!is_incognito_) | 1184 if (!is_incognito_) |
| 1180 db_file_path = cache_directory_.Append(kAppCacheDatabaseName); | 1185 db_file_path = cache_directory_.Append(kAppCacheDatabaseName); |
| 1181 database_ = new AppCacheDatabase(db_file_path); | 1186 database_ = new AppCacheDatabase(db_file_path); |
| 1182 | 1187 |
| 1188 db_thread_ = db_thread; |
| 1189 cache_thread_ = cache_thread; |
| 1190 |
| 1183 scoped_refptr<InitTask> task(new InitTask(this)); | 1191 scoped_refptr<InitTask> task(new InitTask(this)); |
| 1184 task->Schedule(); | 1192 task->Schedule(); |
| 1185 } | 1193 } |
| 1186 | 1194 |
| 1187 void AppCacheStorageImpl::Disable() { | 1195 void AppCacheStorageImpl::Disable() { |
| 1188 if (is_disabled_) | 1196 if (is_disabled_) |
| 1189 return; | 1197 return; |
| 1190 VLOG(1) << "Disabling appcache storage."; | 1198 VLOG(1) << "Disabling appcache storage."; |
| 1191 is_disabled_ = true; | 1199 is_disabled_ = true; |
| 1192 ClearUsageMapAndNotify(); | 1200 ClearUsageMapAndNotify(); |
| (...skipping 435 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1628 LOG(ERROR) << "Failed to open the appcache diskcache."; | 1636 LOG(ERROR) << "Failed to open the appcache diskcache."; |
| 1629 AppCacheHistograms::CountInitResult(AppCacheHistograms::DISK_CACHE_ERROR); | 1637 AppCacheHistograms::CountInitResult(AppCacheHistograms::DISK_CACHE_ERROR); |
| 1630 | 1638 |
| 1631 // We're unable to open the disk cache, this is a fatal error that we can't | 1639 // We're unable to open the disk cache, this is a fatal error that we can't |
| 1632 // really recover from. We handle it by disabling the appcache for this | 1640 // really recover from. We handle it by disabling the appcache for this |
| 1633 // browser session and deleting the directory on disk. The next browser | 1641 // browser session and deleting the directory on disk. The next browser |
| 1634 // session should start with a clean slate. | 1642 // session should start with a clean slate. |
| 1635 Disable(); | 1643 Disable(); |
| 1636 if (!is_incognito_) { | 1644 if (!is_incognito_) { |
| 1637 VLOG(1) << "Deleting existing appcache data and starting over."; | 1645 VLOG(1) << "Deleting existing appcache data and starting over."; |
| 1638 AppCacheThread::PostTask(AppCacheThread::db(), FROM_HERE, | 1646 db_thread_->PostTask(FROM_HERE, |
| 1639 NewRunnableFunction(DeleteDirectory, cache_directory_)); | 1647 NewRunnableFunction(DeleteDirectory, cache_directory_)); |
| 1640 } | 1648 } |
| 1641 } | 1649 } |
| 1642 } | 1650 } |
| 1643 | 1651 |
| 1644 } // namespace appcache | 1652 } // namespace appcache |
| OLD | NEW |