Chromium Code Reviews| Index: content/browser/service_worker/service_worker_cache_storage.cc |
| diff --git a/content/browser/service_worker/service_worker_cache_storage.cc b/content/browser/service_worker/service_worker_cache_storage.cc |
| index 74d476c4292e39058e3875abce0f6b4e2980a21b..734174eb73444c094a7668d57ff5a1e167727000 100644 |
| --- a/content/browser/service_worker/service_worker_cache_storage.cc |
| +++ b/content/browser/service_worker/service_worker_cache_storage.cc |
| @@ -407,6 +407,16 @@ ServiceWorkerCacheStorage::ServiceWorkerCacheStorage( |
| } |
| ServiceWorkerCacheStorage::~ServiceWorkerCacheStorage() { |
| + DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| + |
| + // If init is running call any pending callbacks. Init will cease (due to |
| + // checking the WeakPtr) once this object is deleted. |
| + for (std::vector<base::Closure>::iterator it = init_callbacks_.begin(); |
| + it != init_callbacks_.end(); |
| + ++it) { |
| + it->Run(); |
|
michaeln
2014/08/27 22:00:54
This doesn't look quite right. The set of possible
|
| + } |
| + |
| STLDeleteContainerPairSecondPointers(cache_map_.begin(), cache_map_.end()); |
| } |
| @@ -571,7 +581,6 @@ void ServiceWorkerCacheStorage::DidCreateBackend( |
| callback.Run(cache_id, CACHE_STORAGE_ERROR_NO_ERROR); |
| } |
| -// Init is run lazily so that it is called on the proper MessageLoop. |
| void ServiceWorkerCacheStorage::LazyInit(const base::Closure& callback) { |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| DCHECK(!initialized_); |
| @@ -594,68 +603,83 @@ void ServiceWorkerCacheStorage::LazyInit(const base::Closure& callback) { |
| cache_loader_->LoadIndex( |
| indexed_cache_names.Pass(), |
| base::Bind(&ServiceWorkerCacheStorage::LazyInitDidLoadIndex, |
| - weak_factory_.GetWeakPtr(), |
| - callback)); |
| + callback, |
| + weak_factory_.GetWeakPtr())); |
| } |
| +// static |
| void ServiceWorkerCacheStorage::LazyInitDidLoadIndex( |
| const base::Closure& callback, |
| + base::WeakPtr<ServiceWorkerCacheStorage> storage, |
| scoped_ptr<std::vector<std::string> > indexed_cache_names) { |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| - if (indexed_cache_names->empty()) { |
| - LazyInitDone(); |
| - return; |
| - } |
| + if (!storage) |
| + return; // The callbacks were already run by the destructor. |
| + |
| + if (indexed_cache_names->empty()) |
| + return LazyInitDone(storage); |
| std::vector<std::string>::const_iterator iter = indexed_cache_names->begin(); |
| std::vector<std::string>::const_iterator iter_next = iter + 1; |
| - cache_loader_->LoadCache( |
| + storage->cache_loader_->LoadCache( |
| *iter, |
| base::Bind(&ServiceWorkerCacheStorage::LazyInitIterateAndLoadCacheName, |
| - weak_factory_.GetWeakPtr(), |
| callback, |
| + storage, |
| base::Passed(indexed_cache_names.Pass()), |
| iter_next, |
| *iter)); |
| } |
| +// static |
| void ServiceWorkerCacheStorage::LazyInitIterateAndLoadCacheName( |
| const base::Closure& callback, |
| + base::WeakPtr<ServiceWorkerCacheStorage> storage, |
| scoped_ptr<std::vector<std::string> > indexed_cache_names, |
| const std::vector<std::string>::const_iterator& iter, |
| const std::string& cache_name, |
| scoped_ptr<ServiceWorkerCache> cache) { |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| + if (!storage) |
| + return; // The callbacks were already run by the destructor. |
| + |
| if (cache) |
| - AddCacheToMaps(cache_name, cache.Pass()); |
| + storage->AddCacheToMaps(cache_name, cache.Pass()); |
| if (iter == indexed_cache_names->end()) { |
| - LazyInitDone(); |
| + LazyInitDone(storage); |
| return; |
| } |
| std::vector<std::string>::const_iterator iter_next = iter + 1; |
| - cache_loader_->LoadCache( |
| + storage->cache_loader_->LoadCache( |
| *iter, |
| base::Bind(&ServiceWorkerCacheStorage::LazyInitIterateAndLoadCacheName, |
| - weak_factory_.GetWeakPtr(), |
| callback, |
| + storage, |
| base::Passed(indexed_cache_names.Pass()), |
| iter_next, |
| *iter)); |
| } |
| -void ServiceWorkerCacheStorage::LazyInitDone() { |
| - initialized_ = true; |
| - for (std::vector<base::Closure>::iterator it = init_callbacks_.begin(); |
| - it != init_callbacks_.end(); |
| +// static |
| +void ServiceWorkerCacheStorage::LazyInitDone( |
| + base::WeakPtr<ServiceWorkerCacheStorage> storage) { |
| + DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| + if (!storage) |
| + return; // The callbacks were already run by the destructor. |
| + |
| + storage->initialized_ = true; |
| + for (std::vector<base::Closure>::iterator it = |
| + storage->init_callbacks_.begin(); |
| + it != storage->init_callbacks_.end(); |
| ++it) { |
| it->Run(); |
| } |
| - init_callbacks_.clear(); |
| + storage->init_callbacks_.clear(); |
| } |
| ServiceWorkerCacheStorage::CacheContext* |