Commit 69909ccc authored by jkarlin's avatar jkarlin Committed by Commit bot

Expose ServiceWorkerCache objects to ServiceWorkerCacheStorageManager clients.

The CL provides reference counted ServiceWorkerCaches on ServiceWorkerCacheStorage::Get and Create.  Previously only CacheIDs were provided from those functions and there was no way for the client to access the ServiceWorkerCache itself.

This CL makes the following modifications:

1. Make ServiceWorkerCache refcounted
2. Return ServiceWorkerCache* instead of a CacheID from Create() and Put()
3. Removed CacheID from ServiceWorkerCache
4. Removed CacheContext from ServiceWorkerCache (since it really only existed to hold a CacheID)
5. Now keeps track of CacheIDs in ServiceWorkerCacheListener
6. Added memory unit tests

Related CLs:
1. https://crrev.com/542703002: Change ownership of the parameters to ServiceWorkerCache:: Put and Match.
2. https://crrev.com/545533002: Move ServiceWorkerCache backend creation to a lazy init function.
3. https://crrev.com/548533002: Make ServiceWorkerCacheStorage::CacheLoader::LoadCache synchronous
* 4. https://crrev.com/549493002: Expose ServiceWorkerCache objects to ServiceWorkerCacheStorageManager clients.

BUG=392621

Review URL: https://codereview.chromium.org/549493002

