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 544355296fbd1260eb07d9bec11bf8558b32502c..079834513760092248ce6501800b2bc9ef025dfe 100644 |
--- a/content/browser/cache_storage/cache_storage_cache.cc |
+++ b/content/browser/cache_storage/cache_storage_cache.cc |
@@ -164,6 +164,32 @@ void ReadMetadataDidReadMetadata( |
callback.Run(metadata.Pass()); |
} |
+class BatchOperationManager : public base::RefCounted<BatchOperationManager> { |
jkarlin
2015/05/07 13:06:16
Why not use a BarrierClosure instead? An example v
nhiroki
2015/05/08 04:00:58
Ah, I didn't know MatchAllCaches does the similar
|
+ public: |
+ BatchOperationManager(int num_pending_operations, |
+ const CacheStorageCache::ErrorCallback callback) |
+ : num_pending_operations_(num_pending_operations), callback_(callback) {} |
+ |
+ void OnOperationComplete(CacheStorageCache::ErrorType error) { |
jkarlin
2015/05/07 13:06:16
DCHECK_GE(0, num_pending_operations_)
nhiroki
2015/05/08 04:00:58
(Removed this part)
|
+ if (completed_) |
+ return; |
+ if (--num_pending_operations_ == 0 || |
jkarlin
2015/05/07 13:06:16
This will cause num_pending_operations_ to go nega
nhiroki
2015/05/08 04:00:58
(Removed this part)
|
+ error != CacheStorageCache::ERROR_TYPE_OK) { |
+ completed_ = true; |
+ callback_.Run(error); |
+ return; |
+ } |
+ } |
+ |
+ private: |
+ friend class base::RefCounted<BatchOperationManager>; |
+ ~BatchOperationManager() {} |
+ |
+ int num_pending_operations_; |
+ bool completed_ = false; |
+ CacheStorageCache::ErrorCallback callback_; |
+}; |
+ |
} // namespace |
// Streams data from a blob and writes it to a given disk_cache::Entry. |
@@ -401,40 +427,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(ERROR_TYPE_STORAGE); |
- return; |
- } |
- blob_data_handle = |
- blob_storage_context_->GetBlobDataFromUUID(response->blob_uuid); |
- if (!blob_data_handle) { |
- callback.Run(ERROR_TYPE_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_) { |
@@ -458,8 +450,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(); |
@@ -471,12 +464,26 @@ 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_refptr<BatchOperationManager> manager( |
+ new BatchOperationManager(operations.size(), callback)); |
+ |
+ for (const auto& operation : operations) { |
+ ErrorCallback completion_callback = |
+ base::Bind(&BatchOperationManager::OnOperationComplete, manager); |
+ 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(); |
jkarlin
2015/05/07 13:06:16
Run the callback with an error here.
nhiroki
2015/05/08 04:00:58
Done.
According to the spec, this case should ret
|
+ break; |
+ } |
+ } |
} |
void CacheStorageCache::Keys(const RequestsCallback& callback) { |
@@ -746,6 +753,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(ERROR_TYPE_STORAGE); |
+ return; |
+ } |
+ blob_data_handle = |
+ blob_storage_context_->GetBlobDataFromUUID(response->blob_uuid); |
+ if (!blob_data_handle) { |
+ callback.Run(ERROR_TYPE_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 +967,25 @@ void CacheStorageCache::PutDidWriteBlobToCache( |
put_context->callback.Run(CacheStorageCache::ERROR_TYPE_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) { |