Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1149)

Unified Diff: content/browser/service_worker/service_worker_cache_storage.cc

Issue 460683002: Change threading in ServiceWorkerCacheStorage (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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 d679d3e6242b235f2bc67eab5e4251d334ef72ba..1aa75e38b1d79645fb263cff97027adc2bf38fd5 100644
--- a/content/browser/service_worker/service_worker_cache_storage.cc
+++ b/content/browser/service_worker/service_worker_cache_storage.cc
@@ -15,74 +15,202 @@
#include "content/browser/service_worker/service_worker_cache.pb.h"
#include "content/public/browser/browser_thread.h"
#include "net/base/directory_lister.h"
+#include "net/base/net_errors.h"
namespace content {
// Handles the loading and clean up of ServiceWorkerCache objects.
class ServiceWorkerCacheStorage::CacheLoader {
public:
+ typedef base::Callback<void(ServiceWorkerCache*)> CacheCallback;
+ typedef base::Callback<void(bool)> BoolCallback;
+ typedef base::Callback<void(scoped_ptr<std::vector<std::string> >)>
+ StringsCallback;
+
+ explicit CacheLoader(base::SequencedTaskRunner* cache_task_runner)
+ : cache_task_runner_(cache_task_runner) {}
+
virtual ~CacheLoader() {};
- virtual ServiceWorkerCache* LoadCache(const std::string& cache_name) = 0;
- // Creates a new cache, deleting any pre-existing cache of the same name.
- virtual ServiceWorkerCache* CreateCache(const std::string& cache_name) = 0;
- virtual bool CleanUpDeletedCache(const std::string& key) = 0;
- virtual bool WriteIndex(CacheMap* caches) = 0;
- virtual void LoadIndex(std::vector<std::string>* cache_names) = 0;
+
+ // Loads the given cache_name, the cache is NULL if it fails. If the cache
+ // doesn't exist a new one is created.
+ virtual void LoadCache(const std::string& cache_name,
+ const CacheCallback& callback) = 0;
+
+ // Deletes any pre-existing cache of the same name and then loads it.
+ virtual void CreateCache(const std::string& cache_name,
+ const CacheCallback& callback) = 0;
+
+ // After the backend has been deleted, do any extra house keeping such as
+ // removing the cache's directory.
+ virtual void CleanUpDeletedCache(const std::string& key,
+ const BoolCallback& callback) = 0;
+
+ // Writes the cache names to disk if applicable.
+ virtual void WriteIndex(CacheMap* caches, const BoolCallback& callback) = 0;
+
+ // Loads the cache names from disk if applicable.
+ virtual void LoadIndex(scoped_ptr<std::vector<std::string> > cache_names,
+ const StringsCallback& callback) = 0;
+
+ protected:
+ virtual void LoadCacheImpl(const std::string&) {}
+ scoped_refptr<base::SequencedTaskRunner> cache_task_runner_;
};
class ServiceWorkerCacheStorage::MemoryLoader
: public ServiceWorkerCacheStorage::CacheLoader {
public:
- virtual content::ServiceWorkerCache* LoadCache(
- const std::string& cache_name) OVERRIDE {
+ explicit MemoryLoader(base::SequencedTaskRunner* cache_task_runner)
+ : CacheLoader(cache_task_runner) {}
+ virtual void LoadCache(const std::string& cache_name,
+ const CacheCallback& callback) OVERRIDE {
NOTREACHED();
- return NULL;
}
- virtual ServiceWorkerCache* CreateCache(
- const std::string& cache_name) OVERRIDE {
- return ServiceWorkerCache::CreateMemoryCache(cache_name);
+ virtual void CreateCache(const std::string& cache_name,
+ const CacheCallback& callback) OVERRIDE {
+ ServiceWorkerCache* cache =
+ ServiceWorkerCache::CreateMemoryCache(cache_name);
+ callback.Run(cache);
}
- virtual bool CleanUpDeletedCache(const std::string& cache_name) OVERRIDE {
- return true;
+ virtual void CleanUpDeletedCache(const std::string& cache_name,
+ const BoolCallback& callback) OVERRIDE {
+ callback.Run(true);
}
- virtual bool WriteIndex(CacheMap* caches) OVERRIDE { return false; }
+ virtual void WriteIndex(CacheMap* caches,
+ const BoolCallback& callback) OVERRIDE {
+ callback.Run(false);
+ }
- virtual void LoadIndex(std::vector<std::string>* cache_names) OVERRIDE {
- return;
+ virtual void LoadIndex(scoped_ptr<std::vector<std::string> > cache_names,
+ const StringsCallback& callback) OVERRIDE {
+ callback.Run(cache_names.Pass());
}
};
class ServiceWorkerCacheStorage::SimpleCacheLoader
: public ServiceWorkerCacheStorage::CacheLoader {
public:
- explicit SimpleCacheLoader(const base::FilePath& origin_path)
- : origin_path_(origin_path) {}
+ SimpleCacheLoader(const base::FilePath& origin_path,
+ base::SequencedTaskRunner* cache_task_runner)
+ : CacheLoader(cache_task_runner), origin_path_(origin_path) {}
+
+ virtual void LoadCache(const std::string& cache_name,
+ const CacheCallback& callback) OVERRIDE {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ // 1. Create the cache's directory if necessary. (LoadCreateDirectory)
+ // 2. Create the cache object. (LoadDidCreateDirectory)
+
+ cache_task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&SimpleCacheLoader::LoadCreateDirectoryInPool,
+ base::Unretained(this), // should be weak_ptr?
michaeln 2014/08/11 19:30:17 unretained is no good... deriving CacheLoader from
jkarlin 2014/08/12 14:55:02 Done.
+ CreatePersistentCachePath(origin_path_, cache_name),
+ cache_name,
+ callback,
+ base::MessageLoopProxy::current()));
+ }
- virtual ServiceWorkerCache* LoadCache(
- const std::string& cache_name) OVERRIDE {
- base::CreateDirectory(CreatePersistentCachePath(origin_path_, cache_name));
- return ServiceWorkerCache::CreatePersistentCache(
+ void LoadCreateDirectoryInPool(
+ const base::FilePath& path,
+ const std::string& cache_name,
+ const CacheCallback& callback,
+ scoped_refptr<base::MessageLoopProxy> original_loop) {
+ bool rv = base::CreateDirectory(path);
+ original_loop->PostTask(
+ FROM_HERE,
+ base::Bind(&SimpleCacheLoader::LoadDidCreateDirectory,
+ base::Unretained(this),
+ cache_name,
+ callback,
+ rv));
+ }
+
+ void LoadDidCreateDirectory(const std::string& cache_name,
+ const CacheCallback& callback,
+ bool dir_rv) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ if (!dir_rv) {
+ callback.Run(NULL);
+ return;
+ }
+ ServiceWorkerCache* cache = ServiceWorkerCache::CreatePersistentCache(
CreatePersistentCachePath(origin_path_, cache_name), cache_name);
+ callback.Run(cache);
}
- virtual ServiceWorkerCache* CreateCache(
- const std::string& cache_name) OVERRIDE {
+ virtual void CreateCache(const std::string& cache_name,
+ const CacheCallback& callback) OVERRIDE {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ // 1. Delete the cache's directory if it exists. (CreateDeleteFiles)
michaeln 2014/08/11 20:30:14 (CreateDeleteFiles) s/b (CreateCacheDeleteFilesInP
jkarlin 2014/08/12 14:55:03 Done.
+ // 2. Load the cache. (LoadCache)
+
base::FilePath cache_path =
CreatePersistentCachePath(origin_path_, cache_name);
- if (base::PathExists(cache_path))
- base::DeleteFile(cache_path, /* recursive */ true);
- return LoadCache(cache_name);
+
+ cache_task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&SimpleCacheLoader::CreateCacheDeleteFilesInPool,
+ base::Unretained(this), // should be weak_ptr?
+ cache_path,
+ cache_name,
+ callback,
+ base::MessageLoopProxy::current()));
}
- virtual bool CleanUpDeletedCache(const std::string& cache_name) OVERRIDE {
- return base::DeleteFile(CreatePersistentCachePath(origin_path_, cache_name),
- true);
+ void CreateCacheDeleteFilesInPool(
+ const base::FilePath& cache_path,
+ const std::string& cache_name,
+ const CacheCallback& callback,
+ scoped_refptr<base::MessageLoopProxy> original_loop) {
michaeln 2014/08/11 20:30:14 maybe add DCHECKS for cache_task_runner_.RunTasksO
jkarlin 2014/08/12 14:55:03 Great idea, thanks!
+ base::FilePath path(cache_path);
+ if (base::PathExists(path))
+ base::DeleteFile(path, /* recursive */ true);
+ original_loop->PostTask(FROM_HERE,
+ base::Bind(&SimpleCacheLoader::LoadCache,
michaeln 2014/08/11 20:30:14 This operation take multiple hops to the cache_thr
jkarlin 2014/08/12 14:55:03 Done.
+ base::Unretained(this),
+ cache_name,
+ callback));
}
- virtual bool WriteIndex(CacheMap* caches) OVERRIDE {
+ virtual void CleanUpDeletedCache(const std::string& cache_name,
+ const BoolCallback& callback) OVERRIDE {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ // 1. Delete the cache's directory. (CleanUpDeleteCacheDir)
+
+ base::FilePath cache_path =
+ CreatePersistentCachePath(origin_path_, cache_name);
+ cache_task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&SimpleCacheLoader::CleanUpDeleteCacheDirInPool,
+ base::Unretained(this),
+ cache_path,
+ callback,
+ base::MessageLoopProxy::current()));
+ }
+
+ void CleanUpDeleteCacheDirInPool(
+ const base::FilePath& cache_path,
+ const BoolCallback& callback,
+ scoped_refptr<base::MessageLoopProxy> original_loop) {
michaeln 2014/08/11 20:30:14 can these be const refs (or a rawptr) to the Messa
jkarlin 2014/08/12 14:55:02 Thanks! Done.
+ bool rv = base::DeleteFile(cache_path, true);
+ original_loop->PostTask(FROM_HERE, base::Bind(callback, rv));
+ }
+
+ virtual void WriteIndex(CacheMap* caches,
+ const BoolCallback& callback) OVERRIDE {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ // 1. Create the index file as a string. (WriteIndex)
+ // 2. Write the file to disk. (WriteIndexWriteToFile)
+
ServiceWorkerCacheStorageIndex index;
for (CacheMap::const_iterator iter(caches); !iter.IsAtEnd();
@@ -100,23 +228,75 @@ class ServiceWorkerCacheStorage::SimpleCacheLoader
base::FilePath tmp_path = origin_path_.AppendASCII("index.txt.tmp");
base::FilePath index_path = origin_path_.AppendASCII("index.txt");
- int bytes_written =
- base::WriteFile(tmp_path, serialized.c_str(), serialized.size());
- if (bytes_written != implicit_cast<int>(serialized.size())) {
+ cache_task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&SimpleCacheLoader::WriteIndexWriteToFileInPool,
+ base::Unretained(this), // should be weak?
+ tmp_path,
+ index_path,
+ serialized,
+ caches,
+ callback,
+ base::MessageLoopProxy::current()));
+ }
+
+ void WriteIndexWriteToFileInPool(
+ const base::FilePath& tmp_path,
+ const base::FilePath& index_path,
+ const std::string& data,
+ CacheMap* caches,
+ const BoolCallback& callback,
+ scoped_refptr<base::MessageLoopProxy> original_loop) {
+ int bytes_written = base::WriteFile(tmp_path, data.c_str(), data.size());
+ if (bytes_written != implicit_cast<int>(data.size())) {
base::DeleteFile(tmp_path, /* recursive */ false);
- return false;
+ original_loop->PostTask(FROM_HERE, base::Bind(callback, false));
}
// Atomically rename the temporary index file to become the real one.
- return base::ReplaceFile(tmp_path, index_path, NULL);
+ bool rv = base::ReplaceFile(tmp_path, index_path, NULL);
+ original_loop->PostTask(FROM_HERE, base::Bind(callback, rv));
}
- virtual void LoadIndex(std::vector<std::string>* names) OVERRIDE {
+ virtual void LoadIndex(scoped_ptr<std::vector<std::string> > names,
+ const StringsCallback& callback) OVERRIDE {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ // 1. Read the file from disk. (LoadIndexReadFile)
+ // 2. Parse file and return the names of the caches (LoadIndexDidReadFile)
+
base::FilePath index_path = origin_path_.AppendASCII("index.txt");
- std::string serialized;
- if (!base::ReadFileToString(index_path, &serialized))
- return;
+ cache_task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&SimpleCacheLoader::LoadIndexReadFileInPool,
+ base::Unretained(this),
+ index_path,
+ base::Passed(names.Pass()),
+ callback,
+ base::MessageLoopProxy::current()));
+ }
+
+ void LoadIndexReadFileInPool(
+ const base::FilePath& index_path,
+ scoped_ptr<std::vector<std::string> > names,
+ const StringsCallback& callback,
+ scoped_refptr<base::MessageLoopProxy> original_loop) {
+ std::string body;
+ base::ReadFileToString(index_path, &body);
+
+ original_loop->PostTask(FROM_HERE,
+ base::Bind(&SimpleCacheLoader::LoadIndexDidReadFile,
+ base::Unretained(this),
+ base::Passed(names.Pass()),
+ callback,
+ body));
+ }
+
+ void LoadIndexDidReadFile(scoped_ptr<std::vector<std::string> > names,
+ const StringsCallback& callback,
+ const std::string& serialized) {
+ DCHECK(thread_checker_.CalledOnValidThread());
ServiceWorkerCacheStorageIndex index;
index.ParseFromString(serialized);
@@ -128,7 +308,7 @@ class ServiceWorkerCacheStorage::SimpleCacheLoader
// TODO(jkarlin): Delete caches that are in the directory and not returned
// in LoadIndex.
- return;
+ callback.Run(names.Pass());
}
private:
@@ -144,18 +324,22 @@ class ServiceWorkerCacheStorage::SimpleCacheLoader
return origin_path.AppendASCII(HexedHash(cache_name));
}
+ base::ThreadChecker thread_checker_;
const base::FilePath origin_path_;
};
ServiceWorkerCacheStorage::ServiceWorkerCacheStorage(
const base::FilePath& path,
bool memory_only,
- const scoped_refptr<base::MessageLoopProxy>& callback_loop)
- : initialized_(false), origin_path_(path), callback_loop_(callback_loop) {
+ base::SequencedTaskRunner* cache_task_runner)
+ : initialized_(false),
+ origin_path_(path),
+ cache_task_runner_(cache_task_runner) {
if (memory_only)
- cache_loader_.reset(new MemoryLoader());
+ cache_loader_.reset(new MemoryLoader(cache_task_runner_));
else
- cache_loader_.reset(new SimpleCacheLoader(origin_path_));
+ cache_loader_.reset(
+ new SimpleCacheLoader(origin_path_, cache_task_runner_));
}
ServiceWorkerCacheStorage::~ServiceWorkerCacheStorage() {
@@ -164,114 +348,130 @@ ServiceWorkerCacheStorage::~ServiceWorkerCacheStorage() {
void ServiceWorkerCacheStorage::CreateCache(
const std::string& cache_name,
const CacheAndErrorCallback& callback) {
- LazyInit();
-
- if (cache_name.empty()) {
- callback_loop_->PostTask(
- FROM_HERE, base::Bind(callback, 0, CACHE_STORAGE_ERROR_EMPTY_KEY));
+ if (!initialized_) {
+ LazyInit(base::Bind(&ServiceWorkerCacheStorage::CreateCache,
+ base::Unretained(this),
+ cache_name,
+ callback));
return;
}
- if (GetLoadedCache(cache_name)) {
- callback_loop_->PostTask(
- FROM_HERE, base::Bind(callback, 0, CACHE_STORAGE_ERROR_EXISTS));
+ if (cache_name.empty()) {
+ callback.Run(0, CACHE_STORAGE_ERROR_EMPTY_KEY);
return;
}
- ServiceWorkerCache* cache = cache_loader_->CreateCache(cache_name);
-
- if (!cache) {
- callback_loop_->PostTask(
- FROM_HERE, base::Bind(callback, 0, CACHE_STORAGE_ERROR_STORAGE));
+ if (GetLoadedCache(cache_name)) {
+ callback.Run(0, CACHE_STORAGE_ERROR_EXISTS);
return;
}
- InitCache(cache);
-
- cache_loader_->WriteIndex(&cache_map_);
-
- cache->CreateBackend(
- base::Bind(&ServiceWorkerCacheStorage::InitializeCacheCallback,
+ cache_loader_->CreateCache(
+ cache_name,
+ base::Bind(&ServiceWorkerCacheStorage::CreateCacheDidCreateCache,
base::Unretained(this),
michaeln 2014/08/11 19:30:17 use of unretained here and in other callbacks can
jkarlin 2014/08/12 14:55:03 Done.
- cache,
+ cache_name,
callback));
}
void ServiceWorkerCacheStorage::GetCache(
const std::string& cache_name,
const CacheAndErrorCallback& callback) {
- LazyInit();
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ if (!initialized_) {
+ LazyInit(base::Bind(&ServiceWorkerCacheStorage::GetCache,
+ base::Unretained(this),
+ cache_name,
+ callback));
+ return;
+ }
if (cache_name.empty()) {
- callback_loop_->PostTask(
- FROM_HERE, base::Bind(callback, 0, CACHE_STORAGE_ERROR_EMPTY_KEY));
+ callback.Run(0, CACHE_STORAGE_ERROR_EMPTY_KEY);
return;
}
ServiceWorkerCache* cache = GetLoadedCache(cache_name);
if (!cache) {
- callback_loop_->PostTask(
- FROM_HERE, base::Bind(callback, 0, CACHE_STORAGE_ERROR_NOT_FOUND));
+ callback.Run(0, CACHE_STORAGE_ERROR_NOT_FOUND);
return;
}
- cache->CreateBackend(
- base::Bind(&ServiceWorkerCacheStorage::InitializeCacheCallback,
- base::Unretained(this),
- cache,
- callback));
+ cache->CreateBackend(base::Bind(&ServiceWorkerCacheStorage::DidCreateBackend,
+ base::Unretained(this),
+ cache,
+ callback));
}
void ServiceWorkerCacheStorage::HasCache(const std::string& cache_name,
const BoolAndErrorCallback& callback) {
- LazyInit();
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ if (!initialized_) {
+ LazyInit(base::Bind(&ServiceWorkerCacheStorage::HasCache,
+ base::Unretained(this),
+ cache_name,
+ callback));
+ return;
+ }
if (cache_name.empty()) {
- callback_loop_->PostTask(
- FROM_HERE, base::Bind(callback, false, CACHE_STORAGE_ERROR_EMPTY_KEY));
+ callback.Run(false, CACHE_STORAGE_ERROR_EMPTY_KEY);
return;
}
bool has_cache = GetLoadedCache(cache_name) != NULL;
- callback_loop_->PostTask(
- FROM_HERE,
- base::Bind(
- callback, has_cache, CACHE_STORAGE_ERROR_NO_ERROR));
+ callback.Run(has_cache, CACHE_STORAGE_ERROR_NO_ERROR);
}
void ServiceWorkerCacheStorage::DeleteCache(
const std::string& cache_name,
const BoolAndErrorCallback& callback) {
- LazyInit();
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ if (!initialized_) {
+ LazyInit(base::Bind(&ServiceWorkerCacheStorage::DeleteCache,
+ base::Unretained(this),
+ cache_name,
+ callback));
+ return;
+ }
if (cache_name.empty()) {
- callback_loop_->PostTask(
- FROM_HERE, base::Bind(callback, false, CACHE_STORAGE_ERROR_EMPTY_KEY));
+ callback.Run(false, CACHE_STORAGE_ERROR_EMPTY_KEY);
return;
}
ServiceWorkerCache* cache = GetLoadedCache(cache_name);
if (!cache) {
- callback_loop_->PostTask(
- FROM_HERE, base::Bind(callback, false, CACHE_STORAGE_ERROR_NOT_FOUND));
+ callback.Run(false, CACHE_STORAGE_ERROR_NOT_FOUND);
return;
}
name_map_.erase(cache_name);
cache_map_.Remove(cache->id()); // deletes cache
- cache_loader_->WriteIndex(&cache_map_); // Update the index.
-
- cache_loader_->CleanUpDeletedCache(cache_name);
-
- callback_loop_->PostTask(
- FROM_HERE, base::Bind(callback, true, CACHE_STORAGE_ERROR_NO_ERROR));
+ // Update the Index
+ cache_loader_->WriteIndex(
+ &cache_map_,
+ base::Bind(&ServiceWorkerCacheStorage::DeleteCacheDidWriteIndex,
+ base::Unretained(this),
+ cache_name,
+ callback));
}
void ServiceWorkerCacheStorage::EnumerateCaches(
const StringsAndErrorCallback& callback) {
- LazyInit();
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ if (!initialized_) {
+ LazyInit(base::Bind(&ServiceWorkerCacheStorage::EnumerateCaches,
+ base::Unretained(this),
+ callback));
+ return;
+ }
std::vector<std::string> names;
for (NameMap::const_iterator it = name_map_.begin(); it != name_map_.end();
@@ -279,52 +479,172 @@ void ServiceWorkerCacheStorage::EnumerateCaches(
names.push_back(it->first);
}
- callback_loop_->PostTask(
- FROM_HERE, base::Bind(callback, names, CACHE_STORAGE_ERROR_NO_ERROR));
+ callback.Run(names, CACHE_STORAGE_ERROR_NO_ERROR);
}
-void ServiceWorkerCacheStorage::InitializeCacheCallback(
+void ServiceWorkerCacheStorage::DidCreateBackend(
const ServiceWorkerCache* cache,
const CacheAndErrorCallback& callback,
bool success) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
if (!success) {
// TODO(jkarlin): This should delete the directory and try again in case
// the cache is simply corrupt.
- callback_loop_->PostTask(
- FROM_HERE, base::Bind(callback, 0, CACHE_STORAGE_ERROR_STORAGE));
+ callback.Run(0, CACHE_STORAGE_ERROR_STORAGE);
return;
}
- callback_loop_->PostTask(
- FROM_HERE,
- base::Bind(callback, cache->id(), CACHE_STORAGE_ERROR_NO_ERROR));
+ 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() {
- if (initialized_)
+void ServiceWorkerCacheStorage::LazyInit(const base::Closure& callback) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(!initialized_);
+
+ init_callbacks_.push_back(callback);
+
+ // If this isn't the first call to LazyInit then return as the initialization
+ // has already started.
+ if (init_callbacks_.size() > 1u)
return;
- std::vector<std::string> indexed_cache_names;
- cache_loader_->LoadIndex(&indexed_cache_names);
+ // 1. Get the list of cache names (async call)
+ // 2. For each cache name, load the cache (async call)
+ // 3. Once each load is complete, update the map variables.
+ // 4. Call the list of waiting callbacks.
- for (std::vector<std::string>::const_iterator it =
- indexed_cache_names.begin();
- it != indexed_cache_names.end();
- ++it) {
- ServiceWorkerCache* cache = cache_loader_->LoadCache(*it);
- InitCache(cache);
+ scoped_ptr<std::vector<std::string> > indexed_cache_names(
+ new std::vector<std::string>());
+
+ cache_loader_->LoadIndex(
+ indexed_cache_names.Pass(),
+ base::Bind(&ServiceWorkerCacheStorage::LazyInitDidLoadIndex,
+ base::Unretained(this),
+ callback));
+}
+
+void ServiceWorkerCacheStorage::LazyInitDidLoadIndex(
+ const base::Closure& callback,
+ scoped_ptr<std::vector<std::string> > indexed_cache_names) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ if (indexed_cache_names->empty()) {
+ LazyInitDone();
+ return;
}
+
+ std::vector<std::string>::const_iterator iter = indexed_cache_names->begin();
+ std::vector<std::string>::const_iterator iter_next = iter + 1;
+
+ cache_loader_->LoadCache(
+ *iter,
+ base::Bind(&ServiceWorkerCacheStorage::LazyInitIterateAndLoadCacheName,
+ base::Unretained(this),
+ callback,
+ base::Passed(indexed_cache_names.Pass()),
+ iter_next));
+}
+
+void ServiceWorkerCacheStorage::LazyInitIterateAndLoadCacheName(
+ const base::Closure& callback,
+ scoped_ptr<std::vector<std::string> > indexed_cache_names,
+ std::vector<std::string>::const_iterator iter,
+ ServiceWorkerCache* cache) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ if (cache)
+ AddCacheToMaps(cache);
+
+ if (iter == indexed_cache_names->end()) {
+ LazyInitDone();
+ return;
+ }
+
+ std::vector<std::string>::const_iterator iter_next = iter + 1;
+ cache_loader_->LoadCache(
+ *iter,
+ base::Bind(&ServiceWorkerCacheStorage::LazyInitIterateAndLoadCacheName,
+ base::Unretained(this),
+ callback,
+ base::Passed(indexed_cache_names.Pass()),
+ iter_next));
+}
+
+void ServiceWorkerCacheStorage::LazyInitDone() {
initialized_ = true;
+ for (std::vector<base::Closure>::iterator it = init_callbacks_.begin();
+ it != init_callbacks_.end();
+ ++it) {
+ it->Run();
+ }
+ init_callbacks_.clear();
}
-void ServiceWorkerCacheStorage::InitCache(ServiceWorkerCache* cache) {
+void ServiceWorkerCacheStorage::AddCacheToMaps(ServiceWorkerCache* cache) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
CacheID id = cache_map_.Add(cache);
name_map_.insert(std::make_pair(cache->name(), id));
cache->set_id(id);
}
+void ServiceWorkerCacheStorage::CreateCacheDidCreateCache(
+ const std::string& cache_name,
+ const CacheAndErrorCallback& callback,
+ ServiceWorkerCache* cache) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ if (!cache) {
+ callback.Run(0, CACHE_STORAGE_ERROR_STORAGE);
+ return;
+ }
+
+ AddCacheToMaps(cache);
+
+ cache_loader_->WriteIndex(
+ &cache_map_,
+ base::Bind(&ServiceWorkerCacheStorage::CreateCacheDidWriteIndex,
+ base::Unretained(this),
+ callback,
+ base::Unretained(cache)));
+}
+
+void ServiceWorkerCacheStorage::CreateCacheDidWriteIndex(
+ const CacheAndErrorCallback& callback,
+ ServiceWorkerCache* cache,
+ bool success) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ cache->CreateBackend(base::Bind(&ServiceWorkerCacheStorage::DidCreateBackend,
+ base::Unretained(this),
+ cache,
+ callback));
+}
+
+void ServiceWorkerCacheStorage::DeleteCacheDidWriteIndex(
+ const std::string& cache_name,
+ const BoolAndErrorCallback& callback,
+ bool success) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ cache_loader_->CleanUpDeletedCache(
+ cache_name,
+ base::Bind(&ServiceWorkerCacheStorage::DeleteCacheDidCleanUp,
+ base::Unretained(this),
+ callback));
+}
+
+void ServiceWorkerCacheStorage::DeleteCacheDidCleanUp(
+ const BoolAndErrorCallback& callback,
+ bool success) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ callback.Run(true, CACHE_STORAGE_ERROR_NO_ERROR);
+}
+
ServiceWorkerCache* ServiceWorkerCacheStorage::GetLoadedCache(
const std::string& cache_name) const {
+ DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(initialized_);
NameMap::const_iterator it = name_map_.find(cache_name);

Powered by Google App Engine
This is Rietveld 408576698