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

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

Issue 867903005: [ServiceWorkerCache] Serialize ServiceWorkerCacheStorage operations (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address comments from PS3 Created 5 years, 10 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 539cafb2e23b275d7883390a0919374c3a5444cb..d5fb07c6789be43dc86f66bce251e0ed19fa0b81 100644
--- a/content/browser/service_worker/service_worker_cache_storage.cc
+++ b/content/browser/service_worker/service_worker_cache_storage.cc
@@ -16,6 +16,7 @@
#include "base/strings/string_util.h"
#include "content/browser/service_worker/service_worker_cache.h"
#include "content/browser/service_worker/service_worker_cache.pb.h"
+#include "content/browser/service_worker/service_worker_cache_scheduler.h"
#include "content/public/browser/browser_thread.h"
#include "net/base/directory_lister.h"
#include "net/base/net_errors.h"
@@ -377,6 +378,8 @@ ServiceWorkerCacheStorage::ServiceWorkerCacheStorage(
base::WeakPtr<storage::BlobStorageContext> blob_context,
const GURL& origin)
: initialized_(false),
+ initializing_(false),
+ scheduler_(new ServiceWorkerCacheScheduler()),
origin_path_(path),
cache_task_runner_(cache_task_runner),
memory_only_(memory_only),
@@ -404,43 +407,30 @@ void ServiceWorkerCacheStorage::OpenCache(
const CacheAndErrorCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (!initialized_) {
- LazyInit(base::Bind(&ServiceWorkerCacheStorage::OpenCache,
- weak_factory_.GetWeakPtr(),
- cache_name,
- callback));
- return;
- }
-
- scoped_refptr<ServiceWorkerCache> cache = GetLoadedCache(cache_name);
- if (cache.get()) {
- callback.Run(cache, CACHE_STORAGE_ERROR_NO_ERROR);
- return;
- }
+ if (!initialized_)
+ LazyInit();
- cache_loader_->CreateCache(
- cache_name,
- base::Bind(&ServiceWorkerCacheStorage::CreateCacheDidCreateCache,
- weak_factory_.GetWeakPtr(),
- cache_name,
- callback));
+ CacheAndErrorCallback pending_callback =
+ base::Bind(&ServiceWorkerCacheStorage::PendingCacheAndErrorCallback,
+ weak_factory_.GetWeakPtr(), callback);
+ scheduler_->ScheduleOperation(
+ base::Bind(&ServiceWorkerCacheStorage::OpenCacheImpl,
+ weak_factory_.GetWeakPtr(), cache_name, pending_callback));
}
void ServiceWorkerCacheStorage::HasCache(const std::string& cache_name,
const BoolAndErrorCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (!initialized_) {
- LazyInit(base::Bind(&ServiceWorkerCacheStorage::HasCache,
- weak_factory_.GetWeakPtr(),
- cache_name,
- callback));
- return;
- }
+ if (!initialized_)
+ LazyInit();
- bool has_cache = cache_map_.find(cache_name) != cache_map_.end();
-
- callback.Run(has_cache, CACHE_STORAGE_ERROR_NO_ERROR);
+ BoolAndErrorCallback pending_callback =
+ base::Bind(&ServiceWorkerCacheStorage::PendingBoolAndErrorCallback,
+ weak_factory_.GetWeakPtr(), callback);
+ scheduler_->ScheduleOperation(
+ base::Bind(&ServiceWorkerCacheStorage::HasCacheImpl,
+ weak_factory_.GetWeakPtr(), cache_name, pending_callback));
}
void ServiceWorkerCacheStorage::DeleteCache(
@@ -448,54 +438,30 @@ void ServiceWorkerCacheStorage::DeleteCache(
const BoolAndErrorCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (!initialized_) {
- LazyInit(base::Bind(&ServiceWorkerCacheStorage::DeleteCache,
- weak_factory_.GetWeakPtr(),
- cache_name,
- callback));
- return;
- }
+ if (!initialized_)
+ LazyInit();
- CacheMap::iterator it = cache_map_.find(cache_name);
- if (it == cache_map_.end()) {
- callback.Run(false, CACHE_STORAGE_ERROR_NOT_FOUND);
- return;
- }
-
- base::WeakPtr<ServiceWorkerCache> cache = it->second;
- cache_map_.erase(it);
-
- // Delete the name from ordered_cache_names_.
- StringVector::iterator iter = std::find(
- ordered_cache_names_.begin(), ordered_cache_names_.end(), cache_name);
- DCHECK(iter != ordered_cache_names_.end());
- ordered_cache_names_.erase(iter);
-
- base::Closure closure =
- base::Bind(&ServiceWorkerCacheStorage::DeleteCacheDidClose,
- weak_factory_.GetWeakPtr(), cache_name, callback,
- ordered_cache_names_, make_scoped_refptr(cache.get()));
-
- if (cache) {
- cache->Close(closure);
- return;
- }
-
- closure.Run();
+ BoolAndErrorCallback pending_callback =
+ base::Bind(&ServiceWorkerCacheStorage::PendingBoolAndErrorCallback,
+ weak_factory_.GetWeakPtr(), callback);
+ scheduler_->ScheduleOperation(
+ base::Bind(&ServiceWorkerCacheStorage::DeleteCacheImpl,
+ weak_factory_.GetWeakPtr(), cache_name, pending_callback));
}
void ServiceWorkerCacheStorage::EnumerateCaches(
const StringsAndErrorCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (!initialized_) {
- LazyInit(base::Bind(&ServiceWorkerCacheStorage::EnumerateCaches,
- weak_factory_.GetWeakPtr(),
- callback));
- return;
- }
+ if (!initialized_)
+ LazyInit();
- callback.Run(ordered_cache_names_, CACHE_STORAGE_ERROR_NO_ERROR);
+ StringsAndErrorCallback pending_callback =
+ base::Bind(&ServiceWorkerCacheStorage::PendingStringsAndErrorCallback,
+ weak_factory_.GetWeakPtr(), callback);
+ scheduler_->ScheduleOperation(
+ base::Bind(&ServiceWorkerCacheStorage::EnumerateCachesImpl,
+ weak_factory_.GetWeakPtr(), pending_callback));
}
void ServiceWorkerCacheStorage::MatchCache(
@@ -504,27 +470,15 @@ void ServiceWorkerCacheStorage::MatchCache(
const ServiceWorkerCache::ResponseCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (!initialized_) {
- LazyInit(base::Bind(&ServiceWorkerCacheStorage::MatchCache,
- weak_factory_.GetWeakPtr(), cache_name,
- base::Passed(request.Pass()), callback));
- return;
- }
+ if (!initialized_)
+ LazyInit();
- scoped_refptr<ServiceWorkerCache> cache = GetLoadedCache(cache_name);
-
- if (!cache.get()) {
- callback.Run(ServiceWorkerCache::ErrorTypeNotFound,
- scoped_ptr<ServiceWorkerResponse>(),
- scoped_ptr<storage::BlobDataHandle>());
- return;
- }
-
- // Pass the cache along to the callback to keep the cache open until match is
- // done.
- cache->Match(request.Pass(),
- base::Bind(&ServiceWorkerCacheStorage::MatchCacheDidMatch,
- weak_factory_.GetWeakPtr(), cache, callback));
+ ServiceWorkerCache::ResponseCallback pending_callback =
+ base::Bind(&ServiceWorkerCacheStorage::PendingResponseCallback,
+ weak_factory_.GetWeakPtr(), callback);
+ scheduler_->ScheduleOperation(base::Bind(
+ &ServiceWorkerCacheStorage::MatchCacheImpl, weak_factory_.GetWeakPtr(),
+ cache_name, base::Passed(request.Pass()), pending_callback));
}
void ServiceWorkerCacheStorage::MatchAllCaches(
@@ -532,32 +486,16 @@ void ServiceWorkerCacheStorage::MatchAllCaches(
const ServiceWorkerCache::ResponseCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (!initialized_) {
- LazyInit(base::Bind(&ServiceWorkerCacheStorage::MatchAllCaches,
- weak_factory_.GetWeakPtr(),
- base::Passed(request.Pass()), callback));
- return;
- }
-
- scoped_ptr<ServiceWorkerCache::ResponseCallback> callback_copy(
- new ServiceWorkerCache::ResponseCallback(callback));
-
- ServiceWorkerCache::ResponseCallback* callback_ptr = callback_copy.get();
- base::Closure barrier_closure = base::BarrierClosure(
- ordered_cache_names_.size(),
- base::Bind(&ServiceWorkerCacheStorage::MatchAllCachesDidMatchAll,
- weak_factory_.GetWeakPtr(),
- base::Passed(callback_copy.Pass())));
-
- for (const std::string& cache_name : ordered_cache_names_) {
- scoped_refptr<ServiceWorkerCache> cache = GetLoadedCache(cache_name);
- DCHECK(cache.get());
+ if (!initialized_)
+ LazyInit();
- cache->Match(make_scoped_ptr(new ServiceWorkerFetchRequest(*request)),
- base::Bind(&ServiceWorkerCacheStorage::MatchAllCachesDidMatch,
- weak_factory_.GetWeakPtr(), cache, barrier_closure,
- callback_ptr));
- }
+ ServiceWorkerCache::ResponseCallback pending_callback =
+ base::Bind(&ServiceWorkerCacheStorage::PendingResponseCallback,
+ weak_factory_.GetWeakPtr(), callback);
+ scheduler_->ScheduleOperation(
+ base::Bind(&ServiceWorkerCacheStorage::MatchAllCachesImpl,
+ weak_factory_.GetWeakPtr(), base::Passed(request.Pass()),
+ pending_callback));
}
void ServiceWorkerCacheStorage::CloseAllCaches(const base::Closure& callback) {
@@ -568,31 +506,12 @@ void ServiceWorkerCacheStorage::CloseAllCaches(const base::Closure& callback) {
return;
}
- int live_cache_count = 0;
- for (const auto& key_value : cache_map_) {
- if (key_value.second)
- live_cache_count += 1;
- }
-
- if (live_cache_count == 0) {
- callback.Run();
- return;
- }
-
- // The closure might modify this object so delay calling it until after
- // iterating through cache_map_ by adding one to the barrier.
- base::Closure barrier_closure =
- base::BarrierClosure(live_cache_count + 1, base::Bind(callback));
-
- for (auto& key_value : cache_map_) {
- if (key_value.second) {
- key_value.second->Close(base::Bind(
- CloseAllCachesDidCloseCache,
- make_scoped_refptr(key_value.second.get()), barrier_closure));
- }
- }
-
- barrier_closure.Run();
+ base::Closure pending_callback =
+ base::Bind(&ServiceWorkerCacheStorage::PendingClosure,
+ weak_factory_.GetWeakPtr(), callback);
+ scheduler_->ScheduleOperation(
+ base::Bind(&ServiceWorkerCacheStorage::CloseAllCachesImpl,
+ weak_factory_.GetWeakPtr(), pending_callback));
}
int64 ServiceWorkerCacheStorage::MemoryBackedSize() const {
@@ -609,18 +528,34 @@ int64 ServiceWorkerCacheStorage::MemoryBackedSize() const {
return sum;
}
+void ServiceWorkerCacheStorage::StartAsyncOperationForTesting() {
+ scheduler_->ScheduleOperation(base::Bind(&base::DoNothing));
+}
+
+void ServiceWorkerCacheStorage::CompleteAsyncOperationForTesting() {
+ scheduler_->CompleteOperationAndRunNext();
+}
+
// Init is run lazily so that it is called on the proper MessageLoop.
-void ServiceWorkerCacheStorage::LazyInit(const base::Closure& callback) {
+void ServiceWorkerCacheStorage::LazyInit() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
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)
+ if (initializing_)
return;
+ DCHECK(scheduler_->Empty());
+
+ initializing_ = true;
+ scheduler_->ScheduleOperation(base::Bind(
+ &ServiceWorkerCacheStorage::LazyInitImpl, weak_factory_.GetWeakPtr()));
+}
+
+void ServiceWorkerCacheStorage::LazyInitImpl() {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ DCHECK(!initialized_);
+ DCHECK(initializing_);
+
// 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.
@@ -632,12 +567,10 @@ void ServiceWorkerCacheStorage::LazyInit(const base::Closure& callback) {
cache_loader_->LoadIndex(
indexed_cache_names.Pass(),
base::Bind(&ServiceWorkerCacheStorage::LazyInitDidLoadIndex,
- weak_factory_.GetWeakPtr(),
- callback));
+ weak_factory_.GetWeakPtr()));
}
void ServiceWorkerCacheStorage::LazyInitDidLoadIndex(
- const base::Closure& callback,
scoped_ptr<std::vector<std::string> > indexed_cache_names) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -647,13 +580,25 @@ void ServiceWorkerCacheStorage::LazyInitDidLoadIndex(
ordered_cache_names_.push_back(indexed_cache_names->at(i));
}
+ initializing_ = false;
initialized_ = true;
- for (std::vector<base::Closure>::iterator it = init_callbacks_.begin();
- it != init_callbacks_.end();
- ++it) {
- it->Run();
+
+ scheduler_->CompleteOperationAndRunNext();
+}
+
+void ServiceWorkerCacheStorage::OpenCacheImpl(
+ const std::string& cache_name,
+ const CacheAndErrorCallback& callback) {
+ scoped_refptr<ServiceWorkerCache> cache = GetLoadedCache(cache_name);
+ if (cache.get()) {
+ callback.Run(cache, CACHE_STORAGE_ERROR_NO_ERROR);
+ return;
}
- init_callbacks_.clear();
+
+ cache_loader_->CreateCache(
+ cache_name,
+ base::Bind(&ServiceWorkerCacheStorage::CreateCacheDidCreateCache,
+ weak_factory_.GetWeakPtr(), cache_name, callback));
}
void ServiceWorkerCacheStorage::CreateCacheDidCreateCache(
@@ -689,6 +634,45 @@ void ServiceWorkerCacheStorage::CreateCacheDidWriteIndex(
callback.Run(cache, CACHE_STORAGE_ERROR_NO_ERROR);
}
+void ServiceWorkerCacheStorage::HasCacheImpl(
+ const std::string& cache_name,
+ const BoolAndErrorCallback& callback) {
+ bool has_cache = cache_map_.find(cache_name) != cache_map_.end();
+
+ callback.Run(has_cache, CACHE_STORAGE_ERROR_NO_ERROR);
+}
+
+void ServiceWorkerCacheStorage::DeleteCacheImpl(
+ const std::string& cache_name,
+ const BoolAndErrorCallback& callback) {
+ CacheMap::iterator it = cache_map_.find(cache_name);
+ if (it == cache_map_.end()) {
+ callback.Run(false, CACHE_STORAGE_ERROR_NOT_FOUND);
+ return;
+ }
+
+ base::WeakPtr<ServiceWorkerCache> cache = it->second;
+ cache_map_.erase(it);
+
+ // Delete the name from ordered_cache_names_.
+ StringVector::iterator iter = std::find(
+ ordered_cache_names_.begin(), ordered_cache_names_.end(), cache_name);
+ DCHECK(iter != ordered_cache_names_.end());
+ ordered_cache_names_.erase(iter);
+
+ base::Closure closure =
+ base::Bind(&ServiceWorkerCacheStorage::DeleteCacheDidClose,
+ weak_factory_.GetWeakPtr(), cache_name, callback,
+ ordered_cache_names_, make_scoped_refptr(cache.get()));
+
+ if (cache) {
+ cache->Close(closure);
+ return;
+ }
+
+ closure.Run();
+}
+
void ServiceWorkerCacheStorage::DeleteCacheDidClose(
const std::string& cache_name,
const BoolAndErrorCallback& callback,
@@ -721,6 +705,31 @@ void ServiceWorkerCacheStorage::DeleteCacheDidCleanUp(
callback.Run(true, CACHE_STORAGE_ERROR_NO_ERROR);
}
+void ServiceWorkerCacheStorage::EnumerateCachesImpl(
+ const StringsAndErrorCallback& callback) {
+ callback.Run(ordered_cache_names_, CACHE_STORAGE_ERROR_NO_ERROR);
+}
+
+void ServiceWorkerCacheStorage::MatchCacheImpl(
+ const std::string& cache_name,
+ scoped_ptr<ServiceWorkerFetchRequest> request,
+ const ServiceWorkerCache::ResponseCallback& callback) {
+ scoped_refptr<ServiceWorkerCache> cache = GetLoadedCache(cache_name);
+
+ if (!cache.get()) {
+ callback.Run(ServiceWorkerCache::ErrorTypeNotFound,
+ scoped_ptr<ServiceWorkerResponse>(),
+ scoped_ptr<storage::BlobDataHandle>());
+ return;
+ }
+
+ // Pass the cache along to the callback to keep the cache open until match is
+ // done.
+ cache->Match(request.Pass(),
+ base::Bind(&ServiceWorkerCacheStorage::MatchCacheDidMatch,
+ weak_factory_.GetWeakPtr(), cache, callback));
+}
+
void ServiceWorkerCacheStorage::MatchCacheDidMatch(
const scoped_refptr<ServiceWorkerCache>& cache,
const ServiceWorkerCache::ResponseCallback& callback,
@@ -730,6 +739,30 @@ void ServiceWorkerCacheStorage::MatchCacheDidMatch(
callback.Run(error, response.Pass(), handle.Pass());
}
+void ServiceWorkerCacheStorage::MatchAllCachesImpl(
+ scoped_ptr<ServiceWorkerFetchRequest> request,
+ const ServiceWorkerCache::ResponseCallback& callback) {
+ scoped_ptr<ServiceWorkerCache::ResponseCallback> callback_copy(
+ new ServiceWorkerCache::ResponseCallback(callback));
+
+ ServiceWorkerCache::ResponseCallback* callback_ptr = callback_copy.get();
+ base::Closure barrier_closure = base::BarrierClosure(
+ ordered_cache_names_.size(),
+ base::Bind(&ServiceWorkerCacheStorage::MatchAllCachesDidMatchAll,
+ weak_factory_.GetWeakPtr(),
+ base::Passed(callback_copy.Pass())));
+
+ for (const std::string& cache_name : ordered_cache_names_) {
+ scoped_refptr<ServiceWorkerCache> cache = GetLoadedCache(cache_name);
+ DCHECK(cache.get());
+
+ cache->Match(make_scoped_ptr(new ServiceWorkerFetchRequest(*request)),
+ base::Bind(&ServiceWorkerCacheStorage::MatchAllCachesDidMatch,
+ weak_factory_.GetWeakPtr(), cache, barrier_closure,
+ callback_ptr));
+ }
+}
+
void ServiceWorkerCacheStorage::MatchAllCachesDidMatch(
scoped_refptr<ServiceWorkerCache> cache,
const base::Closure& barrier_closure,
@@ -777,4 +810,91 @@ scoped_refptr<ServiceWorkerCache> ServiceWorkerCacheStorage::GetLoadedCache(
return make_scoped_refptr(cache.get());
}
+void ServiceWorkerCacheStorage::CloseAllCachesImpl(
+ const base::Closure& callback) {
+ int live_cache_count = 0;
+ for (const auto& key_value : cache_map_) {
+ if (key_value.second)
+ live_cache_count += 1;
+ }
+
+ if (live_cache_count == 0) {
+ callback.Run();
+ return;
+ }
+
+ // The closure might modify this object so delay calling it until after
+ // iterating through cache_map_ by adding one to the barrier.
+ base::Closure barrier_closure =
+ base::BarrierClosure(live_cache_count + 1, base::Bind(callback));
+
+ for (auto& key_value : cache_map_) {
+ if (key_value.second) {
+ key_value.second->Close(base::Bind(
+ CloseAllCachesDidCloseCache,
+ make_scoped_refptr(key_value.second.get()), barrier_closure));
+ }
+ }
+
+ barrier_closure.Run();
+}
+
+void ServiceWorkerCacheStorage::PendingClosure(const base::Closure& callback) {
+ base::WeakPtr<ServiceWorkerCacheStorage> cache_storage =
+ weak_factory_.GetWeakPtr();
+
+ callback.Run();
+ if (cache_storage)
+ scheduler_->CompleteOperationAndRunNext();
+}
+
+void ServiceWorkerCacheStorage::PendingBoolAndErrorCallback(
+ const BoolAndErrorCallback& callback,
+ bool found,
+ CacheStorageError error) {
+ base::WeakPtr<ServiceWorkerCacheStorage> cache_storage =
+ weak_factory_.GetWeakPtr();
+
+ callback.Run(found, error);
+ if (cache_storage)
+ scheduler_->CompleteOperationAndRunNext();
+}
+
+void ServiceWorkerCacheStorage::PendingCacheAndErrorCallback(
+ const CacheAndErrorCallback& callback,
+ const scoped_refptr<ServiceWorkerCache>& cache,
+ CacheStorageError error) {
+ base::WeakPtr<ServiceWorkerCacheStorage> cache_storage =
+ weak_factory_.GetWeakPtr();
+
+ callback.Run(cache, error);
+ if (cache_storage)
+ scheduler_->CompleteOperationAndRunNext();
+}
+
+void ServiceWorkerCacheStorage::PendingStringsAndErrorCallback(
+ const StringsAndErrorCallback& callback,
+ const StringVector& strings,
+ CacheStorageError error) {
+ base::WeakPtr<ServiceWorkerCacheStorage> cache_storage =
+ weak_factory_.GetWeakPtr();
+
+ callback.Run(strings, error);
+ if (cache_storage)
+ scheduler_->CompleteOperationAndRunNext();
+}
+
+void ServiceWorkerCacheStorage::PendingResponseCallback(
+ const ServiceWorkerCache::ResponseCallback& callback,
+ ServiceWorkerCache::ErrorType error,
+ scoped_ptr<ServiceWorkerResponse> response,
+ scoped_ptr<storage::BlobDataHandle> blob_data_handle) {
+ base::WeakPtr<ServiceWorkerCacheStorage> cache_storage =
+ weak_factory_.GetWeakPtr();
+
+ callback.Run(error, response.Pass(), blob_data_handle.Pass());
+ if (cache_storage)
+ scheduler_->CompleteOperationAndRunNext();
+}
+
} // namespace content

Powered by Google App Engine
This is Rietveld 408576698