| 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_disk_cache.h" | 5 #include "webkit/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/file_path.h" | 9 #include "base/file_path.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 52 | 52 |
| 53 private: | 53 private: |
| 54 disk_cache::Entry* disk_cache_entry_; | 54 disk_cache::Entry* disk_cache_entry_; |
| 55 }; | 55 }; |
| 56 | 56 |
| 57 // Separate object to hold state for each Create, Delete, or Doom call | 57 // Separate object to hold state for each Create, Delete, or Doom call |
| 58 // while the call is in-flight and to produce an EntryImpl upon completion. | 58 // while the call is in-flight and to produce an EntryImpl upon completion. |
| 59 class AppCacheDiskCache::ActiveCall { | 59 class AppCacheDiskCache::ActiveCall { |
| 60 public: | 60 public: |
| 61 explicit ActiveCall(AppCacheDiskCache* owner) | 61 explicit ActiveCall(AppCacheDiskCache* owner) |
| 62 : entry_(NULL), callback_(NULL), owner_(owner), entry_ptr_(NULL), | 62 : entry_(NULL), |
| 63 ALLOW_THIS_IN_INITIALIZER_LIST( | 63 owner_(owner), |
| 64 async_completion_(this, &ActiveCall::OnAsyncCompletion)) { | 64 entry_ptr_(NULL) { |
| 65 } | 65 } |
| 66 | 66 |
| 67 int CreateEntry(int64 key, Entry** entry, | 67 int CreateEntry(int64 key, Entry** entry, |
| 68 net::OldCompletionCallback* callback) { | 68 const net::CompletionCallback& callback) { |
| 69 int rv = owner_->disk_cache()->CreateEntry( | 69 int rv = owner_->disk_cache()->CreateEntry( |
| 70 base::Int64ToString(key), &entry_ptr_, | 70 base::Int64ToString(key), &entry_ptr_, |
| 71 base::Bind(&ActiveCall::OnAsyncCompletion, | 71 base::Bind(&ActiveCall::OnAsyncCompletion, base::Unretained(this))); |
| 72 base::Unretained(this))); | |
| 73 return HandleImmediateReturnValue(rv, entry, callback); | 72 return HandleImmediateReturnValue(rv, entry, callback); |
| 74 } | 73 } |
| 75 | 74 |
| 76 int OpenEntry(int64 key, Entry** entry, | 75 int OpenEntry(int64 key, Entry** entry, |
| 77 net::OldCompletionCallback* callback) { | 76 const net::CompletionCallback& callback) { |
| 78 int rv = owner_->disk_cache()->OpenEntry( | 77 int rv = owner_->disk_cache()->OpenEntry( |
| 79 base::Int64ToString(key), &entry_ptr_, | 78 base::Int64ToString(key), &entry_ptr_, |
| 80 base::Bind(&ActiveCall::OnAsyncCompletion, | 79 base::Bind(&ActiveCall::OnAsyncCompletion, base::Unretained(this))); |
| 81 base::Unretained(this))); | |
| 82 return HandleImmediateReturnValue(rv, entry, callback); | 80 return HandleImmediateReturnValue(rv, entry, callback); |
| 83 } | 81 } |
| 84 | 82 |
| 85 int DoomEntry(int64 key, net::OldCompletionCallback* callback) { | 83 int DoomEntry(int64 key, const net::CompletionCallback& callback) { |
| 86 int rv = owner_->disk_cache()->DoomEntry( | 84 int rv = owner_->disk_cache()->DoomEntry( |
| 87 base::Int64ToString(key), | 85 base::Int64ToString(key), |
| 88 base::Bind(&ActiveCall::OnAsyncCompletion, base::Unretained(this))); | 86 base::Bind(&ActiveCall::OnAsyncCompletion, base::Unretained(this))); |
| 89 return HandleImmediateReturnValue(rv, NULL, callback); | 87 return HandleImmediateReturnValue(rv, NULL, callback); |
| 90 } | 88 } |
| 91 | 89 |
| 92 private: | 90 private: |
| 93 int HandleImmediateReturnValue(int rv, Entry** entry, | 91 int HandleImmediateReturnValue(int rv, Entry** entry, |
| 94 net::OldCompletionCallback* callback) { | 92 const net::CompletionCallback& callback) { |
| 95 if (rv == net::ERR_IO_PENDING) { | 93 if (rv == net::ERR_IO_PENDING) { |
| 96 // OnAsyncCompletion will be called later. | 94 // OnAsyncCompletion will be called later. |
| 97 callback_ = callback; | 95 callback_ = callback; |
| 98 entry_ = entry; | 96 entry_ = entry; |
| 99 owner_->AddActiveCall(this); | 97 owner_->AddActiveCall(this); |
| 100 return net::ERR_IO_PENDING; | 98 return net::ERR_IO_PENDING; |
| 101 } | 99 } |
| 102 if (rv == net::OK && entry) | 100 if (rv == net::OK && entry) |
| 103 *entry = new EntryImpl(entry_ptr_); | 101 *entry = new EntryImpl(entry_ptr_); |
| 104 delete this; | 102 delete this; |
| 105 return rv; | 103 return rv; |
| 106 } | 104 } |
| 107 | 105 |
| 108 void OnAsyncCompletion(int rv) { | 106 void OnAsyncCompletion(int rv) { |
| 109 owner_->RemoveActiveCall(this); | 107 owner_->RemoveActiveCall(this); |
| 110 if (rv == net::OK && entry_) | 108 if (rv == net::OK && entry_) |
| 111 *entry_ = new EntryImpl(entry_ptr_); | 109 *entry_ = new EntryImpl(entry_ptr_); |
| 112 callback_->Run(rv); | 110 callback_.Run(rv); |
| 113 callback_ = NULL; | 111 callback_.Reset(); |
| 114 delete this; | 112 delete this; |
| 115 } | 113 } |
| 116 | 114 |
| 117 Entry** entry_; | 115 Entry** entry_; |
| 118 net::OldCompletionCallback* callback_; | 116 net::CompletionCallback callback_; |
| 119 AppCacheDiskCache* owner_; | 117 AppCacheDiskCache* owner_; |
| 120 disk_cache::Entry* entry_ptr_; | 118 disk_cache::Entry* entry_ptr_; |
| 121 net::OldCompletionCallbackImpl<ActiveCall> async_completion_; | |
| 122 }; | 119 }; |
| 123 | 120 |
| 124 AppCacheDiskCache::AppCacheDiskCache() | 121 AppCacheDiskCache::AppCacheDiskCache() |
| 125 : is_disabled_(false), init_callback_(NULL) { | 122 : is_disabled_(false) { |
| 126 } | 123 } |
| 127 | 124 |
| 128 AppCacheDiskCache::~AppCacheDiskCache() { | 125 AppCacheDiskCache::~AppCacheDiskCache() { |
| 129 if (create_backend_callback_) { | 126 if (create_backend_callback_) { |
| 130 create_backend_callback_->Cancel(); | 127 create_backend_callback_->Cancel(); |
| 131 create_backend_callback_.release(); | 128 create_backend_callback_.release(); |
| 132 OnCreateBackendComplete(net::ERR_ABORTED); | 129 OnCreateBackendComplete(net::ERR_ABORTED); |
| 133 } | 130 } |
| 134 disk_cache_.reset(); | 131 disk_cache_.reset(); |
| 135 STLDeleteElements(&active_calls_); | 132 STLDeleteElements(&active_calls_); |
| 136 } | 133 } |
| 137 | 134 |
| 138 int AppCacheDiskCache::InitWithDiskBackend( | 135 int AppCacheDiskCache::InitWithDiskBackend( |
| 139 const FilePath& disk_cache_directory, int disk_cache_size, bool force, | 136 const FilePath& disk_cache_directory, int disk_cache_size, bool force, |
| 140 base::MessageLoopProxy* cache_thread, net::OldCompletionCallback* callback)
{ | 137 base::MessageLoopProxy* cache_thread, |
| 138 const net::CompletionCallback& callback) { |
| 141 return Init(net::APP_CACHE, disk_cache_directory, | 139 return Init(net::APP_CACHE, disk_cache_directory, |
| 142 disk_cache_size, force, cache_thread, callback); | 140 disk_cache_size, force, cache_thread, callback); |
| 143 } | 141 } |
| 144 | 142 |
| 145 int AppCacheDiskCache::InitWithMemBackend( | 143 int AppCacheDiskCache::InitWithMemBackend( |
| 146 int mem_cache_size, net::OldCompletionCallback* callback) { | 144 int mem_cache_size, const net::CompletionCallback& callback) { |
| 147 return Init(net::MEMORY_CACHE, FilePath(), mem_cache_size, false, NULL, | 145 return Init(net::MEMORY_CACHE, FilePath(), mem_cache_size, false, NULL, |
| 148 callback); | 146 callback); |
| 149 } | 147 } |
| 150 | 148 |
| 151 void AppCacheDiskCache::Disable() { | 149 void AppCacheDiskCache::Disable() { |
| 152 if (is_disabled_) | 150 if (is_disabled_) |
| 153 return; | 151 return; |
| 154 | 152 |
| 155 is_disabled_ = true; | 153 is_disabled_ = true; |
| 156 | 154 |
| 157 if (create_backend_callback_) { | 155 if (create_backend_callback_) { |
| 158 create_backend_callback_->Cancel(); | 156 create_backend_callback_->Cancel(); |
| 159 create_backend_callback_.release(); | 157 create_backend_callback_.release(); |
| 160 OnCreateBackendComplete(net::ERR_ABORTED); | 158 OnCreateBackendComplete(net::ERR_ABORTED); |
| 161 } | 159 } |
| 162 } | 160 } |
| 163 | 161 |
| 164 int AppCacheDiskCache::CreateEntry(int64 key, Entry** entry, | 162 int AppCacheDiskCache::CreateEntry(int64 key, Entry** entry, |
| 165 net::OldCompletionCallback* callback) { | 163 const net::CompletionCallback& callback) { |
| 166 DCHECK(entry && callback); | 164 DCHECK(entry); |
| 165 DCHECK(!callback.is_null()); |
| 167 if (is_disabled_) | 166 if (is_disabled_) |
| 168 return net::ERR_ABORTED; | 167 return net::ERR_ABORTED; |
| 169 | 168 |
| 170 if (is_initializing()) { | 169 if (is_initializing()) { |
| 171 pending_calls_.push_back(PendingCall(CREATE, key, entry, callback)); | 170 pending_calls_.push_back(PendingCall(CREATE, key, entry, callback)); |
| 172 return net::ERR_IO_PENDING; | 171 return net::ERR_IO_PENDING; |
| 173 } | 172 } |
| 174 | 173 |
| 175 if (!disk_cache_.get()) | 174 if (!disk_cache_.get()) |
| 176 return net::ERR_FAILED; | 175 return net::ERR_FAILED; |
| 177 | 176 |
| 178 return (new ActiveCall(this))->CreateEntry(key, entry, callback); | 177 return (new ActiveCall(this))->CreateEntry(key, entry, callback); |
| 179 } | 178 } |
| 180 | 179 |
| 181 int AppCacheDiskCache::OpenEntry(int64 key, Entry** entry, | 180 int AppCacheDiskCache::OpenEntry(int64 key, Entry** entry, |
| 182 net::OldCompletionCallback* callback) { | 181 const net::CompletionCallback& callback) { |
| 183 DCHECK(entry && callback); | 182 DCHECK(entry); |
| 183 DCHECK(!callback.is_null()); |
| 184 if (is_disabled_) | 184 if (is_disabled_) |
| 185 return net::ERR_ABORTED; | 185 return net::ERR_ABORTED; |
| 186 | 186 |
| 187 if (is_initializing()) { | 187 if (is_initializing()) { |
| 188 pending_calls_.push_back(PendingCall(OPEN, key, entry, callback)); | 188 pending_calls_.push_back(PendingCall(OPEN, key, entry, callback)); |
| 189 return net::ERR_IO_PENDING; | 189 return net::ERR_IO_PENDING; |
| 190 } | 190 } |
| 191 | 191 |
| 192 if (!disk_cache_.get()) | 192 if (!disk_cache_.get()) |
| 193 return net::ERR_FAILED; | 193 return net::ERR_FAILED; |
| 194 | 194 |
| 195 return (new ActiveCall(this))->OpenEntry(key, entry, callback); | 195 return (new ActiveCall(this))->OpenEntry(key, entry, callback); |
| 196 } | 196 } |
| 197 | 197 |
| 198 int AppCacheDiskCache::DoomEntry(int64 key, | 198 int AppCacheDiskCache::DoomEntry(int64 key, |
| 199 net::OldCompletionCallback* callback) { | 199 const net::CompletionCallback& callback) { |
| 200 DCHECK(callback); | 200 DCHECK(!callback.is_null()); |
| 201 if (is_disabled_) | 201 if (is_disabled_) |
| 202 return net::ERR_ABORTED; | 202 return net::ERR_ABORTED; |
| 203 | 203 |
| 204 if (is_initializing()) { | 204 if (is_initializing()) { |
| 205 pending_calls_.push_back(PendingCall(DOOM, key, NULL, callback)); | 205 pending_calls_.push_back(PendingCall(DOOM, key, NULL, callback)); |
| 206 return net::ERR_IO_PENDING; | 206 return net::ERR_IO_PENDING; |
| 207 } | 207 } |
| 208 | 208 |
| 209 if (!disk_cache_.get()) | 209 if (!disk_cache_.get()) |
| 210 return net::ERR_FAILED; | 210 return net::ERR_FAILED; |
| 211 | 211 |
| 212 return (new ActiveCall(this))->DoomEntry(key, callback); | 212 return (new ActiveCall(this))->DoomEntry(key, callback); |
| 213 } | 213 } |
| 214 | 214 |
| 215 AppCacheDiskCache::PendingCall::~PendingCall() {} |
| 216 |
| 215 int AppCacheDiskCache::Init(net::CacheType cache_type, | 217 int AppCacheDiskCache::Init(net::CacheType cache_type, |
| 216 const FilePath& cache_directory, | 218 const FilePath& cache_directory, |
| 217 int cache_size, bool force, | 219 int cache_size, bool force, |
| 218 base::MessageLoopProxy* cache_thread, | 220 base::MessageLoopProxy* cache_thread, |
| 219 net::OldCompletionCallback* callback) { | 221 const net::CompletionCallback& callback) { |
| 220 DCHECK(!is_initializing() && !disk_cache_.get()); | 222 DCHECK(!is_initializing() && !disk_cache_.get()); |
| 221 is_disabled_ = false; | 223 is_disabled_ = false; |
| 222 create_backend_callback_ = new CreateBackendCallback( | 224 create_backend_callback_ = new CreateBackendCallback( |
| 223 this, &AppCacheDiskCache::OnCreateBackendComplete); | 225 this, &AppCacheDiskCache::OnCreateBackendComplete); |
| 224 | 226 |
| 225 int rv = disk_cache::CreateCacheBackend( | 227 int rv = disk_cache::CreateCacheBackend( |
| 226 cache_type, cache_directory, cache_size, force, cache_thread, NULL, | 228 cache_type, cache_directory, cache_size, force, cache_thread, NULL, |
| 227 &(create_backend_callback_->backend_ptr_), | 229 &(create_backend_callback_->backend_ptr_), |
| 228 base::Bind(&net::OldCompletionCallbackAdapter, create_backend_callback_)); | 230 base::Bind(&net::OldCompletionCallbackAdapter, create_backend_callback_)); |
| 229 if (rv == net::ERR_IO_PENDING) | 231 if (rv == net::ERR_IO_PENDING) |
| 230 init_callback_ = callback; | 232 init_callback_ = callback; |
| 231 else | 233 else |
| 232 OnCreateBackendComplete(rv); | 234 OnCreateBackendComplete(rv); |
| 233 return rv; | 235 return rv; |
| 234 } | 236 } |
| 235 | 237 |
| 236 void AppCacheDiskCache::OnCreateBackendComplete(int rv) { | 238 void AppCacheDiskCache::OnCreateBackendComplete(int rv) { |
| 237 if (rv == net::OK) { | 239 if (rv == net::OK) { |
| 238 disk_cache_.reset(create_backend_callback_->backend_ptr_); | 240 disk_cache_.reset(create_backend_callback_->backend_ptr_); |
| 239 create_backend_callback_->backend_ptr_ = NULL; | 241 create_backend_callback_->backend_ptr_ = NULL; |
| 240 } | 242 } |
| 241 create_backend_callback_ = NULL; | 243 create_backend_callback_ = NULL; |
| 242 | 244 |
| 243 // Invoke our clients callback function. | 245 // Invoke our clients callback function. |
| 244 if (init_callback_) { | 246 if (!init_callback_.is_null()) { |
| 245 init_callback_->Run(rv); | 247 init_callback_.Run(rv); |
| 246 init_callback_ = NULL; | 248 init_callback_.Reset(); |
| 247 } | 249 } |
| 248 | 250 |
| 249 // Service pending calls that were queued up while we were initailizating. | 251 // Service pending calls that were queued up while we were initailizating. |
| 250 for (PendingCalls::const_iterator iter = pending_calls_.begin(); | 252 for (PendingCalls::const_iterator iter = pending_calls_.begin(); |
| 251 iter < pending_calls_.end(); ++iter) { | 253 iter < pending_calls_.end(); ++iter) { |
| 252 int rv = net::ERR_FAILED; | 254 int rv = net::ERR_FAILED; |
| 253 switch (iter->call_type) { | 255 switch (iter->call_type) { |
| 254 case CREATE: | 256 case CREATE: |
| 255 rv = CreateEntry(iter->key, iter->entry, iter->callback); | 257 rv = CreateEntry(iter->key, iter->entry, iter->callback); |
| 256 break; | 258 break; |
| 257 case OPEN: | 259 case OPEN: |
| 258 rv = OpenEntry(iter->key, iter->entry, iter->callback); | 260 rv = OpenEntry(iter->key, iter->entry, iter->callback); |
| 259 break; | 261 break; |
| 260 case DOOM: | 262 case DOOM: |
| 261 rv = DoomEntry(iter->key, iter->callback); | 263 rv = DoomEntry(iter->key, iter->callback); |
| 262 break; | 264 break; |
| 263 default: | 265 default: |
| 264 NOTREACHED(); | 266 NOTREACHED(); |
| 265 break; | 267 break; |
| 266 } | 268 } |
| 267 if (rv != net::ERR_IO_PENDING) | 269 if (rv != net::ERR_IO_PENDING) |
| 268 iter->callback->Run(rv); | 270 iter->callback.Run(rv); |
| 269 } | 271 } |
| 270 pending_calls_.clear(); | 272 pending_calls_.clear(); |
| 271 } | 273 } |
| 272 | 274 |
| 273 } // namespace appcache | 275 } // namespace appcache |
| 274 | 276 |
| OLD | NEW |