Chromium Code Reviews| 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_quota_client.h" | 5 #include "webkit/appcache/appcache_quota_client.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <map> | 8 #include <map> |
| 9 #include <set> | 9 #include <set> |
| 10 | 10 |
| 11 #include "base/bind.h" | |
| 11 #include "webkit/appcache/appcache_service.h" | 12 #include "webkit/appcache/appcache_service.h" |
| 12 | 13 |
| 13 using quota::QuotaClient; | 14 using quota::QuotaClient; |
| 14 | 15 |
| 15 namespace { | 16 namespace { |
| 16 quota::QuotaStatusCode NetErrorCodeToQuotaStatus(int code) { | 17 quota::QuotaStatusCode NetErrorCodeToQuotaStatus(int code) { |
| 17 if (code == net::OK) | 18 if (code == net::OK) |
| 18 return quota::kQuotaStatusOk; | 19 return quota::kQuotaStatusOk; |
| 19 else if (code == net::ERR_ABORTED) | 20 else if (code == net::ERR_ABORTED) |
| 20 return quota::kQuotaErrorAbort; | 21 return quota::kQuotaErrorAbort; |
| 21 else | 22 else |
| 22 return quota::kQuotaStatusUnknown; | 23 return quota::kQuotaStatusUnknown; |
| 23 } | 24 } |
| 25 | |
| 26 void RunFront(appcache::AppCacheQuotaClient::RequestQueue* queue) { | |
| 27 base::Closure request = queue->front(); | |
| 28 queue->pop_front(); | |
| 29 request.Run(); | |
| 30 } | |
| 24 } // namespace | 31 } // namespace |
| 25 | 32 |
| 26 namespace appcache { | 33 namespace appcache { |
| 27 | 34 |
| 28 AppCacheQuotaClient::AppCacheQuotaClient(AppCacheService* service) | 35 AppCacheQuotaClient::AppCacheQuotaClient(AppCacheService* service) |
| 29 : ALLOW_THIS_IN_INITIALIZER_LIST(service_delete_callback_( | 36 : ALLOW_THIS_IN_INITIALIZER_LIST(service_delete_callback_( |
| 30 new net::CancelableOldCompletionCallback<AppCacheQuotaClient>( | 37 new net::CancelableOldCompletionCallback<AppCacheQuotaClient>( |
| 31 this, &AppCacheQuotaClient::DidDeleteAppCachesForOrigin))), | 38 this, &AppCacheQuotaClient::DidDeleteAppCachesForOrigin))), |
| 32 service_(service), appcache_is_ready_(false), | 39 service_(service), appcache_is_ready_(false), |
| 33 quota_manager_is_destroyed_(false) { | 40 quota_manager_is_destroyed_(false) { |
| 34 } | 41 } |
| 35 | 42 |
| 36 AppCacheQuotaClient::~AppCacheQuotaClient() { | 43 AppCacheQuotaClient::~AppCacheQuotaClient() { |
| 37 DCHECK(pending_usage_requests_.empty()); | 44 DCHECK(pending_batch_requests_.empty()); |
| 38 DCHECK(pending_origins_requests_.empty()); | 45 DCHECK(pending_serial_requests_.empty()); |
| 39 DCHECK(pending_delete_requests_.empty()); | |
| 40 DCHECK(current_delete_request_callback_.is_null()); | 46 DCHECK(current_delete_request_callback_.is_null()); |
| 41 } | 47 } |
| 42 | 48 |
| 43 QuotaClient::ID AppCacheQuotaClient::id() const { | 49 QuotaClient::ID AppCacheQuotaClient::id() const { |
| 44 return kAppcache; | 50 return kAppcache; |
| 45 } | 51 } |
| 46 | 52 |
| 47 void AppCacheQuotaClient::OnQuotaManagerDestroyed() { | 53 void AppCacheQuotaClient::OnQuotaManagerDestroyed() { |
| 48 DeletePendingRequests(); | 54 DeletePendingRequests(); |
| 49 if (!current_delete_request_callback_.is_null()) { | 55 if (!current_delete_request_callback_.is_null()) { |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 63 const GetUsageCallback& callback) { | 69 const GetUsageCallback& callback) { |
| 64 DCHECK(!callback.is_null()); | 70 DCHECK(!callback.is_null()); |
| 65 DCHECK(!quota_manager_is_destroyed_); | 71 DCHECK(!quota_manager_is_destroyed_); |
| 66 | 72 |
| 67 if (!service_) { | 73 if (!service_) { |
| 68 callback.Run(0); | 74 callback.Run(0); |
| 69 return; | 75 return; |
| 70 } | 76 } |
| 71 | 77 |
| 72 if (!appcache_is_ready_) { | 78 if (!appcache_is_ready_) { |
| 73 pending_usage_requests_.push_back(UsageRequest()); | 79 pending_batch_requests_.push_back( |
| 74 pending_usage_requests_.back().origin = origin; | 80 base::Bind(&AppCacheQuotaClient::GetOriginUsage, |
| 75 pending_usage_requests_.back().type = type; | 81 base::Unretained(this), origin, type, callback)); |
| 76 pending_usage_requests_.back().callback = callback; | |
| 77 return; | 82 return; |
| 78 } | 83 } |
| 79 | 84 |
| 80 if (type == quota::kStorageTypePersistent) { | 85 if (type == quota::kStorageTypePersistent) { |
| 81 callback.Run(0); | 86 callback.Run(0); |
| 82 return; | 87 return; |
| 83 } | 88 } |
| 84 | 89 |
| 85 const AppCacheStorage::UsageMap* map = GetUsageMap(); | 90 const AppCacheStorage::UsageMap* map = GetUsageMap(); |
| 86 AppCacheStorage::UsageMap::const_iterator found = map->find(origin); | 91 AppCacheStorage::UsageMap::const_iterator found = map->find(origin); |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 113 quota::StorageType type, | 118 quota::StorageType type, |
| 114 const DeletionCallback& callback) { | 119 const DeletionCallback& callback) { |
| 115 DCHECK(!quota_manager_is_destroyed_); | 120 DCHECK(!quota_manager_is_destroyed_); |
| 116 | 121 |
| 117 if (!service_) { | 122 if (!service_) { |
| 118 callback.Run(quota::kQuotaErrorAbort); | 123 callback.Run(quota::kQuotaErrorAbort); |
| 119 return; | 124 return; |
| 120 } | 125 } |
| 121 | 126 |
| 122 if (!appcache_is_ready_ || !current_delete_request_callback_.is_null()) { | 127 if (!appcache_is_ready_ || !current_delete_request_callback_.is_null()) { |
| 123 pending_delete_requests_.push_back(DeleteRequest()); | 128 pending_serial_requests_.push_back( |
| 124 pending_delete_requests_.back().origin = origin; | 129 base::Bind(&AppCacheQuotaClient::DeleteOriginData, |
| 125 pending_delete_requests_.back().type = type; | 130 base::Unretained(this), origin, type, callback)); |
| 126 pending_delete_requests_.back().callback = callback; | |
| 127 return; | 131 return; |
| 128 } | 132 } |
| 129 | 133 |
| 130 current_delete_request_callback_ = callback; | 134 current_delete_request_callback_ = callback; |
| 131 if (type == quota::kStorageTypePersistent) { | 135 if (type == quota::kStorageTypePersistent) { |
| 132 DidDeleteAppCachesForOrigin(net::OK); | 136 DidDeleteAppCachesForOrigin(net::OK); |
| 133 return; | 137 return; |
| 134 } | 138 } |
| 135 service_->DeleteAppCachesForOrigin(origin, service_delete_callback_); | 139 service_->DeleteAppCachesForOrigin(origin, service_delete_callback_); |
| 136 } | 140 } |
| 137 | 141 |
| 138 AppCacheQuotaClient::UsageRequest::UsageRequest() {} | |
| 139 AppCacheQuotaClient::UsageRequest::~UsageRequest() {} | |
| 140 | |
| 141 AppCacheQuotaClient::OriginsRequest::OriginsRequest() {} | |
| 142 AppCacheQuotaClient::OriginsRequest::~OriginsRequest() {} | |
| 143 | |
| 144 AppCacheQuotaClient::DeleteRequest::DeleteRequest() {} | |
| 145 AppCacheQuotaClient::DeleteRequest::~DeleteRequest() {} | |
| 146 | |
| 147 void AppCacheQuotaClient::DidDeleteAppCachesForOrigin(int rv) { | 142 void AppCacheQuotaClient::DidDeleteAppCachesForOrigin(int rv) { |
| 148 DCHECK(service_); | 143 DCHECK(service_); |
| 149 if (quota_manager_is_destroyed_) | 144 if (quota_manager_is_destroyed_) |
| 150 return; | 145 return; |
| 151 | 146 |
| 152 // Finish the request by calling our callers callback. | 147 // Finish the request by calling our callers callback. |
| 153 current_delete_request_callback_.Run(NetErrorCodeToQuotaStatus(rv)); | 148 current_delete_request_callback_.Run(NetErrorCodeToQuotaStatus(rv)); |
| 154 current_delete_request_callback_.Reset(); | 149 current_delete_request_callback_.Reset(); |
| 155 if (pending_delete_requests_.empty()) | 150 if (pending_serial_requests_.empty()) |
| 156 return; | 151 return; |
| 157 | 152 |
| 158 // Start the next in the queue. | 153 // Start the next in the queue. |
| 159 DeleteRequest& next_request = pending_delete_requests_.front(); | 154 RunFront(&pending_serial_requests_); |
| 160 current_delete_request_callback_ = next_request.callback; | |
| 161 service_->DeleteAppCachesForOrigin(next_request.origin, | |
| 162 service_delete_callback_); | |
|
tzik
2011/10/12 01:58:23
In current implementation, we call service->Delete
michaeln
2011/10/12 06:36:54
Got it... so this also fixes a logic bug!
| |
| 163 pending_delete_requests_.pop_front(); | |
| 164 } | 155 } |
| 165 | 156 |
| 166 void AppCacheQuotaClient::GetOriginsHelper( | 157 void AppCacheQuotaClient::GetOriginsHelper( |
| 167 quota::StorageType type, | 158 quota::StorageType type, |
| 168 const std::string& opt_host, | 159 const std::string& opt_host, |
| 169 const GetOriginsCallback& callback) { | 160 const GetOriginsCallback& callback) { |
| 170 DCHECK(!callback.is_null()); | 161 DCHECK(!callback.is_null()); |
| 171 DCHECK(!quota_manager_is_destroyed_); | 162 DCHECK(!quota_manager_is_destroyed_); |
| 172 | 163 |
| 173 if (!service_) { | 164 if (!service_) { |
| 174 callback.Run(std::set<GURL>(), type); | 165 callback.Run(std::set<GURL>(), type); |
| 175 return; | 166 return; |
| 176 } | 167 } |
| 177 | 168 |
| 178 if (!appcache_is_ready_) { | 169 if (!appcache_is_ready_) { |
| 179 pending_origins_requests_.push_back(OriginsRequest()); | 170 pending_batch_requests_.push_back( |
| 180 pending_origins_requests_.back().opt_host = opt_host; | 171 base::Bind(&AppCacheQuotaClient::GetOriginsHelper, |
| 181 pending_origins_requests_.back().type = type; | 172 base::Unretained(this), type, opt_host, callback)); |
| 182 pending_origins_requests_.back().callback = callback; | |
| 183 return; | 173 return; |
| 184 } | 174 } |
| 185 | 175 |
| 186 if (type == quota::kStorageTypePersistent) { | 176 if (type == quota::kStorageTypePersistent) { |
| 187 callback.Run(std::set<GURL>(), type); | 177 callback.Run(std::set<GURL>(), type); |
| 188 return; | 178 return; |
| 189 } | 179 } |
| 190 | 180 |
| 191 const AppCacheStorage::UsageMap* map = GetUsageMap(); | 181 const AppCacheStorage::UsageMap* map = GetUsageMap(); |
| 192 std::set<GURL> origins; | 182 std::set<GURL> origins; |
| 193 for (AppCacheStorage::UsageMap::const_iterator iter = map->begin(); | 183 for (AppCacheStorage::UsageMap::const_iterator iter = map->begin(); |
| 194 iter != map->end(); ++iter) { | 184 iter != map->end(); ++iter) { |
| 195 if (opt_host.empty() || iter->first.host() == opt_host) | 185 if (opt_host.empty() || iter->first.host() == opt_host) |
| 196 origins.insert(iter->first); | 186 origins.insert(iter->first); |
| 197 } | 187 } |
| 198 callback.Run(origins, type); | 188 callback.Run(origins, type); |
| 199 } | 189 } |
| 200 | 190 |
| 201 void AppCacheQuotaClient::ProcessPendingRequests() { | 191 void AppCacheQuotaClient::ProcessPendingRequests() { |
| 202 DCHECK(appcache_is_ready_); | 192 DCHECK(appcache_is_ready_); |
| 203 while (!pending_usage_requests_.empty()) { | 193 while (!pending_batch_requests_.empty()) |
| 204 UsageRequest& request = pending_usage_requests_.front(); | 194 RunFront(&pending_batch_requests_); |
| 205 GetOriginUsage(request.origin, request.type, request.callback); | |
| 206 pending_usage_requests_.pop_front(); | |
| 207 } | |
| 208 while (!pending_origins_requests_.empty()) { | |
| 209 OriginsRequest& request = pending_origins_requests_.front(); | |
| 210 GetOriginsHelper(request.type, request.opt_host, request.callback); | |
| 211 pending_origins_requests_.pop_front(); | |
| 212 } | |
| 213 if (!pending_delete_requests_.empty()) { | |
| 214 // Just start the first delete, others will follow upon completion. | |
| 215 DeleteRequest request = pending_delete_requests_.front(); | |
| 216 pending_delete_requests_.pop_front(); | |
| 217 DeleteOriginData(request.origin, request.type, request.callback); | |
| 218 } | |
| 219 } | |
| 220 | 195 |
| 221 void AppCacheQuotaClient::AbortPendingRequests() { | 196 if (!pending_serial_requests_.empty()) |
| 222 while (!pending_usage_requests_.empty()) { | 197 RunFront(&pending_serial_requests_); |
| 223 pending_usage_requests_.front().callback.Run(0); | |
| 224 pending_usage_requests_.pop_front(); | |
| 225 } | |
| 226 while (!pending_origins_requests_.empty()) { | |
| 227 pending_origins_requests_.front().callback.Run(std::set<GURL>(), | |
| 228 pending_origins_requests_.front().type); | |
| 229 pending_origins_requests_.pop_front(); | |
| 230 } | |
| 231 while (!pending_delete_requests_.empty()) { | |
| 232 pending_delete_requests_.front().callback.Run(quota::kQuotaErrorAbort); | |
| 233 pending_delete_requests_.pop_front(); | |
| 234 } | |
| 235 } | 198 } |
| 236 | 199 |
| 237 void AppCacheQuotaClient::DeletePendingRequests() { | 200 void AppCacheQuotaClient::DeletePendingRequests() { |
| 238 while (!pending_usage_requests_.empty()) { | 201 pending_batch_requests_.clear(); |
| 239 pending_usage_requests_.pop_front(); | 202 pending_serial_requests_.clear(); |
| 240 } | |
| 241 while (!pending_origins_requests_.empty()) { | |
| 242 pending_origins_requests_.pop_front(); | |
| 243 } | |
| 244 while (!pending_delete_requests_.empty()) { | |
| 245 pending_delete_requests_.pop_front(); | |
| 246 } | |
| 247 } | 203 } |
| 248 | 204 |
| 249 const AppCacheStorage::UsageMap* AppCacheQuotaClient::GetUsageMap() { | 205 const AppCacheStorage::UsageMap* AppCacheQuotaClient::GetUsageMap() { |
| 250 DCHECK(service_); | 206 DCHECK(service_); |
| 251 return service_->storage()->usage_map(); | 207 return service_->storage()->usage_map(); |
| 252 } | 208 } |
| 253 | 209 |
| 254 void AppCacheQuotaClient::NotifyAppCacheReady() { | 210 void AppCacheQuotaClient::NotifyAppCacheReady() { |
| 255 appcache_is_ready_ = true; | 211 appcache_is_ready_ = true; |
| 256 ProcessPendingRequests(); | 212 ProcessPendingRequests(); |
| 257 } | 213 } |
| 258 | 214 |
| 259 void AppCacheQuotaClient::NotifyAppCacheDestroyed() { | 215 void AppCacheQuotaClient::NotifyAppCacheDestroyed() { |
| 260 service_ = NULL; | 216 service_ = NULL; |
| 261 AbortPendingRequests(); | 217 while (!pending_batch_requests_.empty()) |
| 218 RunFront(&pending_batch_requests_); | |
| 219 | |
| 220 while (!pending_serial_requests_.empty()) | |
| 221 RunFront(&pending_serial_requests_); | |
| 222 | |
| 262 if (!current_delete_request_callback_.is_null()) { | 223 if (!current_delete_request_callback_.is_null()) { |
| 263 current_delete_request_callback_.Run(quota::kQuotaErrorAbort); | 224 current_delete_request_callback_.Run(quota::kQuotaErrorAbort); |
| 264 current_delete_request_callback_.Reset(); | 225 current_delete_request_callback_.Reset(); |
| 265 service_delete_callback_.release()->Cancel(); | 226 service_delete_callback_.release()->Cancel(); |
| 266 } else { | 227 } else { |
| 267 service_delete_callback_ = NULL; | 228 service_delete_callback_ = NULL; |
| 268 } | 229 } |
| 269 if (quota_manager_is_destroyed_) | 230 if (quota_manager_is_destroyed_) |
| 270 delete this; | 231 delete this; |
| 271 } | 232 } |
| 272 | 233 |
| 273 } // namespace appcache | 234 } // namespace appcache |
| OLD | NEW |