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

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

Issue 867903005: [ServiceWorkerCache] Serialize ServiceWorkerCacheStorage operations (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Nits 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_storage.h" 5 #include "content/browser/service_worker/service_worker_cache_storage.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/barrier_closure.h" 9 #include "base/barrier_closure.h"
10 #include "base/files/file_util.h" 10 #include "base/files/file_util.h"
11 #include "base/files/memory_mapped_file.h" 11 #include "base/files/memory_mapped_file.h"
12 #include "base/memory/ref_counted.h" 12 #include "base/memory/ref_counted.h"
13 #include "base/sha1.h" 13 #include "base/sha1.h"
14 #include "base/stl_util.h" 14 #include "base/stl_util.h"
15 #include "base/strings/string_number_conversions.h" 15 #include "base/strings/string_number_conversions.h"
16 #include "base/strings/string_util.h" 16 #include "base/strings/string_util.h"
17 #include "content/browser/service_worker/service_worker_cache.h" 17 #include "content/browser/service_worker/service_worker_cache.h"
18 #include "content/browser/service_worker/service_worker_cache.pb.h" 18 #include "content/browser/service_worker/service_worker_cache.pb.h"
19 #include "content/browser/service_worker/service_worker_cache_scheduler.h"
19 #include "content/public/browser/browser_thread.h" 20 #include "content/public/browser/browser_thread.h"
20 #include "net/base/directory_lister.h" 21 #include "net/base/directory_lister.h"
21 #include "net/base/net_errors.h" 22 #include "net/base/net_errors.h"
22 #include "storage/browser/blob/blob_storage_context.h" 23 #include "storage/browser/blob/blob_storage_context.h"
23 #include "storage/browser/quota/quota_manager_proxy.h" 24 #include "storage/browser/quota/quota_manager_proxy.h"
24 25
25 namespace content { 26 namespace content {
26 27
27 namespace { 28 namespace {
28 29
29 void CloseAllCachesDidCloseCache(const scoped_refptr<ServiceWorkerCache>& cache, 30 void CloseAllCachesDidCloseCache(const scoped_refptr<ServiceWorkerCache>& cache,
30 const base::Closure& barrier_closure) { 31 const base::Closure& barrier_closure) {
31 barrier_closure.Run(); 32 barrier_closure.Run();
32 } 33 }
33 34
35 void NoopClosure() {
michaeln 2015/02/03 19:14:22 use base::DoNothing() instead
jkarlin 2015/02/06 12:52:48 Done.
36 }
37
34 } // namespace 38 } // namespace
35 39
36 const char ServiceWorkerCacheStorage::kIndexFileName[] = "index.txt"; 40 const char ServiceWorkerCacheStorage::kIndexFileName[] = "index.txt";
37 41
38 // Handles the loading and clean up of ServiceWorkerCache objects. The 42 // Handles the loading and clean up of ServiceWorkerCache objects. The
39 // callback of every public method is guaranteed to be called. 43 // callback of every public method is guaranteed to be called.
40 class ServiceWorkerCacheStorage::CacheLoader { 44 class ServiceWorkerCacheStorage::CacheLoader {
41 public: 45 public:
42 typedef base::Callback<void(const scoped_refptr<ServiceWorkerCache>&)> 46 typedef base::Callback<void(const scoped_refptr<ServiceWorkerCache>&)>
43 CacheCallback; 47 CacheCallback;
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after
370 374
371 ServiceWorkerCacheStorage::ServiceWorkerCacheStorage( 375 ServiceWorkerCacheStorage::ServiceWorkerCacheStorage(
372 const base::FilePath& path, 376 const base::FilePath& path,
373 bool memory_only, 377 bool memory_only,
374 base::SequencedTaskRunner* cache_task_runner, 378 base::SequencedTaskRunner* cache_task_runner,
375 net::URLRequestContext* request_context, 379 net::URLRequestContext* request_context,
376 const scoped_refptr<storage::QuotaManagerProxy>& quota_manager_proxy, 380 const scoped_refptr<storage::QuotaManagerProxy>& quota_manager_proxy,
377 base::WeakPtr<storage::BlobStorageContext> blob_context, 381 base::WeakPtr<storage::BlobStorageContext> blob_context,
378 const GURL& origin) 382 const GURL& origin)
379 : initialized_(false), 383 : initialized_(false),
384 initializing_(false),
385 scheduler_(new ServiceWorkerCacheScheduler()),
380 origin_path_(path), 386 origin_path_(path),
381 cache_task_runner_(cache_task_runner), 387 cache_task_runner_(cache_task_runner),
382 memory_only_(memory_only), 388 memory_only_(memory_only),
383 weak_factory_(this) { 389 weak_factory_(this) {
384 if (memory_only) 390 if (memory_only)
385 cache_loader_.reset(new MemoryLoader(cache_task_runner_.get(), 391 cache_loader_.reset(new MemoryLoader(cache_task_runner_.get(),
386 request_context, 392 request_context,
387 quota_manager_proxy, 393 quota_manager_proxy,
388 blob_context, 394 blob_context,
389 origin)); 395 origin));
390 else 396 else
391 cache_loader_.reset(new SimpleCacheLoader(origin_path_, 397 cache_loader_.reset(new SimpleCacheLoader(origin_path_,
392 cache_task_runner_.get(), 398 cache_task_runner_.get(),
393 request_context, 399 request_context,
394 quota_manager_proxy, 400 quota_manager_proxy,
395 blob_context, 401 blob_context,
396 origin)); 402 origin));
397 } 403 }
398 404
399 ServiceWorkerCacheStorage::~ServiceWorkerCacheStorage() { 405 ServiceWorkerCacheStorage::~ServiceWorkerCacheStorage() {
400 } 406 }
401 407
402 void ServiceWorkerCacheStorage::OpenCache( 408 void ServiceWorkerCacheStorage::OpenCache(
403 const std::string& cache_name, 409 const std::string& cache_name,
404 const CacheAndErrorCallback& callback) { 410 const CacheAndErrorCallback& callback) {
405 DCHECK_CURRENTLY_ON(BrowserThread::IO); 411 DCHECK_CURRENTLY_ON(BrowserThread::IO);
406 412
407 if (!initialized_) { 413 if (!initialized_)
408 LazyInit(base::Bind(&ServiceWorkerCacheStorage::OpenCache, 414 LazyInit();
409 weak_factory_.GetWeakPtr(),
410 cache_name,
411 callback));
412 return;
413 }
414 415
416 CacheAndErrorCallback pending_callback =
417 base::Bind(&ServiceWorkerCacheStorage::PendingCacheAndErrorCallback,
418 weak_factory_.GetWeakPtr(), callback);
419 scheduler_->ScheduleOperation(
420 base::Bind(&ServiceWorkerCacheStorage::OpenCacheImpl,
421 weak_factory_.GetWeakPtr(), cache_name, pending_callback));
422 }
423
424 void ServiceWorkerCacheStorage::OpenCacheImpl(
michaeln 2015/02/03 19:14:22 probably should move this <<>>Impl method down in
jkarlin 2015/02/06 12:52:48 Done.
425 const std::string& cache_name,
426 const CacheAndErrorCallback& callback) {
415 scoped_refptr<ServiceWorkerCache> cache = GetLoadedCache(cache_name); 427 scoped_refptr<ServiceWorkerCache> cache = GetLoadedCache(cache_name);
416 if (cache.get()) { 428 if (cache.get()) {
417 callback.Run(cache, CACHE_STORAGE_ERROR_NO_ERROR); 429 callback.Run(cache, CACHE_STORAGE_ERROR_NO_ERROR);
418 return; 430 return;
419 } 431 }
420 432
421 cache_loader_->CreateCache( 433 cache_loader_->CreateCache(
422 cache_name, 434 cache_name,
423 base::Bind(&ServiceWorkerCacheStorage::CreateCacheDidCreateCache, 435 base::Bind(&ServiceWorkerCacheStorage::CreateCacheDidCreateCache,
424 weak_factory_.GetWeakPtr(), 436 weak_factory_.GetWeakPtr(), cache_name, callback));
425 cache_name,
426 callback));
427 } 437 }
428 438
429 void ServiceWorkerCacheStorage::HasCache(const std::string& cache_name, 439 void ServiceWorkerCacheStorage::HasCache(const std::string& cache_name,
430 const BoolAndErrorCallback& callback) { 440 const BoolAndErrorCallback& callback) {
431 DCHECK_CURRENTLY_ON(BrowserThread::IO); 441 DCHECK_CURRENTLY_ON(BrowserThread::IO);
432 442
433 if (!initialized_) { 443 if (!initialized_)
434 LazyInit(base::Bind(&ServiceWorkerCacheStorage::HasCache, 444 LazyInit();
435 weak_factory_.GetWeakPtr(),
436 cache_name,
437 callback));
438 return;
439 }
440 445
441 bool has_cache = cache_map_.find(cache_name) != cache_map_.end(); 446 BoolAndErrorCallback pending_callback =
442 447 base::Bind(&ServiceWorkerCacheStorage::PendingBoolAndErrorCallback,
443 callback.Run(has_cache, CACHE_STORAGE_ERROR_NO_ERROR); 448 weak_factory_.GetWeakPtr(), callback);
449 scheduler_->ScheduleOperation(
450 base::Bind(&ServiceWorkerCacheStorage::HasCacheImpl,
451 weak_factory_.GetWeakPtr(), cache_name, pending_callback));
444 } 452 }
445 453
446 void ServiceWorkerCacheStorage::DeleteCache( 454 void ServiceWorkerCacheStorage::DeleteCache(
447 const std::string& cache_name, 455 const std::string& cache_name,
448 const BoolAndErrorCallback& callback) { 456 const BoolAndErrorCallback& callback) {
449 DCHECK_CURRENTLY_ON(BrowserThread::IO); 457 DCHECK_CURRENTLY_ON(BrowserThread::IO);
450 458
451 if (!initialized_) { 459 if (!initialized_)
452 LazyInit(base::Bind(&ServiceWorkerCacheStorage::DeleteCache, 460 LazyInit();
453 weak_factory_.GetWeakPtr(),
454 cache_name,
455 callback));
456 return;
457 }
458 461
459 CacheMap::iterator it = cache_map_.find(cache_name); 462 BoolAndErrorCallback pending_callback =
460 if (it == cache_map_.end()) { 463 base::Bind(&ServiceWorkerCacheStorage::PendingBoolAndErrorCallback,
461 callback.Run(false, CACHE_STORAGE_ERROR_NOT_FOUND); 464 weak_factory_.GetWeakPtr(), callback);
462 return; 465 scheduler_->ScheduleOperation(
463 } 466 base::Bind(&ServiceWorkerCacheStorage::DeleteCacheImpl,
464 467 weak_factory_.GetWeakPtr(), cache_name, pending_callback));
465 base::WeakPtr<ServiceWorkerCache> cache = it->second;
466 cache_map_.erase(it);
467
468 // Delete the name from ordered_cache_names_.
469 StringVector::iterator iter = std::find(
470 ordered_cache_names_.begin(), ordered_cache_names_.end(), cache_name);
471 DCHECK(iter != ordered_cache_names_.end());
472 ordered_cache_names_.erase(iter);
473
474 base::Closure closure =
475 base::Bind(&ServiceWorkerCacheStorage::DeleteCacheDidClose,
476 weak_factory_.GetWeakPtr(), cache_name, callback,
477 ordered_cache_names_, make_scoped_refptr(cache.get()));
478
479 if (cache) {
480 cache->Close(closure);
481 return;
482 }
483
484 closure.Run();
485 } 468 }
486 469
487 void ServiceWorkerCacheStorage::EnumerateCaches( 470 void ServiceWorkerCacheStorage::EnumerateCaches(
488 const StringsAndErrorCallback& callback) { 471 const StringsAndErrorCallback& callback) {
489 DCHECK_CURRENTLY_ON(BrowserThread::IO); 472 DCHECK_CURRENTLY_ON(BrowserThread::IO);
490 473
491 if (!initialized_) { 474 if (!initialized_)
492 LazyInit(base::Bind(&ServiceWorkerCacheStorage::EnumerateCaches, 475 LazyInit();
493 weak_factory_.GetWeakPtr(),
494 callback));
495 return;
496 }
497 476
498 callback.Run(ordered_cache_names_, CACHE_STORAGE_ERROR_NO_ERROR); 477 StringsAndErrorCallback pending_callback =
478 base::Bind(&ServiceWorkerCacheStorage::PendingStringsAndErrorCallback,
479 weak_factory_.GetWeakPtr(), callback);
480 scheduler_->ScheduleOperation(
481 base::Bind(&ServiceWorkerCacheStorage::EnumerateCachesImpl,
482 weak_factory_.GetWeakPtr(), pending_callback));
499 } 483 }
500 484
501 void ServiceWorkerCacheStorage::MatchCache( 485 void ServiceWorkerCacheStorage::MatchCache(
502 const std::string& cache_name, 486 const std::string& cache_name,
503 scoped_ptr<ServiceWorkerFetchRequest> request, 487 scoped_ptr<ServiceWorkerFetchRequest> request,
504 const ServiceWorkerCache::ResponseCallback& callback) { 488 const ServiceWorkerCache::ResponseCallback& callback) {
505 DCHECK_CURRENTLY_ON(BrowserThread::IO); 489 DCHECK_CURRENTLY_ON(BrowserThread::IO);
506 490
507 if (!initialized_) { 491 if (!initialized_)
508 LazyInit(base::Bind(&ServiceWorkerCacheStorage::MatchCache, 492 LazyInit();
509 weak_factory_.GetWeakPtr(), cache_name,
510 base::Passed(request.Pass()), callback));
511 return;
512 }
513 493
514 scoped_refptr<ServiceWorkerCache> cache = GetLoadedCache(cache_name); 494 ServiceWorkerCache::ResponseCallback pending_callback =
515 495 base::Bind(&ServiceWorkerCacheStorage::PendingResponseCallback,
516 if (!cache.get()) { 496 weak_factory_.GetWeakPtr(), callback);
517 callback.Run(ServiceWorkerCache::ErrorTypeNotFound, 497 scheduler_->ScheduleOperation(base::Bind(
518 scoped_ptr<ServiceWorkerResponse>(), 498 &ServiceWorkerCacheStorage::MatchCacheImpl, weak_factory_.GetWeakPtr(),
519 scoped_ptr<storage::BlobDataHandle>()); 499 cache_name, base::Passed(request.Pass()), pending_callback));
520 return;
521 }
522
523 // Pass the cache along to the callback to keep the cache open until match is
524 // done.
525 cache->Match(request.Pass(),
526 base::Bind(&ServiceWorkerCacheStorage::MatchCacheDidMatch,
527 weak_factory_.GetWeakPtr(), cache, callback));
528 } 500 }
529 501
530 void ServiceWorkerCacheStorage::MatchAllCaches( 502 void ServiceWorkerCacheStorage::MatchAllCaches(
531 scoped_ptr<ServiceWorkerFetchRequest> request, 503 scoped_ptr<ServiceWorkerFetchRequest> request,
532 const ServiceWorkerCache::ResponseCallback& callback) { 504 const ServiceWorkerCache::ResponseCallback& callback) {
533 DCHECK_CURRENTLY_ON(BrowserThread::IO); 505 DCHECK_CURRENTLY_ON(BrowserThread::IO);
534 506
535 if (!initialized_) { 507 if (!initialized_)
536 LazyInit(base::Bind(&ServiceWorkerCacheStorage::MatchAllCaches, 508 LazyInit();
537 weak_factory_.GetWeakPtr(),
538 base::Passed(request.Pass()), callback));
539 return;
540 }
541 509
542 scoped_ptr<ServiceWorkerCache::ResponseCallback> callback_copy( 510 ServiceWorkerCache::ResponseCallback pending_callback =
543 new ServiceWorkerCache::ResponseCallback(callback)); 511 base::Bind(&ServiceWorkerCacheStorage::PendingResponseCallback,
544 512 weak_factory_.GetWeakPtr(), callback);
545 ServiceWorkerCache::ResponseCallback* callback_ptr = callback_copy.get(); 513 scheduler_->ScheduleOperation(
546 base::Closure barrier_closure = base::BarrierClosure( 514 base::Bind(&ServiceWorkerCacheStorage::MatchAllCachesImpl,
547 ordered_cache_names_.size(), 515 weak_factory_.GetWeakPtr(), base::Passed(request.Pass()),
548 base::Bind(&ServiceWorkerCacheStorage::MatchAllCachesDidMatchAll, 516 pending_callback));
549 weak_factory_.GetWeakPtr(),
550 base::Passed(callback_copy.Pass())));
551
552 for (const std::string& cache_name : ordered_cache_names_) {
553 scoped_refptr<ServiceWorkerCache> cache = GetLoadedCache(cache_name);
554 DCHECK(cache.get());
555
556 cache->Match(make_scoped_ptr(new ServiceWorkerFetchRequest(*request)),
557 base::Bind(&ServiceWorkerCacheStorage::MatchAllCachesDidMatch,
558 weak_factory_.GetWeakPtr(), cache, barrier_closure,
559 callback_ptr));
560 }
561 } 517 }
562 518
563 void ServiceWorkerCacheStorage::CloseAllCaches(const base::Closure& callback) { 519 void ServiceWorkerCacheStorage::CloseAllCaches(const base::Closure& callback) {
564 DCHECK_CURRENTLY_ON(BrowserThread::IO); 520 DCHECK_CURRENTLY_ON(BrowserThread::IO);
565 521
566 if (!initialized_) { 522 if (!initialized_) {
567 callback.Run(); 523 callback.Run();
568 return; 524 return;
569 } 525 }
570 526
571 int live_cache_count = 0; 527 base::Closure pending_callback =
572 for (const auto& key_value : cache_map_) { 528 base::Bind(&ServiceWorkerCacheStorage::PendingClosure,
573 if (key_value.second) 529 weak_factory_.GetWeakPtr(), callback);
574 live_cache_count += 1; 530 scheduler_->ScheduleOperation(
575 } 531 base::Bind(&ServiceWorkerCacheStorage::CloseAllCachesImpl,
576 532 weak_factory_.GetWeakPtr(), pending_callback));
577 if (live_cache_count == 0) {
578 callback.Run();
579 return;
580 }
581
582 // The closure might modify this object so delay calling it until after
583 // iterating through cache_map_ by adding one to the barrier.
584 base::Closure barrier_closure =
585 base::BarrierClosure(live_cache_count + 1, base::Bind(callback));
586
587 for (auto& key_value : cache_map_) {
588 if (key_value.second) {
589 key_value.second->Close(base::Bind(
590 CloseAllCachesDidCloseCache,
591 make_scoped_refptr(key_value.second.get()), barrier_closure));
592 }
593 }
594
595 barrier_closure.Run();
596 } 533 }
597 534
598 int64 ServiceWorkerCacheStorage::MemoryBackedSize() const { 535 int64 ServiceWorkerCacheStorage::MemoryBackedSize() const {
599 DCHECK_CURRENTLY_ON(BrowserThread::IO); 536 DCHECK_CURRENTLY_ON(BrowserThread::IO);
600 537
601 if (!initialized_ || !memory_only_) 538 if (!initialized_ || !memory_only_)
602 return 0; 539 return 0;
603 540
604 int64 sum = 0; 541 int64 sum = 0;
605 for (auto& key_value : cache_map_) { 542 for (auto& key_value : cache_map_) {
606 if (key_value.second) 543 if (key_value.second)
607 sum += key_value.second->MemoryBackedSize(); 544 sum += key_value.second->MemoryBackedSize();
608 } 545 }
609 return sum; 546 return sum;
610 } 547 }
611 548
549 void ServiceWorkerCacheStorage::StartAsyncOperationForTesting() {
550 scheduler_->ScheduleOperation(base::Bind(&NoopClosure));
michaeln 2015/02/03 19:14:22 you can use base::DoNothing() for this, see bind_h
jkarlin 2015/02/06 12:52:48 Thanks!
551 }
552
553 void ServiceWorkerCacheStorage::CompleteAsyncOperationForTesting() {
554 scheduler_->CompleteOperationAndRunNext();
555 }
556
612 // Init is run lazily so that it is called on the proper MessageLoop. 557 // Init is run lazily so that it is called on the proper MessageLoop.
613 void ServiceWorkerCacheStorage::LazyInit(const base::Closure& callback) { 558 void ServiceWorkerCacheStorage::LazyInit() {
614 DCHECK_CURRENTLY_ON(BrowserThread::IO); 559 DCHECK_CURRENTLY_ON(BrowserThread::IO);
615 DCHECK(!initialized_); 560 DCHECK(!initialized_);
616 561
617 init_callbacks_.push_back(callback); 562 if (initializing_)
563 return;
618 564
619 // If this isn't the first call to LazyInit then return as the initialization 565 DCHECK(scheduler_->Empty());
620 // has already started. 566
621 if (init_callbacks_.size() > 1u) 567 initializing_ = true;
622 return; 568 scheduler_->ScheduleOperation(base::Bind(
569 &ServiceWorkerCacheStorage::LazyInitImpl, weak_factory_.GetWeakPtr()));
570 }
571
572 void ServiceWorkerCacheStorage::LazyInitImpl() {
573 DCHECK_CURRENTLY_ON(BrowserThread::IO);
574 DCHECK(!initialized_);
575 DCHECK(initializing_);
623 576
624 // 1. Get the list of cache names (async call) 577 // 1. Get the list of cache names (async call)
625 // 2. For each cache name, load the cache (async call) 578 // 2. For each cache name, load the cache (async call)
626 // 3. Once each load is complete, update the map variables. 579 // 3. Once each load is complete, update the map variables.
627 // 4. Call the list of waiting callbacks. 580 // 4. Call the list of waiting callbacks.
628 581
629 scoped_ptr<std::vector<std::string> > indexed_cache_names( 582 scoped_ptr<std::vector<std::string> > indexed_cache_names(
630 new std::vector<std::string>()); 583 new std::vector<std::string>());
631 584
632 cache_loader_->LoadIndex( 585 cache_loader_->LoadIndex(
633 indexed_cache_names.Pass(), 586 indexed_cache_names.Pass(),
634 base::Bind(&ServiceWorkerCacheStorage::LazyInitDidLoadIndex, 587 base::Bind(&ServiceWorkerCacheStorage::LazyInitDidLoadIndex,
635 weak_factory_.GetWeakPtr(), 588 weak_factory_.GetWeakPtr()));
636 callback));
637 } 589 }
638 590
639 void ServiceWorkerCacheStorage::LazyInitDidLoadIndex( 591 void ServiceWorkerCacheStorage::LazyInitDidLoadIndex(
640 const base::Closure& callback,
641 scoped_ptr<std::vector<std::string> > indexed_cache_names) { 592 scoped_ptr<std::vector<std::string> > indexed_cache_names) {
642 DCHECK_CURRENTLY_ON(BrowserThread::IO); 593 DCHECK_CURRENTLY_ON(BrowserThread::IO);
643 594
644 for (size_t i = 0u, max = indexed_cache_names->size(); i < max; ++i) { 595 for (size_t i = 0u, max = indexed_cache_names->size(); i < max; ++i) {
645 cache_map_.insert(std::make_pair(indexed_cache_names->at(i), 596 cache_map_.insert(std::make_pair(indexed_cache_names->at(i),
646 base::WeakPtr<ServiceWorkerCache>())); 597 base::WeakPtr<ServiceWorkerCache>()));
647 ordered_cache_names_.push_back(indexed_cache_names->at(i)); 598 ordered_cache_names_.push_back(indexed_cache_names->at(i));
648 } 599 }
649 600
601 initializing_ = false;
650 initialized_ = true; 602 initialized_ = true;
651 for (std::vector<base::Closure>::iterator it = init_callbacks_.begin(); 603
652 it != init_callbacks_.end(); 604 scheduler_->CompleteOperationAndRunNext();
653 ++it) {
654 it->Run();
655 }
656 init_callbacks_.clear();
657 } 605 }
658 606
659 void ServiceWorkerCacheStorage::CreateCacheDidCreateCache( 607 void ServiceWorkerCacheStorage::CreateCacheDidCreateCache(
660 const std::string& cache_name, 608 const std::string& cache_name,
661 const CacheAndErrorCallback& callback, 609 const CacheAndErrorCallback& callback,
662 const scoped_refptr<ServiceWorkerCache>& cache) { 610 const scoped_refptr<ServiceWorkerCache>& cache) {
663 DCHECK_CURRENTLY_ON(BrowserThread::IO); 611 DCHECK_CURRENTLY_ON(BrowserThread::IO);
664 612
665 if (!cache.get()) { 613 if (!cache.get()) {
666 callback.Run(scoped_refptr<ServiceWorkerCache>(), 614 callback.Run(scoped_refptr<ServiceWorkerCache>(),
(...skipping 15 matching lines...) Expand all
682 void ServiceWorkerCacheStorage::CreateCacheDidWriteIndex( 630 void ServiceWorkerCacheStorage::CreateCacheDidWriteIndex(
683 const CacheAndErrorCallback& callback, 631 const CacheAndErrorCallback& callback,
684 const scoped_refptr<ServiceWorkerCache>& cache, 632 const scoped_refptr<ServiceWorkerCache>& cache,
685 bool success) { 633 bool success) {
686 DCHECK_CURRENTLY_ON(BrowserThread::IO); 634 DCHECK_CURRENTLY_ON(BrowserThread::IO);
687 DCHECK(cache.get()); 635 DCHECK(cache.get());
688 636
689 callback.Run(cache, CACHE_STORAGE_ERROR_NO_ERROR); 637 callback.Run(cache, CACHE_STORAGE_ERROR_NO_ERROR);
690 } 638 }
691 639
640 void ServiceWorkerCacheStorage::HasCacheImpl(
641 const std::string& cache_name,
642 const BoolAndErrorCallback& callback) {
643 bool has_cache = cache_map_.find(cache_name) != cache_map_.end();
644
645 callback.Run(has_cache, CACHE_STORAGE_ERROR_NO_ERROR);
646 }
647
648 void ServiceWorkerCacheStorage::DeleteCacheImpl(
649 const std::string& cache_name,
650 const BoolAndErrorCallback& callback) {
651 CacheMap::iterator it = cache_map_.find(cache_name);
652 if (it == cache_map_.end()) {
653 callback.Run(false, CACHE_STORAGE_ERROR_NOT_FOUND);
654 return;
655 }
656
657 base::WeakPtr<ServiceWorkerCache> cache = it->second;
658 cache_map_.erase(it);
659
660 // Delete the name from ordered_cache_names_.
661 StringVector::iterator iter = std::find(
662 ordered_cache_names_.begin(), ordered_cache_names_.end(), cache_name);
663 DCHECK(iter != ordered_cache_names_.end());
664 ordered_cache_names_.erase(iter);
665
666 base::Closure closure =
667 base::Bind(&ServiceWorkerCacheStorage::DeleteCacheDidClose,
668 weak_factory_.GetWeakPtr(), cache_name, callback,
669 ordered_cache_names_, make_scoped_refptr(cache.get()));
670
671 if (cache) {
672 cache->Close(closure);
673 return;
674 }
675
676 closure.Run();
677 }
678
692 void ServiceWorkerCacheStorage::DeleteCacheDidClose( 679 void ServiceWorkerCacheStorage::DeleteCacheDidClose(
693 const std::string& cache_name, 680 const std::string& cache_name,
694 const BoolAndErrorCallback& callback, 681 const BoolAndErrorCallback& callback,
695 const StringVector& ordered_cache_names, 682 const StringVector& ordered_cache_names,
696 const scoped_refptr<ServiceWorkerCache>& cache /* might be null */) { 683 const scoped_refptr<ServiceWorkerCache>& cache /* might be null */) {
697 cache_loader_->WriteIndex( 684 cache_loader_->WriteIndex(
698 ordered_cache_names, 685 ordered_cache_names,
699 base::Bind(&ServiceWorkerCacheStorage::DeleteCacheDidWriteIndex, 686 base::Bind(&ServiceWorkerCacheStorage::DeleteCacheDidWriteIndex,
700 weak_factory_.GetWeakPtr(), cache_name, callback)); 687 weak_factory_.GetWeakPtr(), cache_name, callback));
701 } 688 }
(...skipping 12 matching lines...) Expand all
714 } 701 }
715 702
716 void ServiceWorkerCacheStorage::DeleteCacheDidCleanUp( 703 void ServiceWorkerCacheStorage::DeleteCacheDidCleanUp(
717 const BoolAndErrorCallback& callback, 704 const BoolAndErrorCallback& callback,
718 bool success) { 705 bool success) {
719 DCHECK_CURRENTLY_ON(BrowserThread::IO); 706 DCHECK_CURRENTLY_ON(BrowserThread::IO);
720 707
721 callback.Run(true, CACHE_STORAGE_ERROR_NO_ERROR); 708 callback.Run(true, CACHE_STORAGE_ERROR_NO_ERROR);
722 } 709 }
723 710
711 void ServiceWorkerCacheStorage::EnumerateCachesImpl(
712 const StringsAndErrorCallback& callback) {
713 callback.Run(ordered_cache_names_, CACHE_STORAGE_ERROR_NO_ERROR);
714 }
715
716 void ServiceWorkerCacheStorage::MatchCacheImpl(
717 const std::string& cache_name,
718 scoped_ptr<ServiceWorkerFetchRequest> request,
719 const ServiceWorkerCache::ResponseCallback& callback) {
720 scoped_refptr<ServiceWorkerCache> cache = GetLoadedCache(cache_name);
721
722 if (!cache.get()) {
723 callback.Run(ServiceWorkerCache::ErrorTypeNotFound,
724 scoped_ptr<ServiceWorkerResponse>(),
725 scoped_ptr<storage::BlobDataHandle>());
726 return;
727 }
728
729 // Pass the cache along to the callback to keep the cache open until match is
730 // done.
731 cache->Match(request.Pass(),
732 base::Bind(&ServiceWorkerCacheStorage::MatchCacheDidMatch,
733 weak_factory_.GetWeakPtr(), cache, callback));
734 }
735
724 void ServiceWorkerCacheStorage::MatchCacheDidMatch( 736 void ServiceWorkerCacheStorage::MatchCacheDidMatch(
725 const scoped_refptr<ServiceWorkerCache>& cache, 737 const scoped_refptr<ServiceWorkerCache>& cache,
726 const ServiceWorkerCache::ResponseCallback& callback, 738 const ServiceWorkerCache::ResponseCallback& callback,
727 ServiceWorkerCache::ErrorType error, 739 ServiceWorkerCache::ErrorType error,
728 scoped_ptr<ServiceWorkerResponse> response, 740 scoped_ptr<ServiceWorkerResponse> response,
729 scoped_ptr<storage::BlobDataHandle> handle) { 741 scoped_ptr<storage::BlobDataHandle> handle) {
730 callback.Run(error, response.Pass(), handle.Pass()); 742 callback.Run(error, response.Pass(), handle.Pass());
731 } 743 }
732 744
745 void ServiceWorkerCacheStorage::MatchAllCachesImpl(
746 scoped_ptr<ServiceWorkerFetchRequest> request,
747 const ServiceWorkerCache::ResponseCallback& callback) {
748 scoped_ptr<ServiceWorkerCache::ResponseCallback> callback_copy(
749 new ServiceWorkerCache::ResponseCallback(callback));
750
751 ServiceWorkerCache::ResponseCallback* callback_ptr = callback_copy.get();
752 base::Closure barrier_closure = base::BarrierClosure(
753 ordered_cache_names_.size(),
754 base::Bind(&ServiceWorkerCacheStorage::MatchAllCachesDidMatchAll,
755 weak_factory_.GetWeakPtr(),
756 base::Passed(callback_copy.Pass())));
757
758 for (const std::string& cache_name : ordered_cache_names_) {
759 scoped_refptr<ServiceWorkerCache> cache = GetLoadedCache(cache_name);
760 DCHECK(cache.get());
761
762 cache->Match(make_scoped_ptr(new ServiceWorkerFetchRequest(*request)),
763 base::Bind(&ServiceWorkerCacheStorage::MatchAllCachesDidMatch,
764 weak_factory_.GetWeakPtr(), cache, barrier_closure,
765 callback_ptr));
766 }
767 }
768
733 void ServiceWorkerCacheStorage::MatchAllCachesDidMatch( 769 void ServiceWorkerCacheStorage::MatchAllCachesDidMatch(
734 scoped_refptr<ServiceWorkerCache> cache, 770 scoped_refptr<ServiceWorkerCache> cache,
735 const base::Closure& barrier_closure, 771 const base::Closure& barrier_closure,
736 ServiceWorkerCache::ResponseCallback* callback, 772 ServiceWorkerCache::ResponseCallback* callback,
737 ServiceWorkerCache::ErrorType error, 773 ServiceWorkerCache::ErrorType error,
738 scoped_ptr<ServiceWorkerResponse> response, 774 scoped_ptr<ServiceWorkerResponse> response,
739 scoped_ptr<storage::BlobDataHandle> handle) { 775 scoped_ptr<storage::BlobDataHandle> handle) {
740 if (callback->is_null() || error == ServiceWorkerCache::ErrorTypeNotFound) { 776 if (callback->is_null() || error == ServiceWorkerCache::ErrorTypeNotFound) {
741 barrier_closure.Run(); 777 barrier_closure.Run();
742 return; 778 return;
(...skipping 27 matching lines...) Expand all
770 if (!cache) { 806 if (!cache) {
771 scoped_refptr<ServiceWorkerCache> new_cache = 807 scoped_refptr<ServiceWorkerCache> new_cache =
772 cache_loader_->CreateServiceWorkerCache(cache_name); 808 cache_loader_->CreateServiceWorkerCache(cache_name);
773 map_iter->second = new_cache->AsWeakPtr(); 809 map_iter->second = new_cache->AsWeakPtr();
774 return new_cache; 810 return new_cache;
775 } 811 }
776 812
777 return make_scoped_refptr(cache.get()); 813 return make_scoped_refptr(cache.get());
778 } 814 }
779 815
816 void ServiceWorkerCacheStorage::CloseAllCachesImpl(
817 const base::Closure& callback) {
818 int live_cache_count = 0;
819 for (const auto& key_value : cache_map_) {
820 if (key_value.second)
821 live_cache_count += 1;
822 }
823
824 if (live_cache_count == 0) {
825 callback.Run();
826 return;
827 }
828
829 // The closure might modify this object so delay calling it until after
830 // iterating through cache_map_ by adding one to the barrier.
831 base::Closure barrier_closure =
832 base::BarrierClosure(live_cache_count + 1, base::Bind(callback));
833
834 for (auto& key_value : cache_map_) {
835 if (key_value.second) {
836 key_value.second->Close(base::Bind(
837 CloseAllCachesDidCloseCache,
838 make_scoped_refptr(key_value.second.get()), barrier_closure));
839 }
840 }
841
842 barrier_closure.Run();
843 }
844
845 void ServiceWorkerCacheStorage::PendingClosure(const base::Closure& callback) {
846 base::WeakPtr<ServiceWorkerCacheStorage> cache_storage =
847 weak_factory_.GetWeakPtr();
848
849 callback.Run();
850 if (cache_storage)
851 scheduler_->CompleteOperationAndRunNext();
852 }
853
854 void ServiceWorkerCacheStorage::PendingBoolAndErrorCallback(
855 const BoolAndErrorCallback& callback,
856 bool found,
857 CacheStorageError error) {
858 base::WeakPtr<ServiceWorkerCacheStorage> cache_storage =
859 weak_factory_.GetWeakPtr();
860
861 callback.Run(found, error);
862 if (cache_storage)
863 scheduler_->CompleteOperationAndRunNext();
864 }
865
866 void ServiceWorkerCacheStorage::PendingCacheAndErrorCallback(
867 const CacheAndErrorCallback& callback,
868 const scoped_refptr<ServiceWorkerCache>& cache,
869 CacheStorageError error) {
870 base::WeakPtr<ServiceWorkerCacheStorage> cache_storage =
871 weak_factory_.GetWeakPtr();
872
873 callback.Run(cache, error);
874 if (cache_storage)
875 scheduler_->CompleteOperationAndRunNext();
876 }
877
878 void ServiceWorkerCacheStorage::PendingStringsAndErrorCallback(
879 const StringsAndErrorCallback& callback,
880 const StringVector& strings,
881 CacheStorageError error) {
882 base::WeakPtr<ServiceWorkerCacheStorage> cache_storage =
883 weak_factory_.GetWeakPtr();
884
885 callback.Run(strings, error);
886 if (cache_storage)
887 scheduler_->CompleteOperationAndRunNext();
888 }
889
890 void ServiceWorkerCacheStorage::PendingResponseCallback(
891 const ServiceWorkerCache::ResponseCallback& callback,
892 ServiceWorkerCache::ErrorType error,
893 scoped_ptr<ServiceWorkerResponse> response,
894 scoped_ptr<storage::BlobDataHandle> blob_data_handle) {
895 base::WeakPtr<ServiceWorkerCacheStorage> cache_storage =
896 weak_factory_.GetWeakPtr();
897
898 callback.Run(error, response.Pass(), blob_data_handle.Pass());
899 if (cache_storage)
900 scheduler_->CompleteOperationAndRunNext();
901 }
902
780 } // namespace content 903 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698