Index: content/browser/cache_storage/cache_storage_cache.cc |
diff --git a/content/browser/cache_storage/cache_storage_cache.cc b/content/browser/cache_storage/cache_storage_cache.cc |
index 522897bbbcc9e2edd087c040a8d8f8b9e950d183..43737590ee9e623cb06cf61829947c37f73cf3cb 100644 |
--- a/content/browser/cache_storage/cache_storage_cache.cc |
+++ b/content/browser/cache_storage/cache_storage_cache.cc |
@@ -6,6 +6,7 @@ |
#include <string> |
+#include "base/barrier_closure.h" |
#include "base/files/file_path.h" |
#include "base/guid.h" |
#include "base/message_loop/message_loop_proxy.h" |
@@ -401,40 +402,6 @@ base::WeakPtr<CacheStorageCache> CacheStorageCache::AsWeakPtr() { |
return weak_ptr_factory_.GetWeakPtr(); |
} |
-void CacheStorageCache::Put(scoped_ptr<ServiceWorkerFetchRequest> request, |
- scoped_ptr<ServiceWorkerResponse> response, |
- const ErrorCallback& callback) { |
- scoped_ptr<storage::BlobDataHandle> blob_data_handle; |
- |
- if (!response->blob_uuid.empty()) { |
- if (!blob_storage_context_) { |
- callback.Run(CACHE_STORAGE_ERROR_STORAGE); |
- return; |
- } |
- blob_data_handle = |
- blob_storage_context_->GetBlobDataFromUUID(response->blob_uuid); |
- if (!blob_data_handle) { |
- callback.Run(CACHE_STORAGE_ERROR_STORAGE); |
- return; |
- } |
- } |
- |
- ErrorCallback pending_callback = |
- base::Bind(&CacheStorageCache::PendingErrorCallback, |
- weak_ptr_factory_.GetWeakPtr(), callback); |
- |
- scoped_ptr<PutContext> put_context(new PutContext( |
- origin_, request.Pass(), response.Pass(), blob_data_handle.Pass(), |
- pending_callback, request_context_, quota_manager_proxy_)); |
- |
- if (backend_state_ == BACKEND_UNINITIALIZED) |
- InitBackend(); |
- |
- scheduler_->ScheduleOperation(base::Bind(&CacheStorageCache::PutImpl, |
- weak_ptr_factory_.GetWeakPtr(), |
- base::Passed(put_context.Pass()))); |
-} |
- |
void CacheStorageCache::Match(scoped_ptr<ServiceWorkerFetchRequest> request, |
const ResponseCallback& callback) { |
switch (backend_state_) { |
@@ -459,8 +426,9 @@ void CacheStorageCache::Match(scoped_ptr<ServiceWorkerFetchRequest> request, |
base::Passed(request.Pass()), pending_callback)); |
} |
-void CacheStorageCache::Delete(scoped_ptr<ServiceWorkerFetchRequest> request, |
- const ErrorCallback& callback) { |
+void CacheStorageCache::BatchOperation( |
+ const std::vector<CacheStorageBatchOperation>& operations, |
+ const ErrorCallback& callback) { |
switch (backend_state_) { |
case BACKEND_UNINITIALIZED: |
InitBackend(); |
@@ -472,12 +440,54 @@ void CacheStorageCache::Delete(scoped_ptr<ServiceWorkerFetchRequest> request, |
DCHECK(backend_); |
break; |
} |
- ErrorCallback pending_callback = |
- base::Bind(&CacheStorageCache::PendingErrorCallback, |
- weak_ptr_factory_.GetWeakPtr(), callback); |
- scheduler_->ScheduleOperation( |
- base::Bind(&CacheStorageCache::DeleteImpl, weak_ptr_factory_.GetWeakPtr(), |
- base::Passed(request.Pass()), pending_callback)); |
+ |
+ scoped_ptr<ErrorCallback> callback_copy(new ErrorCallback(callback)); |
+ ErrorCallback* callback_ptr = callback_copy.get(); |
+ base::Closure barrier_closure = base::BarrierClosure( |
+ operations.size(), base::Bind(&CacheStorageCache::BatchDidAllOperations, |
+ this, base::Passed(callback_copy.Pass()))); |
+ ErrorCallback completion_callback = |
+ base::Bind(&CacheStorageCache::BatchDidOneOperation, this, |
+ barrier_closure, callback_ptr); |
+ |
+ for (const auto& operation : operations) { |
+ switch (operation.operation_type) { |
+ case CACHE_STORAGE_CACHE_OPERATION_TYPE_PUT: |
+ Put(operation, completion_callback); |
+ break; |
+ case CACHE_STORAGE_CACHE_OPERATION_TYPE_DELETE: |
+ DCHECK_EQ(1u, operations.size()); |
+ Delete(operation, completion_callback); |
+ break; |
+ case CACHE_STORAGE_CACHE_OPERATION_TYPE_UNDEFINED: |
+ NOTREACHED(); |
+ // TODO(nhiroki): This should return "TypeError". |
+ // http://crbug.com/425505 |
+ completion_callback.Run(CACHE_STORAGE_ERROR_STORAGE); |
+ break; |
+ } |
+ } |
+} |
+ |
+void CacheStorageCache::BatchDidOneOperation( |
+ const base::Closure& barrier_closure, |
+ ErrorCallback* callback, |
+ CacheStorageError error) { |
+ if (callback->is_null() || error == CACHE_STORAGE_OK) { |
+ barrier_closure.Run(); |
+ return; |
+ } |
+ callback->Run(error); |
+ callback->Reset(); // Only call the callback once. |
+ |
+ barrier_closure.Run(); |
+} |
+ |
+void CacheStorageCache::BatchDidAllOperations( |
+ scoped_ptr<ErrorCallback> callback) { |
+ if (callback->is_null()) |
+ return; |
+ callback->Run(CACHE_STORAGE_OK); |
} |
void CacheStorageCache::Keys(const RequestsCallback& callback) { |
@@ -746,6 +756,52 @@ void CacheStorageCache::MatchDoneWithBody( |
blob_data_handle.Pass()); |
} |
+void CacheStorageCache::Put(const CacheStorageBatchOperation& operation, |
+ const ErrorCallback& callback) { |
+ DCHECK(BACKEND_OPEN == backend_state_ || initializing_); |
+ DCHECK_EQ(CACHE_STORAGE_CACHE_OPERATION_TYPE_PUT, operation.operation_type); |
+ |
+ scoped_ptr<ServiceWorkerFetchRequest> request(new ServiceWorkerFetchRequest( |
+ operation.request.url, operation.request.method, |
+ operation.request.headers, operation.request.referrer, |
+ operation.request.is_reload)); |
+ |
+ // We don't support streaming for cache. |
+ DCHECK(operation.response.stream_url.is_empty()); |
+ scoped_ptr<ServiceWorkerResponse> response(new ServiceWorkerResponse( |
+ operation.response.url, operation.response.status_code, |
+ operation.response.status_text, operation.response.response_type, |
+ operation.response.headers, operation.response.blob_uuid, |
+ operation.response.blob_size, operation.response.stream_url)); |
+ |
+ scoped_ptr<storage::BlobDataHandle> blob_data_handle; |
+ |
+ if (!response->blob_uuid.empty()) { |
+ if (!blob_storage_context_) { |
+ callback.Run(CACHE_STORAGE_ERROR_STORAGE); |
+ return; |
+ } |
+ blob_data_handle = |
+ blob_storage_context_->GetBlobDataFromUUID(response->blob_uuid); |
+ if (!blob_data_handle) { |
+ callback.Run(CACHE_STORAGE_ERROR_STORAGE); |
+ return; |
+ } |
+ } |
+ |
+ ErrorCallback pending_callback = |
+ base::Bind(&CacheStorageCache::PendingErrorCallback, |
+ weak_ptr_factory_.GetWeakPtr(), callback); |
+ |
+ scoped_ptr<PutContext> put_context(new PutContext( |
+ origin_, request.Pass(), response.Pass(), blob_data_handle.Pass(), |
+ pending_callback, request_context_, quota_manager_proxy_)); |
+ |
+ scheduler_->ScheduleOperation(base::Bind(&CacheStorageCache::PutImpl, |
+ weak_ptr_factory_.GetWeakPtr(), |
+ base::Passed(put_context.Pass()))); |
+} |
+ |
void CacheStorageCache::PutImpl(scoped_ptr<PutContext> put_context) { |
DCHECK(backend_state_ != BACKEND_UNINITIALIZED); |
if (backend_state_ != BACKEND_OPEN) { |
@@ -914,6 +970,25 @@ void CacheStorageCache::PutDidWriteBlobToCache( |
put_context->callback.Run(CACHE_STORAGE_OK); |
} |
+void CacheStorageCache::Delete(const CacheStorageBatchOperation& operation, |
+ const ErrorCallback& callback) { |
+ DCHECK(BACKEND_OPEN == backend_state_ || initializing_); |
+ DCHECK_EQ(CACHE_STORAGE_CACHE_OPERATION_TYPE_DELETE, |
+ operation.operation_type); |
+ |
+ scoped_ptr<ServiceWorkerFetchRequest> request(new ServiceWorkerFetchRequest( |
+ operation.request.url, operation.request.method, |
+ operation.request.headers, operation.request.referrer, |
+ operation.request.is_reload)); |
+ |
+ ErrorCallback pending_callback = |
+ base::Bind(&CacheStorageCache::PendingErrorCallback, |
+ weak_ptr_factory_.GetWeakPtr(), callback); |
+ scheduler_->ScheduleOperation( |
+ base::Bind(&CacheStorageCache::DeleteImpl, weak_ptr_factory_.GetWeakPtr(), |
+ base::Passed(request.Pass()), pending_callback)); |
+} |
+ |
void CacheStorageCache::DeleteImpl( |
scoped_ptr<ServiceWorkerFetchRequest> request, |
const ErrorCallback& callback) { |