| Index: webkit/browser/appcache/appcache_disk_cache.cc
|
| diff --git a/webkit/browser/appcache/appcache_disk_cache.cc b/webkit/browser/appcache/appcache_disk_cache.cc
|
| index 4aa3e8ef1827ae717c4172169646716c8184a588..9c16f98779e7dc071241f1e2a24460d8fa5ae173 100644
|
| --- a/webkit/browser/appcache/appcache_disk_cache.cc
|
| +++ b/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,
|
|
|