 Chromium Code Reviews
 Chromium Code Reviews Issue 137493003:
  Appcache::OnCorruptionDetected handling  (Closed) 
  Base URL: svn://svn.chromium.org/chrome/trunk/src
    
  
    Issue 137493003:
  Appcache::OnCorruptionDetected handling  (Closed) 
  Base URL: svn://svn.chromium.org/chrome/trunk/src| 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; | 
| 
jsbell
2014/01/24 21:13:44
nit: space between _ and ?
 
michaeln
2014/01/28 22:12:16
Done.
 | |
| 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 |