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

Side by Side Diff: content/browser/service_worker/service_worker_cache.cc

Issue 867903005: [ServiceWorkerCache] Serialize ServiceWorkerCacheStorage operations (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address comments from PS3 Created 5 years, 10 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/service_worker/service_worker_cache.h" 5 #include "content/browser/service_worker/service_worker_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"
11 #include "base/message_loop/message_loop_proxy.h" 11 #include "base/message_loop/message_loop_proxy.h"
12 #include "base/profiler/scoped_tracker.h" 12 #include "base/profiler/scoped_tracker.h"
13 #include "base/strings/string_util.h" 13 #include "base/strings/string_util.h"
14 #include "content/browser/service_worker/service_worker_cache.pb.h" 14 #include "content/browser/service_worker/service_worker_cache.pb.h"
15 #include "content/browser/service_worker/service_worker_cache_scheduler.h"
15 #include "content/public/browser/browser_thread.h" 16 #include "content/public/browser/browser_thread.h"
16 #include "content/public/common/referrer.h" 17 #include "content/public/common/referrer.h"
17 #include "net/base/io_buffer.h" 18 #include "net/base/io_buffer.h"
18 #include "net/base/net_errors.h" 19 #include "net/base/net_errors.h"
19 #include "net/disk_cache/disk_cache.h" 20 #include "net/disk_cache/disk_cache.h"
20 #include "net/url_request/url_request_context.h" 21 #include "net/url_request/url_request_context.h"
21 #include "storage/browser/blob/blob_data_builder.h" 22 #include "storage/browser/blob/blob_data_builder.h"
22 #include "storage/browser/blob/blob_data_handle.h" 23 #include "storage/browser/blob/blob_data_handle.h"
23 #include "storage/browser/blob/blob_storage_context.h" 24 #include "storage/browser/blob/blob_storage_context.h"
24 #include "storage/browser/blob/blob_url_request_job_factory.h" 25 #include "storage/browser/blob/blob_url_request_job_factory.h"
(...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after
455 origin_, request.Pass(), response.Pass(), blob_data_handle.Pass(), 456 origin_, request.Pass(), response.Pass(), blob_data_handle.Pass(),
456 pending_callback, request_context_, quota_manager_proxy_)); 457 pending_callback, request_context_, quota_manager_proxy_));
457 458
458 if (put_context->blob_data_handle) { 459 if (put_context->blob_data_handle) {
459 // Grab another handle to the blob for the callback response. 460 // Grab another handle to the blob for the callback response.
460 put_context->out_blob_data_handle = 461 put_context->out_blob_data_handle =
461 blob_storage_context_->GetBlobDataFromUUID( 462 blob_storage_context_->GetBlobDataFromUUID(
462 put_context->response->blob_uuid); 463 put_context->response->blob_uuid);
463 } 464 }
464 465
465 pending_operations_.push_back(base::Bind(&ServiceWorkerCache::PutImpl, 466 if (backend_state_ == BACKEND_UNINITIALIZED)
467 InitBackend();
468
469 scheduler_->ScheduleOperation(base::Bind(&ServiceWorkerCache::PutImpl,
466 weak_ptr_factory_.GetWeakPtr(), 470 weak_ptr_factory_.GetWeakPtr(),
467 base::Passed(put_context.Pass()))); 471 base::Passed(put_context.Pass())));
468
469 if (backend_state_ == BACKEND_UNINITIALIZED) {
470 InitBackend();
471 return;
472 }
473
474 RunOperationIfIdle();
475 } 472 }
476 473
477 void ServiceWorkerCache::Match(scoped_ptr<ServiceWorkerFetchRequest> request, 474 void ServiceWorkerCache::Match(scoped_ptr<ServiceWorkerFetchRequest> request,
478 const ResponseCallback& callback) { 475 const ResponseCallback& callback) {
476 switch (backend_state_) {
477 case BACKEND_UNINITIALIZED:
478 InitBackend();
479 break;
480 case BACKEND_CLOSED:
481 callback.Run(ErrorTypeStorage, scoped_ptr<ServiceWorkerResponse>(),
482 scoped_ptr<storage::BlobDataHandle>());
483 return;
484 case BACKEND_OPEN:
485 DCHECK(backend_);
486 break;
487 }
488
479 ResponseCallback pending_callback = 489 ResponseCallback pending_callback =
480 base::Bind(&ServiceWorkerCache::PendingResponseCallback, 490 base::Bind(&ServiceWorkerCache::PendingResponseCallback,
481 weak_ptr_factory_.GetWeakPtr(), callback); 491 weak_ptr_factory_.GetWeakPtr(), callback);
482 pending_operations_.push_back( 492 scheduler_->ScheduleOperation(
483 base::Bind(&ServiceWorkerCache::MatchImpl, weak_ptr_factory_.GetWeakPtr(), 493 base::Bind(&ServiceWorkerCache::MatchImpl, weak_ptr_factory_.GetWeakPtr(),
484 base::Passed(request.Pass()), pending_callback)); 494 base::Passed(request.Pass()), pending_callback));
485
486 switch (backend_state_) {
487 case BACKEND_UNINITIALIZED:
488 InitBackend();
489 return;
490 case BACKEND_CLOSED:
491 pending_callback.Run(ErrorTypeStorage,
492 scoped_ptr<ServiceWorkerResponse>(),
493 scoped_ptr<storage::BlobDataHandle>());
494 return;
495 case BACKEND_OPEN:
496 DCHECK(backend_);
497 RunOperationIfIdle();
498 return;
499 }
500 NOTREACHED();
501 } 495 }
502 496
503 void ServiceWorkerCache::Delete(scoped_ptr<ServiceWorkerFetchRequest> request, 497 void ServiceWorkerCache::Delete(scoped_ptr<ServiceWorkerFetchRequest> request,
504 const ErrorCallback& callback) { 498 const ErrorCallback& callback) {
499 switch (backend_state_) {
500 case BACKEND_UNINITIALIZED:
501 InitBackend();
502 break;
503 case BACKEND_CLOSED:
504 callback.Run(ErrorTypeStorage);
505 return;
506 case BACKEND_OPEN:
507 DCHECK(backend_);
508 break;
509 }
505 ErrorCallback pending_callback = 510 ErrorCallback pending_callback =
506 base::Bind(&ServiceWorkerCache::PendingErrorCallback, 511 base::Bind(&ServiceWorkerCache::PendingErrorCallback,
507 weak_ptr_factory_.GetWeakPtr(), callback); 512 weak_ptr_factory_.GetWeakPtr(), callback);
508 pending_operations_.push_back(base::Bind( 513 scheduler_->ScheduleOperation(base::Bind(
509 &ServiceWorkerCache::DeleteImpl, weak_ptr_factory_.GetWeakPtr(), 514 &ServiceWorkerCache::DeleteImpl, weak_ptr_factory_.GetWeakPtr(),
510 base::Passed(request.Pass()), pending_callback)); 515 base::Passed(request.Pass()), pending_callback));
516 }
511 517
518 void ServiceWorkerCache::Keys(const RequestsCallback& callback) {
512 switch (backend_state_) { 519 switch (backend_state_) {
513 case BACKEND_UNINITIALIZED: 520 case BACKEND_UNINITIALIZED:
514 InitBackend(); 521 InitBackend();
515 return; 522 break;
516 case BACKEND_CLOSED: 523 case BACKEND_CLOSED:
517 pending_callback.Run(ErrorTypeStorage); 524 callback.Run(ErrorTypeStorage, scoped_ptr<Requests>());
518 return; 525 return;
519 case BACKEND_OPEN: 526 case BACKEND_OPEN:
520 DCHECK(backend_); 527 DCHECK(backend_);
521 RunOperationIfIdle(); 528 break;
522 return;
523 } 529 }
524 NOTREACHED();
525 }
526 530
527 void ServiceWorkerCache::Keys(const RequestsCallback& callback) {
528 RequestsCallback pending_callback = 531 RequestsCallback pending_callback =
529 base::Bind(&ServiceWorkerCache::PendingRequestsCallback, 532 base::Bind(&ServiceWorkerCache::PendingRequestsCallback,
530 weak_ptr_factory_.GetWeakPtr(), callback); 533 weak_ptr_factory_.GetWeakPtr(), callback);
531 pending_operations_.push_back(base::Bind(&ServiceWorkerCache::KeysImpl, 534 scheduler_->ScheduleOperation(base::Bind(&ServiceWorkerCache::KeysImpl,
532 weak_ptr_factory_.GetWeakPtr(), 535 weak_ptr_factory_.GetWeakPtr(),
533 pending_callback)); 536 pending_callback));
534
535 switch (backend_state_) {
536 case BACKEND_UNINITIALIZED:
537 InitBackend();
538 return;
539 case BACKEND_CLOSED:
540 pending_callback.Run(ErrorTypeStorage, scoped_ptr<Requests>());
541 return;
542 case BACKEND_OPEN:
543 DCHECK(backend_);
544 RunOperationIfIdle();
545 return;
546 }
547 NOTREACHED();
548 } 537 }
549 538
550 void ServiceWorkerCache::Close(const base::Closure& callback) { 539 void ServiceWorkerCache::Close(const base::Closure& callback) {
551 DCHECK(backend_state_ != BACKEND_CLOSED) 540 DCHECK(backend_state_ != BACKEND_CLOSED)
552 << "Don't call ServiceWorkerCache::Close() twice."; 541 << "Don't call ServiceWorkerCache::Close() twice.";
553 542
554 base::Closure pending_callback = 543 base::Closure pending_callback =
555 base::Bind(&ServiceWorkerCache::PendingClosure, 544 base::Bind(&ServiceWorkerCache::PendingClosure,
556 weak_ptr_factory_.GetWeakPtr(), callback); 545 weak_ptr_factory_.GetWeakPtr(), callback);
557 546
558 pending_operations_.push_back(base::Bind(&ServiceWorkerCache::CloseImpl, 547 scheduler_->ScheduleOperation(base::Bind(&ServiceWorkerCache::CloseImpl,
559 weak_ptr_factory_.GetWeakPtr(), 548 weak_ptr_factory_.GetWeakPtr(),
560 pending_callback)); 549 pending_callback));
561 RunOperationIfIdle();
562 } 550 }
563 551
564 int64 ServiceWorkerCache::MemoryBackedSize() const { 552 int64 ServiceWorkerCache::MemoryBackedSize() const {
565 if (backend_state_ != BACKEND_OPEN || !memory_only_) 553 if (backend_state_ != BACKEND_OPEN || !memory_only_)
566 return 0; 554 return 0;
567 555
568 scoped_ptr<disk_cache::Backend::Iterator> backend_iter = 556 scoped_ptr<disk_cache::Backend::Iterator> backend_iter =
569 backend_->CreateIterator(); 557 backend_->CreateIterator();
570 disk_cache::Entry* entry = nullptr; 558 disk_cache::Entry* entry = nullptr;
571 559
(...skipping 22 matching lines...) Expand all
594 const base::FilePath& path, 582 const base::FilePath& path,
595 net::URLRequestContext* request_context, 583 net::URLRequestContext* request_context,
596 const scoped_refptr<storage::QuotaManagerProxy>& quota_manager_proxy, 584 const scoped_refptr<storage::QuotaManagerProxy>& quota_manager_proxy,
597 base::WeakPtr<storage::BlobStorageContext> blob_context) 585 base::WeakPtr<storage::BlobStorageContext> blob_context)
598 : origin_(origin), 586 : origin_(origin),
599 path_(path), 587 path_(path),
600 request_context_(request_context), 588 request_context_(request_context),
601 quota_manager_proxy_(quota_manager_proxy), 589 quota_manager_proxy_(quota_manager_proxy),
602 blob_storage_context_(blob_context), 590 blob_storage_context_(blob_context),
603 backend_state_(BACKEND_UNINITIALIZED), 591 backend_state_(BACKEND_UNINITIALIZED),
604 operation_running_(false), 592 scheduler_(new ServiceWorkerCacheScheduler()),
605 initializing_(false), 593 initializing_(false),
606 memory_only_(path.empty()), 594 memory_only_(path.empty()),
607 weak_ptr_factory_(this) { 595 weak_ptr_factory_(this) {
608 } 596 }
609 597
610 void ServiceWorkerCache::MatchImpl( 598 void ServiceWorkerCache::MatchImpl(
611 scoped_ptr<ServiceWorkerFetchRequest> request, 599 scoped_ptr<ServiceWorkerFetchRequest> request,
612 const ResponseCallback& callback) { 600 const ResponseCallback& callback) {
613 DCHECK(backend_state_ != BACKEND_UNINITIALIZED); 601 DCHECK(backend_state_ != BACKEND_UNINITIALIZED);
614 if (backend_state_ != BACKEND_OPEN) { 602 if (backend_state_ != BACKEND_OPEN) {
(...skipping 583 matching lines...) Expand 10 before | Expand all | Expand 10 after
1198 return; 1186 return;
1199 } 1187 }
1200 1188
1201 backend_ = backend_ptr->Pass(); 1189 backend_ = backend_ptr->Pass();
1202 callback.Run(ServiceWorkerCache::ErrorTypeOK); 1190 callback.Run(ServiceWorkerCache::ErrorTypeOK);
1203 } 1191 }
1204 1192
1205 void ServiceWorkerCache::InitBackend() { 1193 void ServiceWorkerCache::InitBackend() {
1206 DCHECK(backend_state_ == BACKEND_UNINITIALIZED); 1194 DCHECK(backend_state_ == BACKEND_UNINITIALIZED);
1207 1195
1208 if (initializing_) { 1196 if (initializing_)
1209 DCHECK(operation_running_);
1210 return; 1197 return;
1211 }
1212 1198
1213 DCHECK(!operation_running_); // All ops should wait for backend init. 1199 DCHECK(scheduler_->Empty());
1214 initializing_ = true; 1200 initializing_ = true;
1215 // Note that this operation pushes to the front of the queue. 1201
1216 pending_operations_.push_front(base::Bind( 1202 scheduler_->ScheduleOperation(base::Bind(
1217 &ServiceWorkerCache::CreateBackend, weak_ptr_factory_.GetWeakPtr(), 1203 &ServiceWorkerCache::CreateBackend, weak_ptr_factory_.GetWeakPtr(),
1218 base::Bind(&ServiceWorkerCache::InitDone, 1204 base::Bind(&ServiceWorkerCache::InitDone,
1219 weak_ptr_factory_.GetWeakPtr()))); 1205 weak_ptr_factory_.GetWeakPtr())));
1220 RunOperationIfIdle();
1221 } 1206 }
1222 1207
1223 void ServiceWorkerCache::InitDone(ErrorType error) { 1208 void ServiceWorkerCache::InitDone(ErrorType error) {
1224 initializing_ = false; 1209 initializing_ = false;
1225 backend_state_ = (error == ErrorTypeOK && backend_ && 1210 backend_state_ = (error == ErrorTypeOK && backend_ &&
1226 backend_state_ == BACKEND_UNINITIALIZED) 1211 backend_state_ == BACKEND_UNINITIALIZED)
1227 ? BACKEND_OPEN 1212 ? BACKEND_OPEN
1228 : BACKEND_CLOSED; 1213 : BACKEND_CLOSED;
1229 CompleteOperationAndRunNext(); 1214 scheduler_->CompleteOperationAndRunNext();
1230 }
1231
1232 void ServiceWorkerCache::CompleteOperationAndRunNext() {
1233 DCHECK(!pending_operations_.empty());
1234 operation_running_ = false;
1235 pending_operations_.pop_front();
1236 RunOperationIfIdle();
1237 }
1238
1239 void ServiceWorkerCache::RunOperationIfIdle() {
1240 DCHECK(!operation_running_ || !pending_operations_.empty());
1241
1242 if (!operation_running_ && !pending_operations_.empty()) {
1243 operation_running_ = true;
1244 // TODO(jkarlin): Run multiple operations in parallel where allowed (e.g.,
1245 // if they're for different keys then they won't interfere). See
1246 // https://crbug.com/451174.
1247 pending_operations_.front().Run();
1248 }
1249 } 1215 }
1250 1216
1251 void ServiceWorkerCache::PendingClosure(const base::Closure& callback) { 1217 void ServiceWorkerCache::PendingClosure(const base::Closure& callback) {
1218 base::WeakPtr<ServiceWorkerCache> cache = weak_ptr_factory_.GetWeakPtr();
1219
1252 callback.Run(); 1220 callback.Run();
1253 CompleteOperationAndRunNext(); 1221 if (cache)
1222 scheduler_->CompleteOperationAndRunNext();
1254 } 1223 }
1255 1224
1256 void ServiceWorkerCache::PendingErrorCallback(const ErrorCallback& callback, 1225 void ServiceWorkerCache::PendingErrorCallback(const ErrorCallback& callback,
1257 ErrorType error) { 1226 ErrorType error) {
1227 base::WeakPtr<ServiceWorkerCache> cache = weak_ptr_factory_.GetWeakPtr();
1228
1258 callback.Run(error); 1229 callback.Run(error);
1259 CompleteOperationAndRunNext(); 1230 if (cache)
1231 scheduler_->CompleteOperationAndRunNext();
1260 } 1232 }
1261 1233
1262 void ServiceWorkerCache::PendingResponseCallback( 1234 void ServiceWorkerCache::PendingResponseCallback(
1263 const ResponseCallback& callback, 1235 const ResponseCallback& callback,
1264 ErrorType error, 1236 ErrorType error,
1265 scoped_ptr<ServiceWorkerResponse> response, 1237 scoped_ptr<ServiceWorkerResponse> response,
1266 scoped_ptr<storage::BlobDataHandle> blob_data_handle) { 1238 scoped_ptr<storage::BlobDataHandle> blob_data_handle) {
1239 base::WeakPtr<ServiceWorkerCache> cache = weak_ptr_factory_.GetWeakPtr();
1240
1267 callback.Run(error, response.Pass(), blob_data_handle.Pass()); 1241 callback.Run(error, response.Pass(), blob_data_handle.Pass());
1268 CompleteOperationAndRunNext(); 1242 if (cache)
1243 scheduler_->CompleteOperationAndRunNext();
1269 } 1244 }
1270 1245
1271 void ServiceWorkerCache::PendingRequestsCallback( 1246 void ServiceWorkerCache::PendingRequestsCallback(
1272 const RequestsCallback& callback, 1247 const RequestsCallback& callback,
1273 ErrorType error, 1248 ErrorType error,
1274 scoped_ptr<Requests> requests) { 1249 scoped_ptr<Requests> requests) {
1250 base::WeakPtr<ServiceWorkerCache> cache = weak_ptr_factory_.GetWeakPtr();
1251
1275 callback.Run(error, requests.Pass()); 1252 callback.Run(error, requests.Pass());
1276 CompleteOperationAndRunNext(); 1253 if (cache)
1254 scheduler_->CompleteOperationAndRunNext();
1277 } 1255 }
1278 1256
1279 } // namespace content 1257 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/service_worker/service_worker_cache.h ('k') | content/browser/service_worker/service_worker_cache_scheduler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698