| 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_disk_cache.h" | 5 #include "webkit/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" |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 42 ~CreateBackendCallbackShim() { | 42 ~CreateBackendCallbackShim() { |
| 43 } | 43 } |
| 44 | 44 |
| 45 AppCacheDiskCache* appcache_diskcache_; // Unowned pointer. | 45 AppCacheDiskCache* appcache_diskcache_; // Unowned pointer. |
| 46 }; | 46 }; |
| 47 | 47 |
| 48 // An implementation of AppCacheDiskCacheInterface::Entry that's a thin | 48 // An implementation of AppCacheDiskCacheInterface::Entry that's a thin |
| 49 // wrapper around disk_cache::Entry. | 49 // wrapper around disk_cache::Entry. |
| 50 class AppCacheDiskCache::EntryImpl : public Entry { | 50 class AppCacheDiskCache::EntryImpl : public Entry { |
| 51 public: | 51 public: |
| 52 explicit EntryImpl(disk_cache::Entry* disk_cache_entry) | 52 EntryImpl(disk_cache::Entry* disk_cache_entry, |
| 53 : disk_cache_entry_(disk_cache_entry) { | 53 AppCacheDiskCache* owner) |
| 54 : disk_cache_entry_(disk_cache_entry), owner_(owner) { |
| 54 DCHECK(disk_cache_entry); | 55 DCHECK(disk_cache_entry); |
| 56 DCHECK(owner); |
| 57 owner_->AddOpenEntry(this); |
| 55 } | 58 } |
| 56 | 59 |
| 57 // Entry implementation. | 60 // Entry implementation. |
| 58 virtual int Read(int index, int64 offset, net::IOBuffer* buf, int buf_len, | 61 virtual int Read(int index, int64 offset, net::IOBuffer* buf, int buf_len, |
| 59 const net::CompletionCallback& callback) OVERRIDE { | 62 const net::CompletionCallback& callback) OVERRIDE { |
| 60 if (offset < 0 || offset > kint32max) | 63 if (offset < 0 || offset > kint32max) |
| 61 return net::ERR_INVALID_ARGUMENT; | 64 return net::ERR_INVALID_ARGUMENT; |
| 65 if (!disk_cache_entry_) |
| 66 return net::ERR_ABORTED; |
| 62 return disk_cache_entry_->ReadData( | 67 return disk_cache_entry_->ReadData( |
| 63 index, static_cast<int>(offset), buf, buf_len, callback); | 68 index, static_cast<int>(offset), buf, buf_len, callback); |
| 64 } | 69 } |
| 65 | 70 |
| 66 virtual int Write(int index, int64 offset, net::IOBuffer* buf, int buf_len, | 71 virtual int Write(int index, int64 offset, net::IOBuffer* buf, int buf_len, |
| 67 const net::CompletionCallback& callback) OVERRIDE { | 72 const net::CompletionCallback& callback) OVERRIDE { |
| 68 if (offset < 0 || offset > kint32max) | 73 if (offset < 0 || offset > kint32max) |
| 69 return net::ERR_INVALID_ARGUMENT; | 74 return net::ERR_INVALID_ARGUMENT; |
| 75 if (!disk_cache_entry_) |
| 76 return net::ERR_ABORTED; |
| 70 const bool kTruncate = true; | 77 const bool kTruncate = true; |
| 71 return disk_cache_entry_->WriteData( | 78 return disk_cache_entry_->WriteData( |
| 72 index, static_cast<int>(offset), buf, buf_len, callback, kTruncate); | 79 index, static_cast<int>(offset), buf, buf_len, callback, kTruncate); |
| 73 } | 80 } |
| 74 | 81 |
| 75 virtual int64 GetSize(int index) OVERRIDE { | 82 virtual int64 GetSize(int index) OVERRIDE { |
| 76 return disk_cache_entry_->GetDataSize(index); | 83 return disk_cache_entry_ ? disk_cache_entry_->GetDataSize(index) : 0L; |
| 77 } | 84 } |
| 78 | 85 |
| 79 virtual void Close() OVERRIDE { | 86 virtual void Close() OVERRIDE { |
| 80 disk_cache_entry_->Close(); | 87 if (disk_cache_entry_) |
| 88 disk_cache_entry_->Close(); |
| 81 delete this; | 89 delete this; |
| 82 } | 90 } |
| 83 | 91 |
| 92 void Abandon() { |
| 93 owner_ = NULL; |
| 94 disk_cache_entry_->Close(); |
| 95 disk_cache_entry_ = NULL; |
| 96 } |
| 97 |
| 84 private: | 98 private: |
| 99 virtual ~EntryImpl() { |
| 100 if (owner_) |
| 101 owner_->RemoveOpenEntry(this); |
| 102 } |
| 103 |
| 85 disk_cache::Entry* disk_cache_entry_; | 104 disk_cache::Entry* disk_cache_entry_; |
| 105 AppCacheDiskCache* owner_; |
| 86 }; | 106 }; |
| 87 | 107 |
| 88 // Separate object to hold state for each Create, Delete, or Doom call | 108 // Separate object to hold state for each Create, Delete, or Doom call |
| 89 // while the call is in-flight and to produce an EntryImpl upon completion. | 109 // while the call is in-flight and to produce an EntryImpl upon completion. |
| 90 class AppCacheDiskCache::ActiveCall { | 110 class AppCacheDiskCache::ActiveCall { |
| 91 public: | 111 public: |
| 92 explicit ActiveCall(AppCacheDiskCache* owner) | 112 explicit ActiveCall(AppCacheDiskCache* owner) |
| 93 : entry_(NULL), | 113 : entry_(NULL), |
| 94 owner_(owner), | 114 owner_(owner), |
| 95 entry_ptr_(NULL) { | 115 entry_ptr_(NULL) { |
| (...skipping 26 matching lines...) Expand all Loading... |
| 122 int HandleImmediateReturnValue(int rv, Entry** entry, | 142 int HandleImmediateReturnValue(int rv, Entry** entry, |
| 123 const net::CompletionCallback& callback) { | 143 const net::CompletionCallback& callback) { |
| 124 if (rv == net::ERR_IO_PENDING) { | 144 if (rv == net::ERR_IO_PENDING) { |
| 125 // OnAsyncCompletion will be called later. | 145 // OnAsyncCompletion will be called later. |
| 126 callback_ = callback; | 146 callback_ = callback; |
| 127 entry_ = entry; | 147 entry_ = entry; |
| 128 owner_->AddActiveCall(this); | 148 owner_->AddActiveCall(this); |
| 129 return net::ERR_IO_PENDING; | 149 return net::ERR_IO_PENDING; |
| 130 } | 150 } |
| 131 if (rv == net::OK && entry) | 151 if (rv == net::OK && entry) |
| 132 *entry = new EntryImpl(entry_ptr_); | 152 *entry = new EntryImpl(entry_ptr_, owner_); |
| 133 delete this; | 153 delete this; |
| 134 return rv; | 154 return rv; |
| 135 } | 155 } |
| 136 | 156 |
| 137 void OnAsyncCompletion(int rv) { | 157 void OnAsyncCompletion(int rv) { |
| 138 owner_->RemoveActiveCall(this); | 158 owner_->RemoveActiveCall(this); |
| 139 if (rv == net::OK && entry_) | 159 if (rv == net::OK && entry_) |
| 140 *entry_ = new EntryImpl(entry_ptr_); | 160 *entry_ = new EntryImpl(entry_ptr_, owner_); |
| 141 callback_.Run(rv); | 161 callback_.Run(rv); |
| 142 callback_.Reset(); | 162 callback_.Reset(); |
| 143 delete this; | 163 delete this; |
| 144 } | 164 } |
| 145 | 165 |
| 146 Entry** entry_; | 166 Entry** entry_; |
| 147 net::CompletionCallback callback_; | 167 net::CompletionCallback callback_; |
| 148 AppCacheDiskCache* owner_; | 168 AppCacheDiskCache* owner_; |
| 149 disk_cache::Entry* entry_ptr_; | 169 disk_cache::Entry* entry_ptr_; |
| 150 }; | 170 }; |
| 151 | 171 |
| 152 AppCacheDiskCache::AppCacheDiskCache() | 172 AppCacheDiskCache::AppCacheDiskCache() |
| 153 : is_disabled_(false) { | 173 : is_disabled_(false) { |
| 154 } | 174 } |
| 155 | 175 |
| 156 AppCacheDiskCache::~AppCacheDiskCache() { | 176 AppCacheDiskCache::~AppCacheDiskCache() { |
| 157 if (create_backend_callback_.get()) { | 177 Disable(); |
| 158 create_backend_callback_->Cancel(); | |
| 159 create_backend_callback_ = NULL; | |
| 160 OnCreateBackendComplete(net::ERR_ABORTED); | |
| 161 } | |
| 162 disk_cache_.reset(); | |
| 163 STLDeleteElements(&active_calls_); | |
| 164 } | 178 } |
| 165 | 179 |
| 166 int AppCacheDiskCache::InitWithDiskBackend( | 180 int AppCacheDiskCache::InitWithDiskBackend( |
| 167 const base::FilePath& disk_cache_directory, int disk_cache_size, bool force, | 181 const base::FilePath& disk_cache_directory, int disk_cache_size, bool force, |
| 168 base::MessageLoopProxy* cache_thread, | 182 base::MessageLoopProxy* cache_thread, |
| 169 const net::CompletionCallback& callback) { | 183 const net::CompletionCallback& callback) { |
| 170 return Init(net::APP_CACHE, disk_cache_directory, | 184 return Init(net::APP_CACHE, disk_cache_directory, |
| 171 disk_cache_size, force, cache_thread, callback); | 185 disk_cache_size, force, cache_thread, callback); |
| 172 } | 186 } |
| 173 | 187 |
| 174 int AppCacheDiskCache::InitWithMemBackend( | 188 int AppCacheDiskCache::InitWithMemBackend( |
| 175 int mem_cache_size, const net::CompletionCallback& callback) { | 189 int mem_cache_size, const net::CompletionCallback& callback) { |
| 176 return Init(net::MEMORY_CACHE, base::FilePath(), mem_cache_size, false, NULL, | 190 return Init(net::MEMORY_CACHE, base::FilePath(), mem_cache_size, false, NULL, |
| 177 callback); | 191 callback); |
| 178 } | 192 } |
| 179 | 193 |
| 180 void AppCacheDiskCache::Disable() { | 194 void AppCacheDiskCache::Disable() { |
| 181 if (is_disabled_) | 195 if (is_disabled_) |
| 182 return; | 196 return; |
| 183 | 197 |
| 184 is_disabled_ = true; | 198 is_disabled_ = true; |
| 185 | 199 |
| 186 if (create_backend_callback_.get()) { | 200 if (create_backend_callback_.get()) { |
| 187 create_backend_callback_->Cancel(); | 201 create_backend_callback_->Cancel(); |
| 188 create_backend_callback_ = NULL; | 202 create_backend_callback_ = NULL; |
| 189 OnCreateBackendComplete(net::ERR_ABORTED); | 203 OnCreateBackendComplete(net::ERR_ABORTED); |
| 190 } | 204 } |
| 205 |
| 206 // We need to close open file handles in order to reinitalize the |
| 207 // appcache system on the fly. File handles held in both entries and in |
| 208 // the main disk_cache::Backend class need to be released. |
| 209 for (OpenEntries::const_iterator iter = open_entries_.begin(); |
| 210 iter != open_entries_.end(); ++iter) { |
| 211 (*iter)->Abandon(); |
| 212 } |
| 213 open_entries_.clear(); |
| 214 disk_cache_.reset(); |
| 215 STLDeleteElements(&active_calls_); |
| 191 } | 216 } |
| 192 | 217 |
| 193 int AppCacheDiskCache::CreateEntry(int64 key, Entry** entry, | 218 int AppCacheDiskCache::CreateEntry(int64 key, Entry** entry, |
| 194 const net::CompletionCallback& callback) { | 219 const net::CompletionCallback& callback) { |
| 195 DCHECK(entry); | 220 DCHECK(entry); |
| 196 DCHECK(!callback.is_null()); | 221 DCHECK(!callback.is_null()); |
| 197 if (is_disabled_) | 222 if (is_disabled_) |
| 198 return net::ERR_ABORTED; | 223 return net::ERR_ABORTED; |
| 199 | 224 |
| 200 if (is_initializing()) { | 225 if (is_initializing()) { |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 317 NOTREACHED(); | 342 NOTREACHED(); |
| 318 break; | 343 break; |
| 319 } | 344 } |
| 320 if (rv != net::ERR_IO_PENDING) | 345 if (rv != net::ERR_IO_PENDING) |
| 321 iter->callback.Run(rv); | 346 iter->callback.Run(rv); |
| 322 } | 347 } |
| 323 pending_calls_.clear(); | 348 pending_calls_.clear(); |
| 324 } | 349 } |
| 325 | 350 |
| 326 } // namespace appcache | 351 } // namespace appcache |
| OLD | NEW |