Chromium Code Reviews| 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) { |