| 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 "content/browser/appcache/appcache_disk_cache.h" | 5 #include "content/browser/appcache/appcache_disk_cache.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
| 9 #include "base/files/file_path.h" | 9 #include "base/files/file_path.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/memory/ref_counted.h" |
| 11 #include "base/single_thread_task_runner.h" | 12 #include "base/single_thread_task_runner.h" |
| 12 #include "base/stl_util.h" | 13 #include "base/stl_util.h" |
| 13 #include "base/strings/string_number_conversions.h" | 14 #include "base/strings/string_number_conversions.h" |
| 14 #include "net/base/cache_type.h" | 15 #include "net/base/cache_type.h" |
| 15 #include "net/base/net_errors.h" | 16 #include "net/base/net_errors.h" |
| 16 | 17 |
| 17 namespace content { | 18 namespace content { |
| 18 | 19 |
| 19 // A callback shim that provides storage for the 'backend_ptr' value | 20 // A callback shim that provides storage for the 'backend_ptr' value |
| 20 // and will delete a resulting ptr if completion occurs after its | 21 // and will delete a resulting ptr if completion occurs after its |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 107 if (owner_) | 108 if (owner_) |
| 108 owner_->RemoveOpenEntry(this); | 109 owner_->RemoveOpenEntry(this); |
| 109 } | 110 } |
| 110 | 111 |
| 111 disk_cache::Entry* disk_cache_entry_; | 112 disk_cache::Entry* disk_cache_entry_; |
| 112 AppCacheDiskCache* owner_; | 113 AppCacheDiskCache* owner_; |
| 113 }; | 114 }; |
| 114 | 115 |
| 115 // Separate object to hold state for each Create, Delete, or Doom call | 116 // Separate object to hold state for each Create, Delete, or Doom call |
| 116 // while the call is in-flight and to produce an EntryImpl upon completion. | 117 // while the call is in-flight and to produce an EntryImpl upon completion. |
| 117 class AppCacheDiskCache::ActiveCall { | 118 class AppCacheDiskCache::ActiveCall |
| 119 : public base::RefCounted<AppCacheDiskCache::ActiveCall> { |
| 118 public: | 120 public: |
| 119 explicit ActiveCall(AppCacheDiskCache* owner) | 121 static int CreateEntry(const base::WeakPtr<AppCacheDiskCache>& owner, |
| 120 : entry_(NULL), | 122 int64 key, Entry** entry, |
| 121 owner_(owner), | 123 const net::CompletionCallback& callback) { |
| 122 entry_ptr_(NULL) { | 124 scoped_refptr<ActiveCall> active_call( |
| 125 new ActiveCall(owner, entry, callback)); |
| 126 int rv = owner->disk_cache()->CreateEntry( |
| 127 base::Int64ToString(key), &active_call->entry_ptr_, |
| 128 base::Bind(&ActiveCall::OnAsyncCompletion, active_call)); |
| 129 return active_call->HandleImmediateReturnValue(rv); |
| 123 } | 130 } |
| 124 | 131 |
| 125 int CreateEntry(int64 key, Entry** entry, | 132 static int OpenEntry(const base::WeakPtr<AppCacheDiskCache>& owner, |
| 126 const net::CompletionCallback& callback) { | 133 int64 key, Entry** entry, |
| 127 int rv = owner_->disk_cache()->CreateEntry( | 134 const net::CompletionCallback& callback) { |
| 128 base::Int64ToString(key), &entry_ptr_, | 135 scoped_refptr<ActiveCall> active_call( |
| 129 base::Bind(&ActiveCall::OnAsyncCompletion, base::Unretained(this))); | 136 new ActiveCall(owner, entry, callback)); |
| 130 return HandleImmediateReturnValue(rv, entry, callback); | 137 int rv = owner->disk_cache()->OpenEntry( |
| 138 base::Int64ToString(key), &active_call->entry_ptr_, |
| 139 base::Bind(&ActiveCall::OnAsyncCompletion, active_call)); |
| 140 return active_call->HandleImmediateReturnValue(rv); |
| 131 } | 141 } |
| 132 | 142 |
| 133 int OpenEntry(int64 key, Entry** entry, | 143 static int DoomEntry(const base::WeakPtr<AppCacheDiskCache>& owner, |
| 134 const net::CompletionCallback& callback) { | 144 int64 key, const net::CompletionCallback& callback) { |
| 135 int rv = owner_->disk_cache()->OpenEntry( | 145 scoped_refptr<ActiveCall> active_call( |
| 136 base::Int64ToString(key), &entry_ptr_, | 146 new ActiveCall(owner, nullptr, callback)); |
| 137 base::Bind(&ActiveCall::OnAsyncCompletion, base::Unretained(this))); | 147 int rv = owner->disk_cache()->DoomEntry( |
| 138 return HandleImmediateReturnValue(rv, entry, callback); | |
| 139 } | |
| 140 | |
| 141 int DoomEntry(int64 key, const net::CompletionCallback& callback) { | |
| 142 int rv = owner_->disk_cache()->DoomEntry( | |
| 143 base::Int64ToString(key), | 148 base::Int64ToString(key), |
| 144 base::Bind(&ActiveCall::OnAsyncCompletion, base::Unretained(this))); | 149 base::Bind(&ActiveCall::OnAsyncCompletion, active_call)); |
| 145 return HandleImmediateReturnValue(rv, NULL, callback); | 150 return active_call->HandleImmediateReturnValue(rv); |
| 146 } | 151 } |
| 147 | 152 |
| 148 private: | 153 private: |
| 149 int HandleImmediateReturnValue(int rv, Entry** entry, | 154 friend class base::RefCounted<AppCacheDiskCache::ActiveCall>; |
| 150 const net::CompletionCallback& callback) { | 155 |
| 156 ActiveCall(const base::WeakPtr<AppCacheDiskCache>& owner, |
| 157 Entry** entry, |
| 158 const net::CompletionCallback& callback) |
| 159 : owner_(owner), |
| 160 entry_(entry), |
| 161 callback_(callback), |
| 162 entry_ptr_(nullptr) { |
| 163 DCHECK(owner_); |
| 164 } |
| 165 |
| 166 ~ActiveCall() {} |
| 167 |
| 168 int HandleImmediateReturnValue(int rv) { |
| 151 if (rv == net::ERR_IO_PENDING) { | 169 if (rv == net::ERR_IO_PENDING) { |
| 152 // OnAsyncCompletion will be called later. | 170 // OnAsyncCompletion will be called later. |
| 153 callback_ = callback; | 171 return rv; |
| 154 entry_ = entry; | |
| 155 owner_->AddActiveCall(this); | |
| 156 return net::ERR_IO_PENDING; | |
| 157 } | 172 } |
| 158 if (rv == net::OK && entry) | 173 |
| 159 *entry = new EntryImpl(entry_ptr_, owner_); | 174 if (rv == net::OK && entry_) { |
| 160 delete this; | 175 DCHECK(entry_ptr_); |
| 176 *entry_ = new EntryImpl(entry_ptr_, owner_.get()); |
| 177 } |
| 161 return rv; | 178 return rv; |
| 162 } | 179 } |
| 163 | 180 |
| 164 void OnAsyncCompletion(int rv) { | 181 void OnAsyncCompletion(int rv) { |
| 165 owner_->RemoveActiveCall(this); | 182 if (rv == net::OK && entry_) { |
| 166 if (rv == net::OK && entry_) | 183 DCHECK(entry_ptr_); |
| 167 *entry_ = new EntryImpl(entry_ptr_, owner_); | 184 if (owner_) { |
| 185 *entry_ = new EntryImpl(entry_ptr_, owner_.get()); |
| 186 } else { |
| 187 entry_ptr_->Close(); |
| 188 rv = net::ERR_ABORTED; |
| 189 } |
| 190 } |
| 168 callback_.Run(rv); | 191 callback_.Run(rv); |
| 169 callback_.Reset(); | |
| 170 delete this; | |
| 171 } | 192 } |
| 172 | 193 |
| 194 base::WeakPtr<AppCacheDiskCache> owner_; |
| 173 Entry** entry_; | 195 Entry** entry_; |
| 174 net::CompletionCallback callback_; | 196 net::CompletionCallback callback_; |
| 175 AppCacheDiskCache* owner_; | |
| 176 disk_cache::Entry* entry_ptr_; | 197 disk_cache::Entry* entry_ptr_; |
| 177 }; | 198 }; |
| 178 | 199 |
| 179 AppCacheDiskCache::AppCacheDiskCache() | 200 AppCacheDiskCache::AppCacheDiskCache() |
| 180 : is_disabled_(false) { | 201 : is_disabled_(false), |
| 202 weak_factory_(this) { |
| 181 } | 203 } |
| 182 | 204 |
| 183 AppCacheDiskCache::~AppCacheDiskCache() { | 205 AppCacheDiskCache::~AppCacheDiskCache() { |
| 184 Disable(); | 206 Disable(); |
| 185 } | 207 } |
| 186 | 208 |
| 187 int AppCacheDiskCache::InitWithDiskBackend( | 209 int AppCacheDiskCache::InitWithDiskBackend( |
| 188 const base::FilePath& disk_cache_directory, | 210 const base::FilePath& disk_cache_directory, |
| 189 int disk_cache_size, | 211 int disk_cache_size, |
| 190 bool force, | 212 bool force, |
| (...skipping 27 matching lines...) Expand all Loading... |
| 218 | 240 |
| 219 // We need to close open file handles in order to reinitalize the | 241 // We need to close open file handles in order to reinitalize the |
| 220 // appcache system on the fly. File handles held in both entries and in | 242 // appcache system on the fly. File handles held in both entries and in |
| 221 // the main disk_cache::Backend class need to be released. | 243 // the main disk_cache::Backend class need to be released. |
| 222 for (OpenEntries::const_iterator iter = open_entries_.begin(); | 244 for (OpenEntries::const_iterator iter = open_entries_.begin(); |
| 223 iter != open_entries_.end(); ++iter) { | 245 iter != open_entries_.end(); ++iter) { |
| 224 (*iter)->Abandon(); | 246 (*iter)->Abandon(); |
| 225 } | 247 } |
| 226 open_entries_.clear(); | 248 open_entries_.clear(); |
| 227 disk_cache_.reset(); | 249 disk_cache_.reset(); |
| 228 STLDeleteElements(&active_calls_); | |
| 229 } | 250 } |
| 230 | 251 |
| 231 int AppCacheDiskCache::CreateEntry(int64 key, Entry** entry, | 252 int AppCacheDiskCache::CreateEntry(int64 key, Entry** entry, |
| 232 const net::CompletionCallback& callback) { | 253 const net::CompletionCallback& callback) { |
| 233 DCHECK(entry); | 254 DCHECK(entry); |
| 234 DCHECK(!callback.is_null()); | 255 DCHECK(!callback.is_null()); |
| 235 if (is_disabled_) | 256 if (is_disabled_) |
| 236 return net::ERR_ABORTED; | 257 return net::ERR_ABORTED; |
| 237 | 258 |
| 238 if (is_initializing()) { | 259 if (is_initializing()) { |
| 239 pending_calls_.push_back(PendingCall(CREATE, key, entry, callback)); | 260 pending_calls_.push_back(PendingCall(CREATE, key, entry, callback)); |
| 240 return net::ERR_IO_PENDING; | 261 return net::ERR_IO_PENDING; |
| 241 } | 262 } |
| 242 | 263 |
| 243 if (!disk_cache_) | 264 if (!disk_cache_) |
| 244 return net::ERR_FAILED; | 265 return net::ERR_FAILED; |
| 245 | 266 |
| 246 return (new ActiveCall(this))->CreateEntry(key, entry, callback); | 267 return ActiveCall::CreateEntry( |
| 268 weak_factory_.GetWeakPtr(), key, entry, callback); |
| 247 } | 269 } |
| 248 | 270 |
| 249 int AppCacheDiskCache::OpenEntry(int64 key, Entry** entry, | 271 int AppCacheDiskCache::OpenEntry(int64 key, Entry** entry, |
| 250 const net::CompletionCallback& callback) { | 272 const net::CompletionCallback& callback) { |
| 251 DCHECK(entry); | 273 DCHECK(entry); |
| 252 DCHECK(!callback.is_null()); | 274 DCHECK(!callback.is_null()); |
| 253 if (is_disabled_) | 275 if (is_disabled_) |
| 254 return net::ERR_ABORTED; | 276 return net::ERR_ABORTED; |
| 255 | 277 |
| 256 if (is_initializing()) { | 278 if (is_initializing()) { |
| 257 pending_calls_.push_back(PendingCall(OPEN, key, entry, callback)); | 279 pending_calls_.push_back(PendingCall(OPEN, key, entry, callback)); |
| 258 return net::ERR_IO_PENDING; | 280 return net::ERR_IO_PENDING; |
| 259 } | 281 } |
| 260 | 282 |
| 261 if (!disk_cache_) | 283 if (!disk_cache_) |
| 262 return net::ERR_FAILED; | 284 return net::ERR_FAILED; |
| 263 | 285 |
| 264 return (new ActiveCall(this))->OpenEntry(key, entry, callback); | 286 return ActiveCall::OpenEntry( |
| 287 weak_factory_.GetWeakPtr(), key, entry, callback); |
| 265 } | 288 } |
| 266 | 289 |
| 267 int AppCacheDiskCache::DoomEntry(int64 key, | 290 int AppCacheDiskCache::DoomEntry(int64 key, |
| 268 const net::CompletionCallback& callback) { | 291 const net::CompletionCallback& callback) { |
| 269 DCHECK(!callback.is_null()); | 292 DCHECK(!callback.is_null()); |
| 270 if (is_disabled_) | 293 if (is_disabled_) |
| 271 return net::ERR_ABORTED; | 294 return net::ERR_ABORTED; |
| 272 | 295 |
| 273 if (is_initializing()) { | 296 if (is_initializing()) { |
| 274 pending_calls_.push_back(PendingCall(DOOM, key, NULL, callback)); | 297 pending_calls_.push_back(PendingCall(DOOM, key, NULL, callback)); |
| 275 return net::ERR_IO_PENDING; | 298 return net::ERR_IO_PENDING; |
| 276 } | 299 } |
| 277 | 300 |
| 278 if (!disk_cache_) | 301 if (!disk_cache_) |
| 279 return net::ERR_FAILED; | 302 return net::ERR_FAILED; |
| 280 | 303 |
| 281 return (new ActiveCall(this))->DoomEntry(key, callback); | 304 return ActiveCall::DoomEntry(weak_factory_.GetWeakPtr(), key, callback); |
| 282 } | 305 } |
| 283 | 306 |
| 284 AppCacheDiskCache::PendingCall::PendingCall() | 307 AppCacheDiskCache::PendingCall::PendingCall() |
| 285 : call_type(CREATE), | 308 : call_type(CREATE), |
| 286 key(0), | 309 key(0), |
| 287 entry(NULL) { | 310 entry(NULL) { |
| 288 } | 311 } |
| 289 | 312 |
| 290 AppCacheDiskCache::PendingCall::PendingCall(PendingCallType call_type, | 313 AppCacheDiskCache::PendingCall::PendingCall(PendingCallType call_type, |
| 291 int64 key, | 314 int64 key, |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 363 NOTREACHED(); | 386 NOTREACHED(); |
| 364 break; | 387 break; |
| 365 } | 388 } |
| 366 if (rv != net::ERR_IO_PENDING) | 389 if (rv != net::ERR_IO_PENDING) |
| 367 iter->callback.Run(rv); | 390 iter->callback.Run(rv); |
| 368 } | 391 } |
| 369 pending_calls_.clear(); | 392 pending_calls_.clear(); |
| 370 } | 393 } |
| 371 | 394 |
| 372 } // namespace content | 395 } // namespace content |
| OLD | NEW |