Cr-Commit-Position: refs/heads/master@{#294392}
parent 8abccfde
...@@ -605,7 +605,7 @@ struct ServiceWorkerCache::KeysContext { ...@@ -605,7 +605,7 @@ struct ServiceWorkerCache::KeysContext {
entries[i]->Close(); entries[i]->Close();
if (enumerated_entry) if (enumerated_entry)
enumerated_entry->Close(); enumerated_entry->Close();
if (cache && backend_iterator) if (cache && backend_iterator && cache->backend_)
cache->backend_->EndEnumeration(&backend_iterator); cache->backend_->EndEnumeration(&backend_iterator);
} }
...@@ -627,19 +627,19 @@ struct ServiceWorkerCache::KeysContext { ...@@ -627,19 +627,19 @@ struct ServiceWorkerCache::KeysContext {
}; };
// static // static
scoped_ptr<ServiceWorkerCache> ServiceWorkerCache::CreateMemoryCache( scoped_refptr<ServiceWorkerCache> ServiceWorkerCache::CreateMemoryCache(
net::URLRequestContext* request_context, net::URLRequestContext* request_context,
base::WeakPtr<storage::BlobStorageContext> blob_context) { base::WeakPtr<storage::BlobStorageContext> blob_context) {
return make_scoped_ptr( return make_scoped_refptr(
new ServiceWorkerCache(base::FilePath(), request_context, blob_context)); new ServiceWorkerCache(base::FilePath(), request_context, blob_context));
} }
// static // static
scoped_ptr<ServiceWorkerCache> ServiceWorkerCache::CreatePersistentCache( scoped_refptr<ServiceWorkerCache> ServiceWorkerCache::CreatePersistentCache(
const base::FilePath& path, const base::FilePath& path,
net::URLRequestContext* request_context, net::URLRequestContext* request_context,
base::WeakPtr<storage::BlobStorageContext> blob_context) { base::WeakPtr<storage::BlobStorageContext> blob_context) {
return make_scoped_ptr( return make_scoped_refptr(
new ServiceWorkerCache(path, request_context, blob_context)); new ServiceWorkerCache(path, request_context, blob_context));
} }
...@@ -787,6 +787,10 @@ void ServiceWorkerCache::Keys(const RequestsCallback& callback) { ...@@ -787,6 +787,10 @@ void ServiceWorkerCache::Keys(const RequestsCallback& callback) {
open_entry_callback.Run(rv); open_entry_callback.Run(rv);
} }
void ServiceWorkerCache::Close() {
backend_.reset();
}
ServiceWorkerCache::ServiceWorkerCache( ServiceWorkerCache::ServiceWorkerCache(
const base::FilePath& path, const base::FilePath& path,
net::URLRequestContext* request_context, net::URLRequestContext* request_context,
...@@ -849,6 +853,12 @@ void ServiceWorkerCache::KeysDidOpenNextEntry( ...@@ -849,6 +853,12 @@ void ServiceWorkerCache::KeysDidOpenNextEntry(
return; return;
} }
if (!cache->backend_) {
keys_context->original_callback.Run(ErrorTypeNotFound,
scoped_ptr<Requests>());
return;
}
// Store the entry. // Store the entry.
keys_context->entries.push_back(keys_context->enumerated_entry); keys_context->entries.push_back(keys_context->enumerated_entry);
keys_context->enumerated_entry = NULL; keys_context->enumerated_entry = NULL;
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "base/callback.h" #include "base/callback.h"
#include "base/files/file_path.h" #include "base/files/file_path.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "content/common/service_worker/service_worker_types.h" #include "content/common/service_worker/service_worker_types.h"
#include "net/base/completion_callback.h" #include "net/base/completion_callback.h"
...@@ -33,7 +34,8 @@ class ServiceWorkerRequestResponseHeaders; ...@@ -33,7 +34,8 @@ class ServiceWorkerRequestResponseHeaders;
// Represents a ServiceWorker Cache as seen in // Represents a ServiceWorker Cache as seen in
// https://slightlyoff.github.io/ServiceWorker/spec/service_worker/index.html. // https://slightlyoff.github.io/ServiceWorker/spec/service_worker/index.html.
// InitializeIfNeeded must be called before calling the other public members. // InitializeIfNeeded must be called before calling the other public members.
class CONTENT_EXPORT ServiceWorkerCache { class CONTENT_EXPORT ServiceWorkerCache
: public base::RefCounted<ServiceWorkerCache> {
public: public:
enum ErrorType { enum ErrorType {
ErrorTypeOK = 0, ErrorTypeOK = 0,
...@@ -51,34 +53,27 @@ class CONTENT_EXPORT ServiceWorkerCache { ...@@ -51,34 +53,27 @@ class CONTENT_EXPORT ServiceWorkerCache {
typedef base::Callback<void(ErrorType, scoped_ptr<Requests>)> typedef base::Callback<void(ErrorType, scoped_ptr<Requests>)>
RequestsCallback; RequestsCallback;
static scoped_ptr<ServiceWorkerCache> CreateMemoryCache( static scoped_refptr<ServiceWorkerCache> CreateMemoryCache(
net::URLRequestContext* request_context, net::URLRequestContext* request_context,
base::WeakPtr<storage::BlobStorageContext> blob_context); base::WeakPtr<storage::BlobStorageContext> blob_context);
static scoped_ptr<ServiceWorkerCache> CreatePersistentCache( static scoped_refptr<ServiceWorkerCache> CreatePersistentCache(
const base::FilePath& path, const base::FilePath& path,
net::URLRequestContext* request_context, net::URLRequestContext* request_context,
base::WeakPtr<storage::BlobStorageContext> blob_context); base::WeakPtr<storage::BlobStorageContext> blob_context);
// Operations in progress will complete after the cache is deleted but pending
// operations (those operations waiting for init to finish) won't.
virtual ~ServiceWorkerCache();
// Returns ErrorTypeNotFound if not found. The callback will always be called. // Returns ErrorTypeNotFound if not found. The callback will always be called.
// |request| must remain valid until the callback is called.
void Match(scoped_ptr<ServiceWorkerFetchRequest> request, void Match(scoped_ptr<ServiceWorkerFetchRequest> request,
const ResponseCallback& callback); const ResponseCallback& callback);
// Puts the request and response object in the cache. The response body (if // Puts the request and response object in the cache. The response body (if
// present) is stored in the cache, but not the request body. Returns // present) is stored in the cache, but not the request body. Returns
// ErrorTypeOK on success. The callback will always be called. |request| and // ErrorTypeOK on success. The callback will always be called.
// |response| must remain valid until the callback is called.
void Put(scoped_ptr<ServiceWorkerFetchRequest> request, void Put(scoped_ptr<ServiceWorkerFetchRequest> request,
scoped_ptr<ServiceWorkerResponse> response, scoped_ptr<ServiceWorkerResponse> response,
const ErrorCallback& callback); const ErrorCallback& callback);
// Returns ErrorNotFound if not found. Otherwise deletes and returns // Returns ErrorNotFound if not found. Otherwise deletes and returns
// ErrorTypeOK. The callback will always be called. |request| must remain // ErrorTypeOK. The callback will always be called.
// valid until the callback is called.
void Delete(scoped_ptr<ServiceWorkerFetchRequest> request, void Delete(scoped_ptr<ServiceWorkerFetchRequest> request,
const ErrorCallback& callback); const ErrorCallback& callback);
...@@ -87,6 +82,9 @@ class CONTENT_EXPORT ServiceWorkerCache { ...@@ -87,6 +82,9 @@ class CONTENT_EXPORT ServiceWorkerCache {
// callback will always be called. // callback will always be called.
void Keys(const RequestsCallback& callback); void Keys(const RequestsCallback& callback);
// Prevent further operations on this object and delete the backend.
void Close();
void set_backend(scoped_ptr<disk_cache::Backend> backend) { void set_backend(scoped_ptr<disk_cache::Backend> backend) {
backend_ = backend.Pass(); backend_ = backend.Pass();
} }
...@@ -94,6 +92,8 @@ class CONTENT_EXPORT ServiceWorkerCache { ...@@ -94,6 +92,8 @@ class CONTENT_EXPORT ServiceWorkerCache {
base::WeakPtr<ServiceWorkerCache> AsWeakPtr(); base::WeakPtr<ServiceWorkerCache> AsWeakPtr();
private: private:
friend class base::RefCounted<ServiceWorkerCache>;
struct KeysContext; struct KeysContext;
typedef std::vector<disk_cache::Entry*> Entries; typedef std::vector<disk_cache::Entry*> Entries;
...@@ -101,6 +101,10 @@ class CONTENT_EXPORT ServiceWorkerCache { ...@@ -101,6 +101,10 @@ class CONTENT_EXPORT ServiceWorkerCache {
net::URLRequestContext* request_context, net::URLRequestContext* request_context,
base::WeakPtr<storage::BlobStorageContext> blob_context); base::WeakPtr<storage::BlobStorageContext> blob_context);
// Operations in progress will complete after the cache is deleted but pending
// operations (those operations waiting for init to finish) won't.
virtual ~ServiceWorkerCache();
void PutImpl(scoped_ptr<ServiceWorkerFetchRequest> request, void PutImpl(scoped_ptr<ServiceWorkerFetchRequest> request,
scoped_ptr<ServiceWorkerResponse> response, scoped_ptr<ServiceWorkerResponse> response,
scoped_ptr<storage::BlobDataHandle> blob_data_handle, scoped_ptr<storage::BlobDataHandle> blob_data_handle,
...@@ -123,6 +127,8 @@ class CONTENT_EXPORT ServiceWorkerCache { ...@@ -123,6 +127,8 @@ class CONTENT_EXPORT ServiceWorkerCache {
void Init(const base::Closure& callback); void Init(const base::Closure& callback);
void InitDone(ErrorType error); void InitDone(ErrorType error);
// The backend can be deleted via the Close function at any time so always
// check for its existence before use.
scoped_ptr<disk_cache::Backend> backend_; scoped_ptr<disk_cache::Backend> backend_;
base::FilePath path_; base::FilePath path_;
net::URLRequestContext* request_context_; net::URLRequestContext* request_context_;
......
...@@ -49,7 +49,10 @@ WebServiceWorkerCacheError ToWebServiceWorkerCacheError( ...@@ -49,7 +49,10 @@ WebServiceWorkerCacheError ToWebServiceWorkerCacheError(
ServiceWorkerCacheListener::ServiceWorkerCacheListener( ServiceWorkerCacheListener::ServiceWorkerCacheListener(
ServiceWorkerVersion* version, ServiceWorkerVersion* version,
base::WeakPtr<ServiceWorkerContextCore> context) base::WeakPtr<ServiceWorkerContextCore> context)
: version_(version), context_(context), weak_factory_(this) { : version_(version),
context_(context),
next_cache_id_(0),
weak_factory_(this) {
} }
ServiceWorkerCacheListener::~ServiceWorkerCacheListener() { ServiceWorkerCacheListener::~ServiceWorkerCacheListener() {
...@@ -143,13 +146,15 @@ void ServiceWorkerCacheListener::Send(const IPC::Message& message) { ...@@ -143,13 +146,15 @@ void ServiceWorkerCacheListener::Send(const IPC::Message& message) {
void ServiceWorkerCacheListener::OnCacheStorageGetCallback( void ServiceWorkerCacheListener::OnCacheStorageGetCallback(
int request_id, int request_id,
int cache_id, const scoped_refptr<ServiceWorkerCache>& cache,
ServiceWorkerCacheStorage::CacheStorageError error) { ServiceWorkerCacheStorage::CacheStorageError error) {
if (error != ServiceWorkerCacheStorage::CACHE_STORAGE_ERROR_NO_ERROR) { if (error != ServiceWorkerCacheStorage::CACHE_STORAGE_ERROR_NO_ERROR) {
Send(ServiceWorkerMsg_CacheStorageGetError( Send(ServiceWorkerMsg_CacheStorageGetError(
request_id, ToWebServiceWorkerCacheError(error))); request_id, ToWebServiceWorkerCacheError(error)));
return; return;
} }
CacheID cache_id = StoreCacheReference(cache);
Send(ServiceWorkerMsg_CacheStorageGetSuccess(request_id, cache_id)); Send(ServiceWorkerMsg_CacheStorageGetSuccess(request_id, cache_id));
} }
...@@ -173,13 +178,14 @@ void ServiceWorkerCacheListener::OnCacheStorageHasCallback( ...@@ -173,13 +178,14 @@ void ServiceWorkerCacheListener::OnCacheStorageHasCallback(
void ServiceWorkerCacheListener::OnCacheStorageCreateCallback( void ServiceWorkerCacheListener::OnCacheStorageCreateCallback(
int request_id, int request_id,
int cache_id, const scoped_refptr<ServiceWorkerCache>& cache,
ServiceWorkerCacheStorage::CacheStorageError error) { ServiceWorkerCacheStorage::CacheStorageError error) {
if (error != ServiceWorkerCacheStorage::CACHE_STORAGE_ERROR_NO_ERROR) { if (error != ServiceWorkerCacheStorage::CACHE_STORAGE_ERROR_NO_ERROR) {
Send(ServiceWorkerMsg_CacheStorageCreateError( Send(ServiceWorkerMsg_CacheStorageCreateError(
request_id, ToWebServiceWorkerCacheError(error))); request_id, ToWebServiceWorkerCacheError(error)));
return; return;
} }
CacheID cache_id = StoreCacheReference(cache);
Send(ServiceWorkerMsg_CacheStorageCreateSuccess(request_id, cache_id)); Send(ServiceWorkerMsg_CacheStorageCreateSuccess(request_id, cache_id));
} }
...@@ -213,4 +219,28 @@ void ServiceWorkerCacheListener::OnCacheStorageKeysCallback( ...@@ -213,4 +219,28 @@ void ServiceWorkerCacheListener::OnCacheStorageKeysCallback(
Send(ServiceWorkerMsg_CacheStorageKeysSuccess(request_id, string16s)); Send(ServiceWorkerMsg_CacheStorageKeysSuccess(request_id, string16s));
} }
ServiceWorkerCacheListener::CacheID
ServiceWorkerCacheListener::StoreCacheReference(
const scoped_refptr<ServiceWorkerCache>& cache) {
CacheToIDMap::iterator it = cache_to_id_map_.find(cache.get());
if (it == cache_to_id_map_.end()) {
CacheID cache_id = next_cache_id_++;
cache_to_id_map_.insert(std::make_pair(cache.get(), cache_id));
id_to_cache_map_.insert(std::make_pair(cache_id, cache));
return cache_id;
}
return it->second;
}
void ServiceWorkerCacheListener::DropCacheReference(CacheID cache_id) {
IDToCacheMap::iterator it = id_to_cache_map_.find(cache_id);
if (it != id_to_cache_map_.end())
return;
size_t deleted = cache_to_id_map_.erase(it->second.get());
DCHECK(deleted == 1u);
id_to_cache_map_.erase(it);
}
} // namespace content } // namespace content
...@@ -35,12 +35,19 @@ class ServiceWorkerCacheListener : public EmbeddedWorkerInstance::Listener { ...@@ -35,12 +35,19 @@ class ServiceWorkerCacheListener : public EmbeddedWorkerInstance::Listener {
const base::string16& cache_name); const base::string16& cache_name);
void OnCacheStorageKeys(int request_id); void OnCacheStorageKeys(int request_id);
// TODO(gavinp,jkarlin): Plumb a message up from the renderer saying that the
// renderer is done with a cache id.
private: private:
typedef int32_t CacheID; // TODO(jkarlin): Bump to 64 bit.
typedef std::map<ServiceWorkerCache*, CacheID> CacheToIDMap;
typedef std::map<CacheID, scoped_refptr<ServiceWorkerCache> > IDToCacheMap;
void Send(const IPC::Message& message); void Send(const IPC::Message& message);
void OnCacheStorageGetCallback( void OnCacheStorageGetCallback(
int request_id, int request_id,
int cache_id, const scoped_refptr<ServiceWorkerCache>& cache,
ServiceWorkerCacheStorage::CacheStorageError error); ServiceWorkerCacheStorage::CacheStorageError error);
void OnCacheStorageHasCallback( void OnCacheStorageHasCallback(
int request_id, int request_id,
...@@ -48,7 +55,7 @@ class ServiceWorkerCacheListener : public EmbeddedWorkerInstance::Listener { ...@@ -48,7 +55,7 @@ class ServiceWorkerCacheListener : public EmbeddedWorkerInstance::Listener {
ServiceWorkerCacheStorage::CacheStorageError error); ServiceWorkerCacheStorage::CacheStorageError error);
void OnCacheStorageCreateCallback( void OnCacheStorageCreateCallback(
int request_id, int request_id,
int cache_id, const scoped_refptr<ServiceWorkerCache>& cache,
ServiceWorkerCacheStorage::CacheStorageError error); ServiceWorkerCacheStorage::CacheStorageError error);
void OnCacheStorageDeleteCallback( void OnCacheStorageDeleteCallback(
int request_id, int request_id,
...@@ -59,12 +66,22 @@ class ServiceWorkerCacheListener : public EmbeddedWorkerInstance::Listener { ...@@ -59,12 +66,22 @@ class ServiceWorkerCacheListener : public EmbeddedWorkerInstance::Listener {
const std::vector<std::string>& strings, const std::vector<std::string>& strings,
ServiceWorkerCacheStorage::CacheStorageError error); ServiceWorkerCacheStorage::CacheStorageError error);
// Hangs onto a scoped_refptr for the cache if it isn't already doing so.
// Returns a unique cache_id. Call DropCacheReference when the client is done
// with this cache.
CacheID StoreCacheReference(const scoped_refptr<ServiceWorkerCache>& cache);
void DropCacheReference(CacheID cache_id);
// The ServiceWorkerVersion to use for messaging back to the renderer thread. // The ServiceWorkerVersion to use for messaging back to the renderer thread.
ServiceWorkerVersion* version_; ServiceWorkerVersion* version_;
// The ServiceWorkerContextCore should always outlive this. // The ServiceWorkerContextCore should always outlive this.
base::WeakPtr<ServiceWorkerContextCore> context_; base::WeakPtr<ServiceWorkerContextCore> context_;
IDToCacheMap id_to_cache_map_;
CacheToIDMap cache_to_id_map_;
CacheID next_cache_id_;
base::WeakPtrFactory<ServiceWorkerCacheListener> weak_factory_; base::WeakPtrFactory<ServiceWorkerCacheListener> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(ServiceWorkerCacheListener); DISALLOW_COPY_AND_ASSIGN(ServiceWorkerCacheListener);
......
...@@ -34,13 +34,6 @@ namespace content { ...@@ -34,13 +34,6 @@ namespace content {
// on the IO thread. // on the IO thread.
class CONTENT_EXPORT ServiceWorkerCacheStorage { class CONTENT_EXPORT ServiceWorkerCacheStorage {
public: public:
// TODO(jkarlin): Convert this (and everything that uses it) to int64_t so
// that we don't run out of id space.
typedef int32_t CacheID;
// The CacheID returned on failed cache operations.
const static int kInvalidCacheID;
enum CacheStorageError { enum CacheStorageError {
CACHE_STORAGE_ERROR_NO_ERROR, CACHE_STORAGE_ERROR_NO_ERROR,
CACHE_STORAGE_ERROR_NOT_IMPLEMENTED, CACHE_STORAGE_ERROR_NOT_IMPLEMENTED,
...@@ -51,7 +44,8 @@ class CONTENT_EXPORT ServiceWorkerCacheStorage { ...@@ -51,7 +44,8 @@ class CONTENT_EXPORT ServiceWorkerCacheStorage {
}; };
typedef base::Callback<void(bool, CacheStorageError)> BoolAndErrorCallback; typedef base::Callback<void(bool, CacheStorageError)> BoolAndErrorCallback;
typedef base::Callback<void(int, CacheStorageError)> CacheAndErrorCallback; typedef base::Callback<void(const scoped_refptr<ServiceWorkerCache>&,
CacheStorageError)> CacheAndErrorCallback;
typedef base::Callback<void(const std::vector<std::string>&, typedef base::Callback<void(const std::vector<std::string>&,
CacheStorageError)> StringsAndErrorCallback; CacheStorageError)> StringsAndErrorCallback;
...@@ -93,12 +87,13 @@ class CONTENT_EXPORT ServiceWorkerCacheStorage { ...@@ -93,12 +87,13 @@ class CONTENT_EXPORT ServiceWorkerCacheStorage {
class MemoryLoader; class MemoryLoader;
class SimpleCacheLoader; class SimpleCacheLoader;
class CacheLoader; class CacheLoader;
struct CacheContext;
typedef std::map<CacheID, CacheContext*> CacheMap; typedef std::map<std::string, base::WeakPtr<ServiceWorkerCache> > CacheMap;
typedef std::map<std::string, CacheID> NameMap;
CacheContext* GetLoadedCache(const std::string& cache_name) const; // Return a ServiceWorkerCache for the given name if the name is known. If the
// ServiceWorkerCache has been deleted, creates a new one.
scoped_refptr<ServiceWorkerCache> GetLoadedCache(
const std::string& cache_name);
// Initializer and its callback are below. // Initializer and its callback are below.
void LazyInit(const base::Closure& closure); void LazyInit(const base::Closure& closure);
...@@ -106,16 +101,16 @@ class CONTENT_EXPORT ServiceWorkerCacheStorage { ...@@ -106,16 +101,16 @@ class CONTENT_EXPORT ServiceWorkerCacheStorage {
const base::Closure& callback, const base::Closure& callback,
scoped_ptr<std::vector<std::string> > indexed_cache_names); scoped_ptr<std::vector<std::string> > indexed_cache_names);
CacheContext* AddCacheToMaps(const std::string& cache_name, void AddCacheToMap(const std::string& cache_name,
scoped_ptr<ServiceWorkerCache> cache); base::WeakPtr<ServiceWorkerCache> cache);
// The CreateCache callbacks are below. // The CreateCache callbacks are below.
void CreateCacheDidCreateCache(const std::string& cache_name, void CreateCacheDidCreateCache(
const CacheAndErrorCallback& callback, const std::string& cache_name,
scoped_ptr<ServiceWorkerCache> cache); const CacheAndErrorCallback& callback,
const scoped_refptr<ServiceWorkerCache>& cache);
void CreateCacheDidWriteIndex(const CacheAndErrorCallback& callback, void CreateCacheDidWriteIndex(const CacheAndErrorCallback& callback,
base::WeakPtr<ServiceWorkerCache> cache, const scoped_refptr<ServiceWorkerCache>& cache,
CacheID id,
bool success); bool success);
// The DeleteCache callbacks are below. // The DeleteCache callbacks are below.
...@@ -131,14 +126,8 @@ class CONTENT_EXPORT ServiceWorkerCacheStorage { ...@@ -131,14 +126,8 @@ class CONTENT_EXPORT ServiceWorkerCacheStorage {
// The list of operations waiting on initialization. // The list of operations waiting on initialization.
std::vector<base::Closure> init_callbacks_; std::vector<base::Closure> init_callbacks_;
// The map of CacheIDs to their CacheContext objects. Owns the CacheContext // The map of cache names to ServiceWorkerCache objects.
// object. The CacheIDs are used by JavaScript to reference a
// ServiceWorkerCache.
CacheMap cache_map_; CacheMap cache_map_;
CacheID next_cache_id_; // The next CacheID to use in cache_map_
// The map of cache names to their integer ids.
NameMap name_map_;
// The file path for this CacheStorage. // The file path for this CacheStorage.
base::FilePath origin_path_; base::FilePath origin_path_;
...@@ -146,6 +135,9 @@ class CONTENT_EXPORT ServiceWorkerCacheStorage { ...@@ -146,6 +135,9 @@ class CONTENT_EXPORT ServiceWorkerCacheStorage {
// The TaskRunner to run file IO on. // The TaskRunner to run file IO on.
scoped_refptr<base::SequencedTaskRunner> cache_task_runner_; scoped_refptr<base::SequencedTaskRunner> cache_task_runner_;
// Whether or not to store data in disk or memory.
bool memory_only_;
// Performs backend specific operations (memory vs disk). // Performs backend specific operations (memory vs disk).
scoped_ptr<CacheLoader> cache_loader_; scoped_ptr<CacheLoader> cache_loader_;
......
...@@ -24,9 +24,9 @@ class ServiceWorkerCacheStorageManagerTest : public testing::Test { ...@@ -24,9 +24,9 @@ class ServiceWorkerCacheStorageManagerTest : public testing::Test {
ServiceWorkerCacheStorageManagerTest() ServiceWorkerCacheStorageManagerTest()
: browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP), : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP),
callback_bool_(false), callback_bool_(false),
callback_cache_id_(0),
callback_error_( callback_error_(
ServiceWorkerCacheStorage::CACHE_STORAGE_ERROR_NO_ERROR), ServiceWorkerCacheStorage::CACHE_STORAGE_ERROR_NO_ERROR),
callback_cache_error_(ServiceWorkerCache::ErrorTypeOK),
origin1_("http://example1.com"), origin1_("http://example1.com"),
origin2_("http://example2.com") {} origin2_("http://example2.com") {}
...@@ -74,9 +74,9 @@ class ServiceWorkerCacheStorageManagerTest : public testing::Test { ...@@ -74,9 +74,9 @@ class ServiceWorkerCacheStorageManagerTest : public testing::Test {
void CacheAndErrorCallback( void CacheAndErrorCallback(
base::RunLoop* run_loop, base::RunLoop* run_loop,
int cache_id, const scoped_refptr<ServiceWorkerCache>& cache,
ServiceWorkerCacheStorage::CacheStorageError error) { ServiceWorkerCacheStorage::CacheStorageError error) {
callback_cache_id_ = cache_id; callback_cache_ = cache;
callback_error_ = error; callback_error_ = error;
run_loop->Quit(); run_loop->Quit();
} }
...@@ -90,6 +90,23 @@ class ServiceWorkerCacheStorageManagerTest : public testing::Test { ...@@ -90,6 +90,23 @@ class ServiceWorkerCacheStorageManagerTest : public testing::Test {
run_loop->Quit(); run_loop->Quit();
} }
void CachePutCallback(base::RunLoop* run_loop,
ServiceWorkerCache::ErrorType error) {
callback_cache_error_ = error;
run_loop->Quit();
}
void CacheMatchCallback(
base::RunLoop* run_loop,
ServiceWorkerCache::ErrorType error,
scoped_ptr<ServiceWorkerResponse> response,
scoped_ptr<storage::BlobDataHandle> blob_data_handle) {
callback_cache_error_ = error;
callback_cache_response_ = response.Pass();
// Deliberately drop the data handle as only the url is being tested.
run_loop->Quit();
}
bool CreateCache(const GURL& origin, const std::string& cache_name) { bool CreateCache(const GURL& origin, const std::string& cache_name) {
scoped_ptr<base::RunLoop> loop(new base::RunLoop()); scoped_ptr<base::RunLoop> loop(new base::RunLoop());
cache_manager_->CreateCache( cache_manager_->CreateCache(
...@@ -103,9 +120,9 @@ class ServiceWorkerCacheStorageManagerTest : public testing::Test { ...@@ -103,9 +120,9 @@ class ServiceWorkerCacheStorageManagerTest : public testing::Test {
bool error = callback_error_ != bool error = callback_error_ !=
ServiceWorkerCacheStorage::CACHE_STORAGE_ERROR_NO_ERROR; ServiceWorkerCacheStorage::CACHE_STORAGE_ERROR_NO_ERROR;
if (error) if (error)
EXPECT_EQ(ServiceWorkerCacheStorage::kInvalidCacheID, callback_cache_id_); EXPECT_TRUE(!callback_cache_.get());
else else
EXPECT_LE(0, callback_cache_id_); EXPECT_TRUE(callback_cache_.get());
return !error; return !error;
} }
...@@ -122,9 +139,9 @@ class ServiceWorkerCacheStorageManagerTest : public testing::Test { ...@@ -122,9 +139,9 @@ class ServiceWorkerCacheStorageManagerTest : public testing::Test {
bool error = callback_error_ != bool error = callback_error_ !=
ServiceWorkerCacheStorage::CACHE_STORAGE_ERROR_NO_ERROR; ServiceWorkerCacheStorage::CACHE_STORAGE_ERROR_NO_ERROR;
if (error) if (error)
EXPECT_EQ(ServiceWorkerCacheStorage::kInvalidCacheID, callback_cache_id_); EXPECT_TRUE(!callback_cache_.get());
else else
EXPECT_LE(0, callback_cache_id_); EXPECT_TRUE(callback_cache_.get());
return !error; return !error;
} }
...@@ -169,6 +186,43 @@ class ServiceWorkerCacheStorageManagerTest : public testing::Test { ...@@ -169,6 +186,43 @@ class ServiceWorkerCacheStorageManagerTest : public testing::Test {
return !error; return !error;
} }
bool CachePut(const scoped_refptr<ServiceWorkerCache>& cache,
const std::string& url) {
scoped_ptr<ServiceWorkerFetchRequest> request(
new ServiceWorkerFetchRequest());
scoped_ptr<ServiceWorkerResponse> response(new ServiceWorkerResponse());
request->url = GURL("http://example.com/foo");
response->url = GURL("http://example.com/foo");
scoped_ptr<base::RunLoop> loop(new base::RunLoop());
cache->Put(
request.Pass(),
response.Pass(),
base::Bind(&ServiceWorkerCacheStorageManagerTest::CachePutCallback,
base::Unretained(this),
base::Unretained(loop.get())));
loop->Run();
bool error = callback_cache_error_ != ServiceWorkerCache::ErrorTypeOK;
return !error;
}
bool CacheMatch(const scoped_refptr<ServiceWorkerCache>& cache,
const std::string& url) {
scoped_ptr<ServiceWorkerFetchRequest> request(
new ServiceWorkerFetchRequest());
request->url = GURL("http://example.com/foo");
scoped_ptr<base::RunLoop> loop(new base::RunLoop());
cache->Match(
request.Pass(),
base::Bind(&ServiceWorkerCacheStorageManagerTest::CacheMatchCallback,
base::Unretained(this),
base::Unretained(loop.get())));
loop->Run();
bool error = callback_cache_error_ != ServiceWorkerCache::ErrorTypeOK;
return !error;
}
bool VerifyKeys(const std::vector<std::string>& expected_keys) { bool VerifyKeys(const std::vector<std::string>& expected_keys) {
if (expected_keys.size() != callback_strings_.size()) if (expected_keys.size() != callback_strings_.size())
return false; return false;
...@@ -191,9 +245,11 @@ class ServiceWorkerCacheStorageManagerTest : public testing::Test { ...@@ -191,9 +245,11 @@ class ServiceWorkerCacheStorageManagerTest : public testing::Test {
base::ScopedTempDir temp_dir_; base::ScopedTempDir temp_dir_;
scoped_ptr<ServiceWorkerCacheStorageManager> cache_manager_; scoped_ptr<ServiceWorkerCacheStorageManager> cache_manager_;
scoped_refptr<ServiceWorkerCache> callback_cache_;
int callback_bool_; int callback_bool_;
ServiceWorkerCacheStorage::CacheID callback_cache_id_;
ServiceWorkerCacheStorage::CacheStorageError callback_error_; ServiceWorkerCacheStorage::CacheStorageError callback_error_;
ServiceWorkerCache::ErrorType callback_cache_error_;
scoped_ptr<ServiceWorkerResponse> callback_cache_response_;
std::vector<std::string> callback_strings_; std::vector<std::string> callback_strings_;
const GURL origin1_; const GURL origin1_;
...@@ -234,12 +290,11 @@ TEST_P(ServiceWorkerCacheStorageManagerTestP, CreateTwoCaches) { ...@@ -234,12 +290,11 @@ TEST_P(ServiceWorkerCacheStorageManagerTestP, CreateTwoCaches) {
EXPECT_TRUE(CreateCache(origin1_, "bar")); EXPECT_TRUE(CreateCache(origin1_, "bar"));
} }
TEST_P(ServiceWorkerCacheStorageManagerTestP, IDsDiffer) { TEST_P(ServiceWorkerCacheStorageManagerTestP, CachePointersDiffer) {
EXPECT_TRUE(CreateCache(origin1_, "foo")); EXPECT_TRUE(CreateCache(origin1_, "foo"));
ServiceWorkerCacheStorage::CacheID id1 = callback_cache_id_; scoped_refptr<ServiceWorkerCache> cache = callback_cache_;
EXPECT_TRUE(CreateCache(origin1_, "bar")); EXPECT_TRUE(CreateCache(origin1_, "bar"));
ServiceWorkerCacheStorage::CacheID id2 = callback_cache_id_; EXPECT_TRUE(cache.get() != callback_cache_.get());
EXPECT_NE(id1, id2);
} }
TEST_P(ServiceWorkerCacheStorageManagerTestP, Create2CachesSameNameDiffSWs) { TEST_P(ServiceWorkerCacheStorageManagerTestP, Create2CachesSameNameDiffSWs) {
...@@ -249,9 +304,9 @@ TEST_P(ServiceWorkerCacheStorageManagerTestP, Create2CachesSameNameDiffSWs) { ...@@ -249,9 +304,9 @@ TEST_P(ServiceWorkerCacheStorageManagerTestP, Create2CachesSameNameDiffSWs) {
TEST_P(ServiceWorkerCacheStorageManagerTestP, GetCache) { TEST_P(ServiceWorkerCacheStorageManagerTestP, GetCache) {
EXPECT_TRUE(CreateCache(origin1_, "foo")); EXPECT_TRUE(CreateCache(origin1_, "foo"));
int cache_id = callback_cache_id_; scoped_refptr<ServiceWorkerCache> cache = callback_cache_;
EXPECT_TRUE(Get(origin1_, "foo")); EXPECT_TRUE(Get(origin1_, "foo"));
EXPECT_EQ(cache_id, callback_cache_id_); EXPECT_TRUE(cache.get() == callback_cache_.get());
} }
TEST_P(ServiceWorkerCacheStorageManagerTestP, GetNonExistent) { TEST_P(ServiceWorkerCacheStorageManagerTestP, GetNonExistent) {
...@@ -318,9 +373,9 @@ TEST_P(ServiceWorkerCacheStorageManagerTestP, DeletedKeysGone) { ...@@ -318,9 +373,9 @@ TEST_P(ServiceWorkerCacheStorageManagerTestP, DeletedKeysGone) {
TEST_P(ServiceWorkerCacheStorageManagerTestP, Chinese) { TEST_P(ServiceWorkerCacheStorageManagerTestP, Chinese) {
EXPECT_TRUE(CreateCache(origin1_, "你好")); EXPECT_TRUE(CreateCache(origin1_, "你好"));
int cache_id = callback_cache_id_; scoped_refptr<ServiceWorkerCache> cache = callback_cache_;
EXPECT_TRUE(Get(origin1_, "你好")); EXPECT_TRUE(Get(origin1_, "你好"));
EXPECT_EQ(cache_id, callback_cache_id_); EXPECT_TRUE(cache.get() == callback_cache_.get());
EXPECT_TRUE(Keys(origin1_)); EXPECT_TRUE(Keys(origin1_));
EXPECT_EQ(1u, callback_strings_.size()); EXPECT_EQ(1u, callback_strings_.size());
EXPECT_TRUE("你好" == callback_strings_[0]); EXPECT_TRUE("你好" == callback_strings_[0]);
...@@ -328,9 +383,9 @@ TEST_P(ServiceWorkerCacheStorageManagerTestP, Chinese) { ...@@ -328,9 +383,9 @@ TEST_P(ServiceWorkerCacheStorageManagerTestP, Chinese) {
TEST_F(ServiceWorkerCacheStorageManagerTest, EmptyKey) { TEST_F(ServiceWorkerCacheStorageManagerTest, EmptyKey) {
EXPECT_TRUE(CreateCache(origin1_, "")); EXPECT_TRUE(CreateCache(origin1_, ""));
int cache_id = callback_cache_id_; scoped_refptr<ServiceWorkerCache> cache = callback_cache_;
EXPECT_TRUE(Get(origin1_, "")); EXPECT_TRUE(Get(origin1_, ""));
EXPECT_EQ(cache_id, callback_cache_id_); EXPECT_EQ(cache.get(), callback_cache_.get());
EXPECT_TRUE(Keys(origin1_)); EXPECT_TRUE(Keys(origin1_));
EXPECT_EQ(1u, callback_strings_.size()); EXPECT_EQ(1u, callback_strings_.size());
EXPECT_TRUE("" == callback_strings_[0]); EXPECT_TRUE("" == callback_strings_[0]);
...@@ -385,6 +440,42 @@ TEST_F(ServiceWorkerCacheStorageManagerTest, BadOriginName) { ...@@ -385,6 +440,42 @@ TEST_F(ServiceWorkerCacheStorageManagerTest, BadOriginName) {
EXPECT_STREQ("foo", callback_strings_[0].c_str()); EXPECT_STREQ("foo", callback_strings_[0].c_str());
} }
// With a persistent cache if the client drops its reference to a
// ServiceWorkerCache
// it should be deleted.
TEST_F(ServiceWorkerCacheStorageManagerTest, DropReference) {
EXPECT_TRUE(CreateCache(origin1_, "foo"));
base::WeakPtr<ServiceWorkerCache> cache = callback_cache_->AsWeakPtr();
callback_cache_ = NULL;
EXPECT_TRUE(!cache);
}
// With a memory cache the cache can't be freed from memory until the client
// calls delete.
TEST_F(ServiceWorkerCacheStorageManagerMemoryOnlyTest,
MemoryLosesReferenceOnlyAfterDelete) {
EXPECT_TRUE(CreateCache(origin1_, "foo"));
base::WeakPtr<ServiceWorkerCache> cache = callback_cache_->AsWeakPtr();
callback_cache_ = NULL;
EXPECT_TRUE(cache);
EXPECT_TRUE(Delete(origin1_, "foo"));
EXPECT_FALSE(cache);
}
TEST_P(ServiceWorkerCacheStorageManagerTestP, RecreateCacheOnDemand) {
EXPECT_TRUE(CreateCache(origin1_, "foo"));
EXPECT_TRUE(CachePut(callback_cache_, "bar"));
callback_cache_ = NULL;
EXPECT_TRUE(Get(origin1_, "foo"));
EXPECT_TRUE(CacheMatch(callback_cache_, "bar"));
}
TEST_P(ServiceWorkerCacheStorageManagerTestP, DeleteBeforeRelease) {
EXPECT_TRUE(CreateCache(origin1_, "foo"));
EXPECT_TRUE(Delete(origin1_, "foo"));
EXPECT_TRUE(callback_cache_->AsWeakPtr());
}
INSTANTIATE_TEST_CASE_P(ServiceWorkerCacheStorageManagerTests, INSTANTIATE_TEST_CASE_P(ServiceWorkerCacheStorageManagerTests,
ServiceWorkerCacheStorageManagerTestP, ServiceWorkerCacheStorageManagerTestP,
::testing::Values(false, true)); ::testing::Values(false, true));
......
...@@ -82,7 +82,7 @@ class ServiceWorkerCacheTest : public testing::Test { ...@@ -82,7 +82,7 @@ class ServiceWorkerCacheTest : public testing::Test {
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
disk_cache::SimpleBackendImpl::FlushWorkerPoolForTesting(); disk_cache::SimpleBackendImpl::FlushWorkerPoolForTesting();
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
cache_.reset(); cache_ = NULL;
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
disk_cache::SimpleBackendImpl::FlushWorkerPoolForTesting(); disk_cache::SimpleBackendImpl::FlushWorkerPoolForTesting();
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
...@@ -255,7 +255,7 @@ class ServiceWorkerCacheTest : public testing::Test { ...@@ -255,7 +255,7 @@ class ServiceWorkerCacheTest : public testing::Test {
storage::BlobStorageContext* blob_storage_context_; storage::BlobStorageContext* blob_storage_context_;
base::ScopedTempDir temp_dir_; base::ScopedTempDir temp_dir_;
scoped_ptr<ServiceWorkerCache> cache_; scoped_refptr<ServiceWorkerCache> cache_;
ServiceWorkerFetchRequest body_request_; ServiceWorkerFetchRequest body_request_;
ServiceWorkerResponse body_response_; ServiceWorkerResponse body_response_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment