Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(163)

Side by Side Diff: content/browser/cache_storage/cache_storage_cache.cc

Issue 1113303003: CacheStorage: Support multiple batch operations (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@remove_responses
Patch Set: Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/cache_storage/cache_storage_cache.h" 5 #include "content/browser/cache_storage/cache_storage_cache.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/files/file_path.h" 9 #include "base/files/file_path.h"
10 #include "base/guid.h" 10 #include "base/guid.h"
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
157 scoped_ptr<CacheMetadata> metadata(new CacheMetadata()); 157 scoped_ptr<CacheMetadata> metadata(new CacheMetadata());
158 158
159 if (!metadata->ParseFromArray(buffer->data(), buffer->size())) { 159 if (!metadata->ParseFromArray(buffer->data(), buffer->size())) {
160 callback.Run(scoped_ptr<CacheMetadata>()); 160 callback.Run(scoped_ptr<CacheMetadata>());
161 return; 161 return;
162 } 162 }
163 163
164 callback.Run(metadata.Pass()); 164 callback.Run(metadata.Pass());
165 } 165 }
166 166
167 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
168 public:
169 BatchOperationManager(int num_pending_operations,
170 const CacheStorageCache::ErrorCallback callback)
171 : num_pending_operations_(num_pending_operations), callback_(callback) {}
172
173 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)
174 if (completed_)
175 return;
176 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)
177 error != CacheStorageCache::ERROR_TYPE_OK) {
178 completed_ = true;
179 callback_.Run(error);
180 return;
181 }
182 }
183
184 private:
185 friend class base::RefCounted<BatchOperationManager>;
186 ~BatchOperationManager() {}
187
188 int num_pending_operations_;
189 bool completed_ = false;
190 CacheStorageCache::ErrorCallback callback_;
191 };
192
167 } // namespace 193 } // namespace
168 194
169 // Streams data from a blob and writes it to a given disk_cache::Entry. 195 // Streams data from a blob and writes it to a given disk_cache::Entry.
170 class CacheStorageCache::BlobReader : public net::URLRequest::Delegate { 196 class CacheStorageCache::BlobReader : public net::URLRequest::Delegate {
171 public: 197 public:
172 typedef base::Callback<void(disk_cache::ScopedEntryPtr, bool)> 198 typedef base::Callback<void(disk_cache::ScopedEntryPtr, bool)>
173 EntryAndBoolCallback; 199 EntryAndBoolCallback;
174 200
175 BlobReader() 201 BlobReader()
176 : cache_entry_offset_(0), 202 : cache_entry_offset_(0),
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
394 origin, path, request_context, quota_manager_proxy, blob_context)); 420 origin, path, request_context, quota_manager_proxy, blob_context));
395 } 421 }
396 422
397 CacheStorageCache::~CacheStorageCache() { 423 CacheStorageCache::~CacheStorageCache() {
398 } 424 }
399 425
400 base::WeakPtr<CacheStorageCache> CacheStorageCache::AsWeakPtr() { 426 base::WeakPtr<CacheStorageCache> CacheStorageCache::AsWeakPtr() {
401 return weak_ptr_factory_.GetWeakPtr(); 427 return weak_ptr_factory_.GetWeakPtr();
402 } 428 }
403 429
404 void CacheStorageCache::Put(scoped_ptr<ServiceWorkerFetchRequest> request,
405 scoped_ptr<ServiceWorkerResponse> response,
406 const ErrorCallback& callback) {
407 scoped_ptr<storage::BlobDataHandle> blob_data_handle;
408
409 if (!response->blob_uuid.empty()) {
410 if (!blob_storage_context_) {
411 callback.Run(ERROR_TYPE_STORAGE);
412 return;
413 }
414 blob_data_handle =
415 blob_storage_context_->GetBlobDataFromUUID(response->blob_uuid);
416 if (!blob_data_handle) {
417 callback.Run(ERROR_TYPE_STORAGE);
418 return;
419 }
420 }
421
422 ErrorCallback pending_callback =
423 base::Bind(&CacheStorageCache::PendingErrorCallback,
424 weak_ptr_factory_.GetWeakPtr(), callback);
425
426 scoped_ptr<PutContext> put_context(new PutContext(
427 origin_, request.Pass(), response.Pass(), blob_data_handle.Pass(),
428 pending_callback, request_context_, quota_manager_proxy_));
429
430 if (backend_state_ == BACKEND_UNINITIALIZED)
431 InitBackend();
432
433 scheduler_->ScheduleOperation(base::Bind(&CacheStorageCache::PutImpl,
434 weak_ptr_factory_.GetWeakPtr(),
435 base::Passed(put_context.Pass())));
436 }
437
438 void CacheStorageCache::Match(scoped_ptr<ServiceWorkerFetchRequest> request, 430 void CacheStorageCache::Match(scoped_ptr<ServiceWorkerFetchRequest> request,
439 const ResponseCallback& callback) { 431 const ResponseCallback& callback) {
440 switch (backend_state_) { 432 switch (backend_state_) {
441 case BACKEND_UNINITIALIZED: 433 case BACKEND_UNINITIALIZED:
442 InitBackend(); 434 InitBackend();
443 break; 435 break;
444 case BACKEND_CLOSED: 436 case BACKEND_CLOSED:
445 callback.Run(ERROR_TYPE_STORAGE, scoped_ptr<ServiceWorkerResponse>(), 437 callback.Run(ERROR_TYPE_STORAGE, scoped_ptr<ServiceWorkerResponse>(),
446 scoped_ptr<storage::BlobDataHandle>()); 438 scoped_ptr<storage::BlobDataHandle>());
447 return; 439 return;
448 case BACKEND_OPEN: 440 case BACKEND_OPEN:
449 DCHECK(backend_); 441 DCHECK(backend_);
450 break; 442 break;
451 } 443 }
452 444
453 ResponseCallback pending_callback = 445 ResponseCallback pending_callback =
454 base::Bind(&CacheStorageCache::PendingResponseCallback, 446 base::Bind(&CacheStorageCache::PendingResponseCallback,
455 weak_ptr_factory_.GetWeakPtr(), callback); 447 weak_ptr_factory_.GetWeakPtr(), callback);
456 scheduler_->ScheduleOperation( 448 scheduler_->ScheduleOperation(
457 base::Bind(&CacheStorageCache::MatchImpl, weak_ptr_factory_.GetWeakPtr(), 449 base::Bind(&CacheStorageCache::MatchImpl, weak_ptr_factory_.GetWeakPtr(),
458 base::Passed(request.Pass()), pending_callback)); 450 base::Passed(request.Pass()), pending_callback));
459 } 451 }
460 452
461 void CacheStorageCache::Delete(scoped_ptr<ServiceWorkerFetchRequest> request, 453 void CacheStorageCache::BatchOperation(
462 const ErrorCallback& callback) { 454 const std::vector<CacheStorageBatchOperation>& operations,
455 const ErrorCallback& callback) {
463 switch (backend_state_) { 456 switch (backend_state_) {
464 case BACKEND_UNINITIALIZED: 457 case BACKEND_UNINITIALIZED:
465 InitBackend(); 458 InitBackend();
466 break; 459 break;
467 case BACKEND_CLOSED: 460 case BACKEND_CLOSED:
468 callback.Run(ERROR_TYPE_STORAGE); 461 callback.Run(ERROR_TYPE_STORAGE);
469 return; 462 return;
470 case BACKEND_OPEN: 463 case BACKEND_OPEN:
471 DCHECK(backend_); 464 DCHECK(backend_);
472 break; 465 break;
473 } 466 }
474 ErrorCallback pending_callback = 467
475 base::Bind(&CacheStorageCache::PendingErrorCallback, 468 scoped_refptr<BatchOperationManager> manager(
476 weak_ptr_factory_.GetWeakPtr(), callback); 469 new BatchOperationManager(operations.size(), callback));
477 scheduler_->ScheduleOperation( 470
478 base::Bind(&CacheStorageCache::DeleteImpl, weak_ptr_factory_.GetWeakPtr(), 471 for (const auto& operation : operations) {
479 base::Passed(request.Pass()), pending_callback)); 472 ErrorCallback completion_callback =
473 base::Bind(&BatchOperationManager::OnOperationComplete, manager);
474 switch (operation.operation_type) {
475 case CACHE_STORAGE_CACHE_OPERATION_TYPE_PUT:
476 Put(operation, completion_callback);
477 break;
478 case CACHE_STORAGE_CACHE_OPERATION_TYPE_DELETE:
479 DCHECK_EQ(1u, operations.size());
480 Delete(operation, completion_callback);
481 break;
482 case CACHE_STORAGE_CACHE_OPERATION_TYPE_UNDEFINED:
483 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
484 break;
485 }
486 }
480 } 487 }
481 488
482 void CacheStorageCache::Keys(const RequestsCallback& callback) { 489 void CacheStorageCache::Keys(const RequestsCallback& callback) {
483 switch (backend_state_) { 490 switch (backend_state_) {
484 case BACKEND_UNINITIALIZED: 491 case BACKEND_UNINITIALIZED:
485 InitBackend(); 492 InitBackend();
486 break; 493 break;
487 case BACKEND_CLOSED: 494 case BACKEND_CLOSED:
488 callback.Run(ERROR_TYPE_STORAGE, scoped_ptr<Requests>()); 495 callback.Run(ERROR_TYPE_STORAGE, scoped_ptr<Requests>());
489 return; 496 return;
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after
739 746
740 scoped_ptr<storage::BlobDataHandle> blob_data_handle( 747 scoped_ptr<storage::BlobDataHandle> blob_data_handle(
741 match_context->blob_storage_context->AddFinishedBlob( 748 match_context->blob_storage_context->AddFinishedBlob(
742 match_context->blob_data.get())); 749 match_context->blob_data.get()));
743 750
744 match_context->original_callback.Run(CacheStorageCache::ERROR_TYPE_OK, 751 match_context->original_callback.Run(CacheStorageCache::ERROR_TYPE_OK,
745 match_context->response.Pass(), 752 match_context->response.Pass(),
746 blob_data_handle.Pass()); 753 blob_data_handle.Pass());
747 } 754 }
748 755
756 void CacheStorageCache::Put(const CacheStorageBatchOperation& operation,
757 const ErrorCallback& callback) {
758 DCHECK(BACKEND_OPEN == backend_state_ || initializing_);
759 DCHECK_EQ(CACHE_STORAGE_CACHE_OPERATION_TYPE_PUT, operation.operation_type);
760
761 scoped_ptr<ServiceWorkerFetchRequest> request(new ServiceWorkerFetchRequest(
762 operation.request.url, operation.request.method,
763 operation.request.headers, operation.request.referrer,
764 operation.request.is_reload));
765
766 // We don't support streaming for cache.
767 DCHECK(operation.response.stream_url.is_empty());
768 scoped_ptr<ServiceWorkerResponse> response(new ServiceWorkerResponse(
769 operation.response.url, operation.response.status_code,
770 operation.response.status_text, operation.response.response_type,
771 operation.response.headers, operation.response.blob_uuid,
772 operation.response.blob_size, operation.response.stream_url));
773
774 scoped_ptr<storage::BlobDataHandle> blob_data_handle;
775
776 if (!response->blob_uuid.empty()) {
777 if (!blob_storage_context_) {
778 callback.Run(ERROR_TYPE_STORAGE);
779 return;
780 }
781 blob_data_handle =
782 blob_storage_context_->GetBlobDataFromUUID(response->blob_uuid);
783 if (!blob_data_handle) {
784 callback.Run(ERROR_TYPE_STORAGE);
785 return;
786 }
787 }
788
789 ErrorCallback pending_callback =
790 base::Bind(&CacheStorageCache::PendingErrorCallback,
791 weak_ptr_factory_.GetWeakPtr(), callback);
792
793 scoped_ptr<PutContext> put_context(new PutContext(
794 origin_, request.Pass(), response.Pass(), blob_data_handle.Pass(),
795 pending_callback, request_context_, quota_manager_proxy_));
796
797 scheduler_->ScheduleOperation(base::Bind(&CacheStorageCache::PutImpl,
798 weak_ptr_factory_.GetWeakPtr(),
799 base::Passed(put_context.Pass())));
800 }
801
749 void CacheStorageCache::PutImpl(scoped_ptr<PutContext> put_context) { 802 void CacheStorageCache::PutImpl(scoped_ptr<PutContext> put_context) {
750 DCHECK(backend_state_ != BACKEND_UNINITIALIZED); 803 DCHECK(backend_state_ != BACKEND_UNINITIALIZED);
751 if (backend_state_ != BACKEND_OPEN) { 804 if (backend_state_ != BACKEND_OPEN) {
752 put_context->callback.Run(ERROR_TYPE_STORAGE); 805 put_context->callback.Run(ERROR_TYPE_STORAGE);
753 return; 806 return;
754 } 807 }
755 808
756 scoped_ptr<ServiceWorkerFetchRequest> request_copy( 809 scoped_ptr<ServiceWorkerFetchRequest> request_copy(
757 new ServiceWorkerFetchRequest(*put_context->request)); 810 new ServiceWorkerFetchRequest(*put_context->request));
758 811
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
907 put_context->quota_manager_proxy->NotifyStorageModified( 960 put_context->quota_manager_proxy->NotifyStorageModified(
908 storage::QuotaClient::kServiceWorkerCache, put_context->origin, 961 storage::QuotaClient::kServiceWorkerCache, put_context->origin,
909 storage::kStorageTypeTemporary, 962 storage::kStorageTypeTemporary,
910 put_context->cache_entry->GetDataSize(INDEX_HEADERS) + 963 put_context->cache_entry->GetDataSize(INDEX_HEADERS) +
911 put_context->cache_entry->GetDataSize(INDEX_RESPONSE_BODY)); 964 put_context->cache_entry->GetDataSize(INDEX_RESPONSE_BODY));
912 } 965 }
913 966
914 put_context->callback.Run(CacheStorageCache::ERROR_TYPE_OK); 967 put_context->callback.Run(CacheStorageCache::ERROR_TYPE_OK);
915 } 968 }
916 969
970 void CacheStorageCache::Delete(const CacheStorageBatchOperation& operation,
971 const ErrorCallback& callback) {
972 DCHECK(BACKEND_OPEN == backend_state_ || initializing_);
973 DCHECK_EQ(CACHE_STORAGE_CACHE_OPERATION_TYPE_DELETE,
974 operation.operation_type);
975
976 scoped_ptr<ServiceWorkerFetchRequest> request(new ServiceWorkerFetchRequest(
977 operation.request.url, operation.request.method,
978 operation.request.headers, operation.request.referrer,
979 operation.request.is_reload));
980
981 ErrorCallback pending_callback =
982 base::Bind(&CacheStorageCache::PendingErrorCallback,
983 weak_ptr_factory_.GetWeakPtr(), callback);
984 scheduler_->ScheduleOperation(
985 base::Bind(&CacheStorageCache::DeleteImpl, weak_ptr_factory_.GetWeakPtr(),
986 base::Passed(request.Pass()), pending_callback));
987 }
988
917 void CacheStorageCache::DeleteImpl( 989 void CacheStorageCache::DeleteImpl(
918 scoped_ptr<ServiceWorkerFetchRequest> request, 990 scoped_ptr<ServiceWorkerFetchRequest> request,
919 const ErrorCallback& callback) { 991 const ErrorCallback& callback) {
920 DCHECK(backend_state_ != BACKEND_UNINITIALIZED); 992 DCHECK(backend_state_ != BACKEND_UNINITIALIZED);
921 if (backend_state_ != BACKEND_OPEN) { 993 if (backend_state_ != BACKEND_OPEN) {
922 callback.Run(ERROR_TYPE_STORAGE); 994 callback.Run(ERROR_TYPE_STORAGE);
923 return; 995 return;
924 } 996 }
925 scoped_ptr<disk_cache::Entry*> entry(new disk_cache::Entry*); 997 scoped_ptr<disk_cache::Entry*> entry(new disk_cache::Entry*);
926 998
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
1191 ErrorType error, 1263 ErrorType error,
1192 scoped_ptr<Requests> requests) { 1264 scoped_ptr<Requests> requests) {
1193 base::WeakPtr<CacheStorageCache> cache = weak_ptr_factory_.GetWeakPtr(); 1265 base::WeakPtr<CacheStorageCache> cache = weak_ptr_factory_.GetWeakPtr();
1194 1266
1195 callback.Run(error, requests.Pass()); 1267 callback.Run(error, requests.Pass());
1196 if (cache) 1268 if (cache)
1197 scheduler_->CompleteOperationAndRunNext(); 1269 scheduler_->CompleteOperationAndRunNext();
1198 } 1270 }
1199 1271
1200 } // namespace content 1272 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/cache_storage/cache_storage_cache.h ('k') | content/browser/cache_storage/cache_storage_cache_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698