| Index: content/browser/service_worker/service_worker_cache.cc
|
| diff --git a/content/browser/service_worker/service_worker_cache.cc b/content/browser/service_worker/service_worker_cache.cc
|
| index dd9184036aa47fc20f35d2da1fd76a40539ceb73..2911b406d1bc0f4109f668ec0c77685ae94f94c1 100644
|
| --- a/content/browser/service_worker/service_worker_cache.cc
|
| +++ b/content/browser/service_worker/service_worker_cache.cc
|
| @@ -650,51 +650,9 @@ base::WeakPtr<ServiceWorkerCache> ServiceWorkerCache::AsWeakPtr() {
|
| return weak_ptr_factory_.GetWeakPtr();
|
| }
|
|
|
| -void ServiceWorkerCache::CreateBackend(const ErrorCallback& callback) {
|
| - DCHECK(!backend_);
|
| -
|
| - // Use APP_CACHE as opposed to DISK_CACHE to prevent cache eviction.
|
| - net::CacheType cache_type =
|
| - path_.empty() ? net::MEMORY_CACHE : net::APP_CACHE;
|
| -
|
| - scoped_ptr<ScopedBackendPtr> backend_ptr(new ScopedBackendPtr());
|
| -
|
| - // Temporary pointer so that backend_ptr can be Pass()'d in Bind below.
|
| - ScopedBackendPtr* backend = backend_ptr.get();
|
| -
|
| - net::CompletionCallback create_cache_callback =
|
| - base::Bind(CreateBackendDidCreate,
|
| - callback,
|
| - base::Passed(backend_ptr.Pass()),
|
| - weak_ptr_factory_.GetWeakPtr());
|
| -
|
| - // TODO(jkarlin): Use the cache MessageLoopProxy that ServiceWorkerCacheCore
|
| - // has for disk caches.
|
| - // TODO(jkarlin): Switch to SimpleCache after it supports APP_CACHE and after
|
| - // debugging why the QuickStressBody unittest fails with it.
|
| - int rv = disk_cache::CreateCacheBackend(
|
| - cache_type,
|
| - net::CACHE_BACKEND_SIMPLE,
|
| - path_,
|
| - kMaxCacheBytes,
|
| - false, /* force */
|
| - BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE).get(),
|
| - NULL,
|
| - backend,
|
| - create_cache_callback);
|
| - if (rv != net::ERR_IO_PENDING)
|
| - create_cache_callback.Run(rv);
|
| -}
|
| -
|
| void ServiceWorkerCache::Put(scoped_ptr<ServiceWorkerFetchRequest> request,
|
| scoped_ptr<ServiceWorkerResponse> response,
|
| const ErrorCallback& callback) {
|
| - DCHECK(backend_);
|
| -
|
| - scoped_ptr<disk_cache::Entry*> entry(new disk_cache::Entry*);
|
| -
|
| - disk_cache::Entry** entry_ptr = entry.get();
|
| -
|
| scoped_ptr<storage::BlobDataHandle> blob_data_handle;
|
|
|
| if (!response->blob_uuid.empty()) {
|
| @@ -710,27 +668,36 @@ void ServiceWorkerCache::Put(scoped_ptr<ServiceWorkerFetchRequest> request,
|
| }
|
| }
|
|
|
| - ServiceWorkerFetchRequest* request_ptr = request.get();
|
| -
|
| - net::CompletionCallback create_entry_callback =
|
| - base::Bind(PutDidCreateEntry,
|
| - base::Passed(request.Pass()),
|
| - base::Passed(response.Pass()),
|
| - callback,
|
| - base::Passed(entry.Pass()),
|
| - base::Passed(blob_data_handle.Pass()),
|
| - request_context_);
|
| + base::Closure continuation = base::Bind(&ServiceWorkerCache::PutImpl,
|
| + weak_ptr_factory_.GetWeakPtr(),
|
| + base::Passed(request.Pass()),
|
| + base::Passed(response.Pass()),
|
| + base::Passed(blob_data_handle.Pass()),
|
| + callback);
|
|
|
| - int rv = backend_->CreateEntry(
|
| - request_ptr->url.spec(), entry_ptr, create_entry_callback);
|
| + if (!initialized_) {
|
| + Init(continuation);
|
| + return;
|
| + }
|
|
|
| - if (rv != net::ERR_IO_PENDING)
|
| - create_entry_callback.Run(rv);
|
| + continuation.Run();
|
| }
|
|
|
| void ServiceWorkerCache::Match(scoped_ptr<ServiceWorkerFetchRequest> request,
|
| const ResponseCallback& callback) {
|
| - DCHECK(backend_);
|
| + if (!initialized_) {
|
| + Init(base::Bind(&ServiceWorkerCache::Match,
|
| + weak_ptr_factory_.GetWeakPtr(),
|
| + base::Passed(request.Pass()),
|
| + callback));
|
| + return;
|
| + }
|
| + if (!backend_) {
|
| + callback.Run(ErrorTypeStorage,
|
| + scoped_ptr<ServiceWorkerResponse>(),
|
| + scoped_ptr<storage::BlobDataHandle>());
|
| + return;
|
| + }
|
|
|
| scoped_ptr<disk_cache::Entry*> entry(new disk_cache::Entry*);
|
|
|
| @@ -753,7 +720,17 @@ void ServiceWorkerCache::Match(scoped_ptr<ServiceWorkerFetchRequest> request,
|
|
|
| void ServiceWorkerCache::Delete(scoped_ptr<ServiceWorkerFetchRequest> request,
|
| const ErrorCallback& callback) {
|
| - DCHECK(backend_);
|
| + if (!initialized_) {
|
| + Init(base::Bind(&ServiceWorkerCache::Delete,
|
| + weak_ptr_factory_.GetWeakPtr(),
|
| + base::Passed(request.Pass()),
|
| + callback));
|
| + return;
|
| + }
|
| + if (!backend_) {
|
| + callback.Run(ErrorTypeStorage);
|
| + return;
|
| + }
|
|
|
| scoped_ptr<disk_cache::Entry*> entry(new disk_cache::Entry*);
|
|
|
| @@ -774,7 +751,15 @@ void ServiceWorkerCache::Delete(scoped_ptr<ServiceWorkerFetchRequest> request,
|
| }
|
|
|
| void ServiceWorkerCache::Keys(const RequestsCallback& callback) {
|
| - DCHECK(backend_);
|
| + if (!initialized_) {
|
| + Init(base::Bind(
|
| + &ServiceWorkerCache::Keys, weak_ptr_factory_.GetWeakPtr(), callback));
|
| + return;
|
| + }
|
| + if (!backend_) {
|
| + callback.Run(ErrorTypeStorage, scoped_ptr<Requests>());
|
| + return;
|
| + }
|
|
|
| // 1. Iterate through all of the entries, open them, and add them to a vector.
|
| // 2. For each open entry:
|
| @@ -802,10 +787,6 @@ void ServiceWorkerCache::Keys(const RequestsCallback& callback) {
|
| open_entry_callback.Run(rv);
|
| }
|
|
|
| -bool ServiceWorkerCache::HasCreatedBackend() const {
|
| - return backend_;
|
| -}
|
| -
|
| ServiceWorkerCache::ServiceWorkerCache(
|
| const base::FilePath& path,
|
| net::URLRequestContext* request_context,
|
| @@ -813,9 +794,42 @@ ServiceWorkerCache::ServiceWorkerCache(
|
| : path_(path),
|
| request_context_(request_context),
|
| blob_storage_context_(blob_context),
|
| + initialized_(false),
|
| weak_ptr_factory_(this) {
|
| }
|
|
|
| +void ServiceWorkerCache::PutImpl(
|
| + scoped_ptr<ServiceWorkerFetchRequest> request,
|
| + scoped_ptr<ServiceWorkerResponse> response,
|
| + scoped_ptr<storage::BlobDataHandle> blob_data_handle,
|
| + const ErrorCallback& callback) {
|
| + if (!backend_) {
|
| + callback.Run(ErrorTypeStorage);
|
| + return;
|
| + }
|
| +
|
| + scoped_ptr<disk_cache::Entry*> entry(new disk_cache::Entry*);
|
| +
|
| + disk_cache::Entry** entry_ptr = entry.get();
|
| +
|
| + ServiceWorkerFetchRequest* request_ptr = request.get();
|
| +
|
| + net::CompletionCallback create_entry_callback =
|
| + base::Bind(PutDidCreateEntry,
|
| + base::Passed(request.Pass()),
|
| + base::Passed(response.Pass()),
|
| + callback,
|
| + base::Passed(entry.Pass()),
|
| + base::Passed(blob_data_handle.Pass()),
|
| + request_context_);
|
| +
|
| + int rv = backend_->CreateEntry(
|
| + request_ptr->url.spec(), entry_ptr, create_entry_callback);
|
| +
|
| + if (rv != net::ERR_IO_PENDING)
|
| + create_entry_callback.Run(rv);
|
| +}
|
| +
|
| // static
|
| void ServiceWorkerCache::KeysDidOpenNextEntry(
|
| scoped_ptr<KeysContext> keys_context,
|
| @@ -899,4 +913,60 @@ void ServiceWorkerCache::KeysDidReadHeaders(
|
| KeysProcessNextEntry(keys_context.Pass(), iter + 1);
|
| }
|
|
|
| +void ServiceWorkerCache::CreateBackend(const ErrorCallback& callback) {
|
| + DCHECK(!backend_);
|
| +
|
| + // Use APP_CACHE as opposed to DISK_CACHE to prevent cache eviction.
|
| + net::CacheType cache_type =
|
| + path_.empty() ? net::MEMORY_CACHE : net::APP_CACHE;
|
| +
|
| + scoped_ptr<ScopedBackendPtr> backend_ptr(new ScopedBackendPtr());
|
| +
|
| + // Temporary pointer so that backend_ptr can be Pass()'d in Bind below.
|
| + ScopedBackendPtr* backend = backend_ptr.get();
|
| +
|
| + net::CompletionCallback create_cache_callback =
|
| + base::Bind(CreateBackendDidCreate,
|
| + callback,
|
| + base::Passed(backend_ptr.Pass()),
|
| + weak_ptr_factory_.GetWeakPtr());
|
| +
|
| + // TODO(jkarlin): Use the cache MessageLoopProxy that ServiceWorkerCacheCore
|
| + // has for disk caches.
|
| + int rv = disk_cache::CreateCacheBackend(
|
| + cache_type,
|
| + net::CACHE_BACKEND_SIMPLE,
|
| + path_,
|
| + kMaxCacheBytes,
|
| + false, /* force */
|
| + BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE).get(),
|
| + NULL,
|
| + backend,
|
| + create_cache_callback);
|
| + if (rv != net::ERR_IO_PENDING)
|
| + create_cache_callback.Run(rv);
|
| +}
|
| +
|
| +void ServiceWorkerCache::Init(const base::Closure& callback) {
|
| + init_callbacks_.push_back(callback);
|
| +
|
| + // If this isn't the first call to Init then return as the initialization
|
| + // has already started.
|
| + if (init_callbacks_.size() > 1u)
|
| + return;
|
| +
|
| + CreateBackend(base::Bind(&ServiceWorkerCache::InitDone,
|
| + weak_ptr_factory_.GetWeakPtr()));
|
| +}
|
| +
|
| +void ServiceWorkerCache::InitDone(ErrorType error) {
|
| + initialized_ = true;
|
| + for (std::vector<base::Closure>::iterator it = init_callbacks_.begin();
|
| + it != init_callbacks_.end();
|
| + ++it) {
|
| + it->Run();
|
| + }
|
| + init_callbacks_.clear();
|
| +}
|
| +
|
| } // namespace content
|
|
|