diff options
Diffstat (limited to 'chromium/webkit/browser/appcache/appcache_disk_cache.cc')
-rw-r--r-- | chromium/webkit/browser/appcache/appcache_disk_cache.cc | 51 |
1 files changed, 38 insertions, 13 deletions
diff --git a/chromium/webkit/browser/appcache/appcache_disk_cache.cc b/chromium/webkit/browser/appcache/appcache_disk_cache.cc index 4aa3e8ef182..9c16f98779e 100644 --- a/chromium/webkit/browser/appcache/appcache_disk_cache.cc +++ b/chromium/webkit/browser/appcache/appcache_disk_cache.cc @@ -49,9 +49,12 @@ class AppCacheDiskCache::CreateBackendCallbackShim // wrapper around disk_cache::Entry. class AppCacheDiskCache::EntryImpl : public Entry { public: - explicit EntryImpl(disk_cache::Entry* disk_cache_entry) - : disk_cache_entry_(disk_cache_entry) { + EntryImpl(disk_cache::Entry* disk_cache_entry, + AppCacheDiskCache* owner) + : disk_cache_entry_(disk_cache_entry), owner_(owner) { DCHECK(disk_cache_entry); + DCHECK(owner); + owner_->AddOpenEntry(this); } // Entry implementation. @@ -59,6 +62,8 @@ class AppCacheDiskCache::EntryImpl : public Entry { const net::CompletionCallback& callback) OVERRIDE { if (offset < 0 || offset > kint32max) return net::ERR_INVALID_ARGUMENT; + if (!disk_cache_entry_) + return net::ERR_ABORTED; return disk_cache_entry_->ReadData( index, static_cast<int>(offset), buf, buf_len, callback); } @@ -67,22 +72,37 @@ class AppCacheDiskCache::EntryImpl : public Entry { const net::CompletionCallback& callback) OVERRIDE { if (offset < 0 || offset > kint32max) return net::ERR_INVALID_ARGUMENT; + if (!disk_cache_entry_) + return net::ERR_ABORTED; const bool kTruncate = true; return disk_cache_entry_->WriteData( index, static_cast<int>(offset), buf, buf_len, callback, kTruncate); } virtual int64 GetSize(int index) OVERRIDE { - return disk_cache_entry_->GetDataSize(index); + return disk_cache_entry_ ? disk_cache_entry_->GetDataSize(index) : 0L; } virtual void Close() OVERRIDE { - disk_cache_entry_->Close(); + if (disk_cache_entry_) + disk_cache_entry_->Close(); delete this; } + void Abandon() { + owner_ = NULL; + disk_cache_entry_->Close(); + disk_cache_entry_ = NULL; + } + private: + virtual ~EntryImpl() { + if (owner_) + owner_->RemoveOpenEntry(this); + } + disk_cache::Entry* disk_cache_entry_; + AppCacheDiskCache* owner_; }; // Separate object to hold state for each Create, Delete, or Doom call @@ -129,7 +149,7 @@ class AppCacheDiskCache::ActiveCall { return net::ERR_IO_PENDING; } if (rv == net::OK && entry) - *entry = new EntryImpl(entry_ptr_); + *entry = new EntryImpl(entry_ptr_, owner_); delete this; return rv; } @@ -137,7 +157,7 @@ class AppCacheDiskCache::ActiveCall { void OnAsyncCompletion(int rv) { owner_->RemoveActiveCall(this); if (rv == net::OK && entry_) - *entry_ = new EntryImpl(entry_ptr_); + *entry_ = new EntryImpl(entry_ptr_, owner_); callback_.Run(rv); callback_.Reset(); delete this; @@ -154,13 +174,7 @@ AppCacheDiskCache::AppCacheDiskCache() } AppCacheDiskCache::~AppCacheDiskCache() { - if (create_backend_callback_.get()) { - create_backend_callback_->Cancel(); - create_backend_callback_ = NULL; - OnCreateBackendComplete(net::ERR_ABORTED); - } - disk_cache_.reset(); - STLDeleteElements(&active_calls_); + Disable(); } int AppCacheDiskCache::InitWithDiskBackend( @@ -188,6 +202,17 @@ void AppCacheDiskCache::Disable() { create_backend_callback_ = NULL; OnCreateBackendComplete(net::ERR_ABORTED); } + + // We need to close open file handles in order to reinitalize the + // appcache system on the fly. File handles held in both entries and in + // the main disk_cache::Backend class need to be released. + for (OpenEntries::const_iterator iter = open_entries_.begin(); + iter != open_entries_.end(); ++iter) { + (*iter)->Abandon(); + } + open_entries_.clear(); + disk_cache_.reset(); + STLDeleteElements(&active_calls_); } int AppCacheDiskCache::CreateEntry(int64 key, Entry** entry, |