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

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

Issue 545533002: Move ServiceWorkerCache backend creation to a lazy init function. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@no_pointers_keys
Patch Set: Rebase Created 6 years, 3 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"
(...skipping 632 matching lines...) Expand 10 before | Expand all | Expand 10 after
643 new ServiceWorkerCache(path, request_context, blob_context)); 643 new ServiceWorkerCache(path, request_context, blob_context));
644 } 644 }
645 645
646 ServiceWorkerCache::~ServiceWorkerCache() { 646 ServiceWorkerCache::~ServiceWorkerCache() {
647 } 647 }
648 648
649 base::WeakPtr<ServiceWorkerCache> ServiceWorkerCache::AsWeakPtr() { 649 base::WeakPtr<ServiceWorkerCache> ServiceWorkerCache::AsWeakPtr() {
650 return weak_ptr_factory_.GetWeakPtr(); 650 return weak_ptr_factory_.GetWeakPtr();
651 } 651 }
652 652
653 void ServiceWorkerCache::CreateBackend(const ErrorCallback& callback) {
654 DCHECK(!backend_);
655
656 // Use APP_CACHE as opposed to DISK_CACHE to prevent cache eviction.
657 net::CacheType cache_type =
658 path_.empty() ? net::MEMORY_CACHE : net::APP_CACHE;
659
660 scoped_ptr<ScopedBackendPtr> backend_ptr(new ScopedBackendPtr());
661
662 // Temporary pointer so that backend_ptr can be Pass()'d in Bind below.
663 ScopedBackendPtr* backend = backend_ptr.get();
664
665 net::CompletionCallback create_cache_callback =
666 base::Bind(CreateBackendDidCreate,
667 callback,
668 base::Passed(backend_ptr.Pass()),
669 weak_ptr_factory_.GetWeakPtr());
670
671 // TODO(jkarlin): Use the cache MessageLoopProxy that ServiceWorkerCacheCore
672 // has for disk caches.
673 // TODO(jkarlin): Switch to SimpleCache after it supports APP_CACHE and after
674 // debugging why the QuickStressBody unittest fails with it.
675 int rv = disk_cache::CreateCacheBackend(
676 cache_type,
677 net::CACHE_BACKEND_SIMPLE,
678 path_,
679 kMaxCacheBytes,
680 false, /* force */
681 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE).get(),
682 NULL,
683 backend,
684 create_cache_callback);
685 if (rv != net::ERR_IO_PENDING)
686 create_cache_callback.Run(rv);
687 }
688
689 void ServiceWorkerCache::Put(scoped_ptr<ServiceWorkerFetchRequest> request, 653 void ServiceWorkerCache::Put(scoped_ptr<ServiceWorkerFetchRequest> request,
690 scoped_ptr<ServiceWorkerResponse> response, 654 scoped_ptr<ServiceWorkerResponse> response,
691 const ErrorCallback& callback) { 655 const ErrorCallback& callback) {
692 DCHECK(backend_);
693
694 scoped_ptr<disk_cache::Entry*> entry(new disk_cache::Entry*);
695
696 disk_cache::Entry** entry_ptr = entry.get();
697
698 scoped_ptr<storage::BlobDataHandle> blob_data_handle; 656 scoped_ptr<storage::BlobDataHandle> blob_data_handle;
699 657
700 if (!response->blob_uuid.empty()) { 658 if (!response->blob_uuid.empty()) {
701 if (!blob_storage_context_) { 659 if (!blob_storage_context_) {
702 callback.Run(ErrorTypeStorage); 660 callback.Run(ErrorTypeStorage);
703 return; 661 return;
704 } 662 }
705 blob_data_handle = 663 blob_data_handle =
706 blob_storage_context_->GetBlobDataFromUUID(response->blob_uuid); 664 blob_storage_context_->GetBlobDataFromUUID(response->blob_uuid);
707 if (!blob_data_handle) { 665 if (!blob_data_handle) {
708 callback.Run(ErrorTypeStorage); 666 callback.Run(ErrorTypeStorage);
709 return; 667 return;
710 } 668 }
711 } 669 }
712 670
713 ServiceWorkerFetchRequest* request_ptr = request.get(); 671 base::Closure continuation = base::Bind(&ServiceWorkerCache::PutImpl,
672 weak_ptr_factory_.GetWeakPtr(),
673 base::Passed(request.Pass()),
674 base::Passed(response.Pass()),
675 base::Passed(blob_data_handle.Pass()),
676 callback);
714 677
715 net::CompletionCallback create_entry_callback = 678 if (!initialized_) {
716 base::Bind(PutDidCreateEntry, 679 Init(continuation);
717 base::Passed(request.Pass()), 680 return;
718 base::Passed(response.Pass()), 681 }
719 callback,
720 base::Passed(entry.Pass()),
721 base::Passed(blob_data_handle.Pass()),
722 request_context_);
723 682
724 int rv = backend_->CreateEntry( 683 continuation.Run();
725 request_ptr->url.spec(), entry_ptr, create_entry_callback);
726
727 if (rv != net::ERR_IO_PENDING)
728 create_entry_callback.Run(rv);
729 } 684 }
730 685
731 void ServiceWorkerCache::Match(scoped_ptr<ServiceWorkerFetchRequest> request, 686 void ServiceWorkerCache::Match(scoped_ptr<ServiceWorkerFetchRequest> request,
732 const ResponseCallback& callback) { 687 const ResponseCallback& callback) {
733 DCHECK(backend_); 688 if (!initialized_) {
689 Init(base::Bind(&ServiceWorkerCache::Match,
690 weak_ptr_factory_.GetWeakPtr(),
691 base::Passed(request.Pass()),
692 callback));
693 return;
694 }
695 if (!backend_) {
696 callback.Run(ErrorTypeStorage,
697 scoped_ptr<ServiceWorkerResponse>(),
698 scoped_ptr<storage::BlobDataHandle>());
699 return;
700 }
734 701
735 scoped_ptr<disk_cache::Entry*> entry(new disk_cache::Entry*); 702 scoped_ptr<disk_cache::Entry*> entry(new disk_cache::Entry*);
736 703
737 disk_cache::Entry** entry_ptr = entry.get(); 704 disk_cache::Entry** entry_ptr = entry.get();
738 705
739 ServiceWorkerFetchRequest* request_ptr = request.get(); 706 ServiceWorkerFetchRequest* request_ptr = request.get();
740 707
741 net::CompletionCallback open_entry_callback = 708 net::CompletionCallback open_entry_callback =
742 base::Bind(MatchDidOpenEntry, 709 base::Bind(MatchDidOpenEntry,
743 base::Passed(request.Pass()), 710 base::Passed(request.Pass()),
744 callback, 711 callback,
745 blob_storage_context_, 712 blob_storage_context_,
746 base::Passed(entry.Pass())); 713 base::Passed(entry.Pass()));
747 714
748 int rv = backend_->OpenEntry( 715 int rv = backend_->OpenEntry(
749 request_ptr->url.spec(), entry_ptr, open_entry_callback); 716 request_ptr->url.spec(), entry_ptr, open_entry_callback);
750 if (rv != net::ERR_IO_PENDING) 717 if (rv != net::ERR_IO_PENDING)
751 open_entry_callback.Run(rv); 718 open_entry_callback.Run(rv);
752 } 719 }
753 720
754 void ServiceWorkerCache::Delete(scoped_ptr<ServiceWorkerFetchRequest> request, 721 void ServiceWorkerCache::Delete(scoped_ptr<ServiceWorkerFetchRequest> request,
755 const ErrorCallback& callback) { 722 const ErrorCallback& callback) {
756 DCHECK(backend_); 723 if (!initialized_) {
724 Init(base::Bind(&ServiceWorkerCache::Delete,
725 weak_ptr_factory_.GetWeakPtr(),
726 base::Passed(request.Pass()),
727 callback));
728 return;
729 }
730 if (!backend_) {
731 callback.Run(ErrorTypeStorage);
732 return;
733 }
757 734
758 scoped_ptr<disk_cache::Entry*> entry(new disk_cache::Entry*); 735 scoped_ptr<disk_cache::Entry*> entry(new disk_cache::Entry*);
759 736
760 disk_cache::Entry** entry_ptr = entry.get(); 737 disk_cache::Entry** entry_ptr = entry.get();
761 738
762 ServiceWorkerFetchRequest* request_ptr = request.get(); 739 ServiceWorkerFetchRequest* request_ptr = request.get();
763 740
764 net::CompletionCallback open_entry_callback = 741 net::CompletionCallback open_entry_callback =
765 base::Bind(DeleteDidOpenEntry, 742 base::Bind(DeleteDidOpenEntry,
766 base::Passed(request.Pass()), 743 base::Passed(request.Pass()),
767 callback, 744 callback,
768 base::Passed(entry.Pass())); 745 base::Passed(entry.Pass()));
769 746
770 int rv = backend_->OpenEntry( 747 int rv = backend_->OpenEntry(
771 request_ptr->url.spec(), entry_ptr, open_entry_callback); 748 request_ptr->url.spec(), entry_ptr, open_entry_callback);
772 if (rv != net::ERR_IO_PENDING) 749 if (rv != net::ERR_IO_PENDING)
773 open_entry_callback.Run(rv); 750 open_entry_callback.Run(rv);
774 } 751 }
775 752
776 void ServiceWorkerCache::Keys(const RequestsCallback& callback) { 753 void ServiceWorkerCache::Keys(const RequestsCallback& callback) {
777 DCHECK(backend_); 754 if (!initialized_) {
755 Init(base::Bind(
756 &ServiceWorkerCache::Keys, weak_ptr_factory_.GetWeakPtr(), callback));
757 return;
758 }
759 if (!backend_) {
760 callback.Run(ErrorTypeStorage, scoped_ptr<Requests>());
761 return;
762 }
778 763
779 // 1. Iterate through all of the entries, open them, and add them to a vector. 764 // 1. Iterate through all of the entries, open them, and add them to a vector.
780 // 2. For each open entry: 765 // 2. For each open entry:
781 // 2.1. Read the headers into a protobuf. 766 // 2.1. Read the headers into a protobuf.
782 // 2.2. Copy the protobuf into a ServiceWorkerFetchRequest (a "key"). 767 // 2.2. Copy the protobuf into a ServiceWorkerFetchRequest (a "key").
783 // 2.3. Push the response into a vector of requests to be returned. 768 // 2.3. Push the response into a vector of requests to be returned.
784 // 3. Return the vector of requests (keys). 769 // 3. Return the vector of requests (keys).
785 770
786 // The entries have to be loaded into a vector first because enumeration loops 771 // The entries have to be loaded into a vector first because enumeration loops
787 // forever if you read data from a cache entry while enumerating. 772 // forever if you read data from a cache entry while enumerating.
788 773
789 scoped_ptr<KeysContext> keys_context( 774 scoped_ptr<KeysContext> keys_context(
790 new KeysContext(callback, weak_ptr_factory_.GetWeakPtr())); 775 new KeysContext(callback, weak_ptr_factory_.GetWeakPtr()));
791 776
792 void** backend_iterator = &keys_context->backend_iterator; 777 void** backend_iterator = &keys_context->backend_iterator;
793 disk_cache::Entry** enumerated_entry = &keys_context->enumerated_entry; 778 disk_cache::Entry** enumerated_entry = &keys_context->enumerated_entry;
794 779
795 net::CompletionCallback open_entry_callback = 780 net::CompletionCallback open_entry_callback =
796 base::Bind(KeysDidOpenNextEntry, base::Passed(keys_context.Pass())); 781 base::Bind(KeysDidOpenNextEntry, base::Passed(keys_context.Pass()));
797 782
798 int rv = backend_->OpenNextEntry( 783 int rv = backend_->OpenNextEntry(
799 backend_iterator, enumerated_entry, open_entry_callback); 784 backend_iterator, enumerated_entry, open_entry_callback);
800 785
801 if (rv != net::ERR_IO_PENDING) 786 if (rv != net::ERR_IO_PENDING)
802 open_entry_callback.Run(rv); 787 open_entry_callback.Run(rv);
803 } 788 }
804 789
805 bool ServiceWorkerCache::HasCreatedBackend() const {
806 return backend_;
807 }
808
809 ServiceWorkerCache::ServiceWorkerCache( 790 ServiceWorkerCache::ServiceWorkerCache(
810 const base::FilePath& path, 791 const base::FilePath& path,
811 net::URLRequestContext* request_context, 792 net::URLRequestContext* request_context,
812 base::WeakPtr<storage::BlobStorageContext> blob_context) 793 base::WeakPtr<storage::BlobStorageContext> blob_context)
813 : path_(path), 794 : path_(path),
814 request_context_(request_context), 795 request_context_(request_context),
815 blob_storage_context_(blob_context), 796 blob_storage_context_(blob_context),
797 initialized_(false),
816 weak_ptr_factory_(this) { 798 weak_ptr_factory_(this) {
817 } 799 }
818 800
801 void ServiceWorkerCache::PutImpl(
802 scoped_ptr<ServiceWorkerFetchRequest> request,
803 scoped_ptr<ServiceWorkerResponse> response,
804 scoped_ptr<storage::BlobDataHandle> blob_data_handle,
805 const ErrorCallback& callback) {
806 if (!backend_) {
807 callback.Run(ErrorTypeStorage);
808 return;
809 }
810
811 scoped_ptr<disk_cache::Entry*> entry(new disk_cache::Entry*);
812
813 disk_cache::Entry** entry_ptr = entry.get();
814
815 ServiceWorkerFetchRequest* request_ptr = request.get();
816
817 net::CompletionCallback create_entry_callback =
818 base::Bind(PutDidCreateEntry,
819 base::Passed(request.Pass()),
820 base::Passed(response.Pass()),
821 callback,
822 base::Passed(entry.Pass()),
823 base::Passed(blob_data_handle.Pass()),
824 request_context_);
825
826 int rv = backend_->CreateEntry(
827 request_ptr->url.spec(), entry_ptr, create_entry_callback);
828
829 if (rv != net::ERR_IO_PENDING)
830 create_entry_callback.Run(rv);
831 }
832
819 // static 833 // static
820 void ServiceWorkerCache::KeysDidOpenNextEntry( 834 void ServiceWorkerCache::KeysDidOpenNextEntry(
821 scoped_ptr<KeysContext> keys_context, 835 scoped_ptr<KeysContext> keys_context,
822 int rv) { 836 int rv) {
823 if (rv == net::ERR_FAILED) { 837 if (rv == net::ERR_FAILED) {
824 DCHECK(!keys_context->enumerated_entry); 838 DCHECK(!keys_context->enumerated_entry);
825 // Enumeration is complete, extract the requests from the entries. 839 // Enumeration is complete, extract the requests from the entries.
826 Entries::iterator iter = keys_context->entries.begin(); 840 Entries::iterator iter = keys_context->entries.begin();
827 KeysProcessNextEntry(keys_context.Pass(), iter); 841 KeysProcessNextEntry(keys_context.Pass(), iter);
828 return; 842 return;
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
892 headers->request_headers(i); 906 headers->request_headers(i);
893 req_headers.insert(std::make_pair(header.name(), header.value())); 907 req_headers.insert(std::make_pair(header.name(), header.value()));
894 } 908 }
895 } else { 909 } else {
896 entry->Doom(); 910 entry->Doom();
897 } 911 }
898 912
899 KeysProcessNextEntry(keys_context.Pass(), iter + 1); 913 KeysProcessNextEntry(keys_context.Pass(), iter + 1);
900 } 914 }
901 915
916 void ServiceWorkerCache::CreateBackend(const ErrorCallback& callback) {
917 DCHECK(!backend_);
918
919 // Use APP_CACHE as opposed to DISK_CACHE to prevent cache eviction.
920 net::CacheType cache_type =
921 path_.empty() ? net::MEMORY_CACHE : net::APP_CACHE;
922
923 scoped_ptr<ScopedBackendPtr> backend_ptr(new ScopedBackendPtr());
924
925 // Temporary pointer so that backend_ptr can be Pass()'d in Bind below.
926 ScopedBackendPtr* backend = backend_ptr.get();
927
928 net::CompletionCallback create_cache_callback =
929 base::Bind(CreateBackendDidCreate,
930 callback,
931 base::Passed(backend_ptr.Pass()),
932 weak_ptr_factory_.GetWeakPtr());
933
934 // TODO(jkarlin): Use the cache MessageLoopProxy that ServiceWorkerCacheCore
935 // has for disk caches.
936 int rv = disk_cache::CreateCacheBackend(
937 cache_type,
938 net::CACHE_BACKEND_SIMPLE,
939 path_,
940 kMaxCacheBytes,
941 false, /* force */
942 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE).get(),
943 NULL,
944 backend,
945 create_cache_callback);
946 if (rv != net::ERR_IO_PENDING)
947 create_cache_callback.Run(rv);
948 }
949
950 void ServiceWorkerCache::Init(const base::Closure& callback) {
951 init_callbacks_.push_back(callback);
952
953 // If this isn't the first call to Init then return as the initialization
954 // has already started.
955 if (init_callbacks_.size() > 1u)
956 return;
957
958 CreateBackend(base::Bind(&ServiceWorkerCache::InitDone,
959 weak_ptr_factory_.GetWeakPtr()));
960 }
961
962 void ServiceWorkerCache::InitDone(ErrorType error) {
963 initialized_ = true;
964 for (std::vector<base::Closure>::iterator it = init_callbacks_.begin();
965 it != init_callbacks_.end();
966 ++it) {
967 it->Run();
968 }
969 init_callbacks_.clear();
970 }
971
902 } // namespace content 972 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/service_worker/service_worker_cache.h ('k') | content/browser/service_worker/service_worker_cache_storage.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698