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

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

Issue 701403002: [ServiceWorkerCache Cleanup] Make the state of the cache backend explicit (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@close_async
Patch Set: Nits Created 6 years, 1 month 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 697 matching lines...) Expand 10 before | Expand all | Expand 10 after
708 if (put_context->blob_data_handle) { 708 if (put_context->blob_data_handle) {
709 // Grab another handle to the blob for the callback response. 709 // Grab another handle to the blob for the callback response.
710 put_context->out_blob_data_handle = 710 put_context->out_blob_data_handle =
711 blob_storage_context_->GetBlobDataFromUUID( 711 blob_storage_context_->GetBlobDataFromUUID(
712 put_context->response->blob_uuid); 712 put_context->response->blob_uuid);
713 } 713 }
714 714
715 base::Closure continuation = base::Bind(&ServiceWorkerCache::PutImpl, 715 base::Closure continuation = base::Bind(&ServiceWorkerCache::PutImpl,
716 base::Passed(put_context.Pass())); 716 base::Passed(put_context.Pass()));
717 717
718 if (!initialized_) { 718 if (backend_state_ == BackendUninitialized) {
719 Init(continuation); 719 InitBackend(continuation);
720 return; 720 return;
721 } 721 }
722 722
723 continuation.Run(); 723 continuation.Run();
724 } 724 }
725 725
726 void ServiceWorkerCache::Match(scoped_ptr<ServiceWorkerFetchRequest> request, 726 void ServiceWorkerCache::Match(scoped_ptr<ServiceWorkerFetchRequest> request,
727 const ResponseCallback& callback) { 727 const ResponseCallback& callback) {
728 IncPendingOps(); 728 IncPendingOps();
729 ResponseCallback pending_callback = 729 ResponseCallback pending_callback =
730 base::Bind(&ServiceWorkerCache::PendingResponseCallback, 730 base::Bind(&ServiceWorkerCache::PendingResponseCallback,
731 weak_ptr_factory_.GetWeakPtr(), callback); 731 weak_ptr_factory_.GetWeakPtr(), callback);
732 732
733 if (!initialized_) { 733 switch (backend_state_) {
734 Init(base::Bind(&ServiceWorkerCache::Match, weak_ptr_factory_.GetWeakPtr(), 734 case BackendUninitialized:
735 base::Passed(request.Pass()), pending_callback)); 735 InitBackend(base::Bind(&ServiceWorkerCache::Match,
736 return; 736 weak_ptr_factory_.GetWeakPtr(),
737 } 737 base::Passed(request.Pass()), pending_callback));
738 if (!backend_) { 738 return;
739 pending_callback.Run(ErrorTypeStorage, scoped_ptr<ServiceWorkerResponse>(), 739 case BackendClosed:
740 scoped_ptr<storage::BlobDataHandle>()); 740 pending_callback.Run(ErrorTypeStorage,
741 return; 741 scoped_ptr<ServiceWorkerResponse>(),
742 scoped_ptr<storage::BlobDataHandle>());
743 return;
744 case BackendOpen:
745 DCHECK(backend_);
746 break;
742 } 747 }
743 748
744 scoped_ptr<disk_cache::Entry*> entry(new disk_cache::Entry*); 749 scoped_ptr<disk_cache::Entry*> entry(new disk_cache::Entry*);
745 750
746 disk_cache::Entry** entry_ptr = entry.get(); 751 disk_cache::Entry** entry_ptr = entry.get();
747 752
748 ServiceWorkerFetchRequest* request_ptr = request.get(); 753 ServiceWorkerFetchRequest* request_ptr = request.get();
749 754
750 net::CompletionCallback open_entry_callback = base::Bind( 755 net::CompletionCallback open_entry_callback = base::Bind(
751 MatchDidOpenEntry, base::Passed(request.Pass()), pending_callback, 756 MatchDidOpenEntry, base::Passed(request.Pass()), pending_callback,
752 blob_storage_context_, base::Passed(entry.Pass())); 757 blob_storage_context_, base::Passed(entry.Pass()));
753 758
754 int rv = backend_->OpenEntry( 759 int rv = backend_->OpenEntry(
755 request_ptr->url.spec(), entry_ptr, open_entry_callback); 760 request_ptr->url.spec(), entry_ptr, open_entry_callback);
756 if (rv != net::ERR_IO_PENDING) 761 if (rv != net::ERR_IO_PENDING)
757 open_entry_callback.Run(rv); 762 open_entry_callback.Run(rv);
758 } 763 }
759 764
760 void ServiceWorkerCache::Delete(scoped_ptr<ServiceWorkerFetchRequest> request, 765 void ServiceWorkerCache::Delete(scoped_ptr<ServiceWorkerFetchRequest> request,
761 const ErrorCallback& callback) { 766 const ErrorCallback& callback) {
762 IncPendingOps(); 767 IncPendingOps();
763 ErrorCallback pending_callback = 768 ErrorCallback pending_callback =
764 base::Bind(&ServiceWorkerCache::PendingErrorCallback, 769 base::Bind(&ServiceWorkerCache::PendingErrorCallback,
765 weak_ptr_factory_.GetWeakPtr(), callback); 770 weak_ptr_factory_.GetWeakPtr(), callback);
766 771
767 if (!initialized_) { 772 switch (backend_state_) {
768 Init(base::Bind(&ServiceWorkerCache::Delete, weak_ptr_factory_.GetWeakPtr(), 773 case BackendUninitialized:
769 base::Passed(request.Pass()), pending_callback)); 774 InitBackend(base::Bind(&ServiceWorkerCache::Delete,
770 return; 775 weak_ptr_factory_.GetWeakPtr(),
771 } 776 base::Passed(request.Pass()), pending_callback));
772 if (!backend_) { 777 return;
773 pending_callback.Run(ErrorTypeStorage); 778 case BackendClosed:
774 return; 779 pending_callback.Run(ErrorTypeStorage);
780 return;
781 case BackendOpen:
782 DCHECK(backend_);
783 break;
775 } 784 }
776 785
777 scoped_ptr<disk_cache::Entry*> entry(new disk_cache::Entry*); 786 scoped_ptr<disk_cache::Entry*> entry(new disk_cache::Entry*);
778 787
779 disk_cache::Entry** entry_ptr = entry.get(); 788 disk_cache::Entry** entry_ptr = entry.get();
780 789
781 ServiceWorkerFetchRequest* request_ptr = request.get(); 790 ServiceWorkerFetchRequest* request_ptr = request.get();
782 791
783 net::CompletionCallback open_entry_callback = base::Bind( 792 net::CompletionCallback open_entry_callback = base::Bind(
784 DeleteDidOpenEntry, origin_, base::Passed(request.Pass()), 793 DeleteDidOpenEntry, origin_, base::Passed(request.Pass()),
785 pending_callback, base::Passed(entry.Pass()), quota_manager_proxy_); 794 pending_callback, base::Passed(entry.Pass()), quota_manager_proxy_);
786 795
787 int rv = backend_->OpenEntry( 796 int rv = backend_->OpenEntry(
788 request_ptr->url.spec(), entry_ptr, open_entry_callback); 797 request_ptr->url.spec(), entry_ptr, open_entry_callback);
789 if (rv != net::ERR_IO_PENDING) 798 if (rv != net::ERR_IO_PENDING)
790 open_entry_callback.Run(rv); 799 open_entry_callback.Run(rv);
791 } 800 }
792 801
793 void ServiceWorkerCache::Keys(const RequestsCallback& callback) { 802 void ServiceWorkerCache::Keys(const RequestsCallback& callback) {
794 IncPendingOps(); 803 IncPendingOps();
795 RequestsCallback pending_callback = 804 RequestsCallback pending_callback =
796 base::Bind(&ServiceWorkerCache::PendingRequestsCallback, 805 base::Bind(&ServiceWorkerCache::PendingRequestsCallback,
797 weak_ptr_factory_.GetWeakPtr(), callback); 806 weak_ptr_factory_.GetWeakPtr(), callback);
798 if (!initialized_) { 807
799 Init(base::Bind(&ServiceWorkerCache::Keys, weak_ptr_factory_.GetWeakPtr(), 808 switch (backend_state_) {
800 pending_callback)); 809 case BackendUninitialized:
801 return; 810 InitBackend(base::Bind(&ServiceWorkerCache::Keys,
802 } 811 weak_ptr_factory_.GetWeakPtr(), pending_callback));
803 if (!backend_) { 812 return;
804 pending_callback.Run(ErrorTypeStorage, scoped_ptr<Requests>()); 813 case BackendClosed:
805 return; 814 pending_callback.Run(ErrorTypeStorage, scoped_ptr<Requests>());
815 return;
816 case BackendOpen:
817 DCHECK(backend_);
818 break;
806 } 819 }
807 820
808 // 1. Iterate through all of the entries, open them, and add them to a vector. 821 // 1. Iterate through all of the entries, open them, and add them to a vector.
809 // 2. For each open entry: 822 // 2. For each open entry:
810 // 2.1. Read the headers into a protobuf. 823 // 2.1. Read the headers into a protobuf.
811 // 2.2. Copy the protobuf into a ServiceWorkerFetchRequest (a "key"). 824 // 2.2. Copy the protobuf into a ServiceWorkerFetchRequest (a "key").
812 // 2.3. Push the response into a vector of requests to be returned. 825 // 2.3. Push the response into a vector of requests to be returned.
813 // 3. Return the vector of requests (keys). 826 // 3. Return the vector of requests (keys).
814 827
815 // The entries have to be loaded into a vector first because enumeration loops 828 // The entries have to be loaded into a vector first because enumeration loops
816 // forever if you read data from a cache entry while enumerating. 829 // forever if you read data from a cache entry while enumerating.
817 830
818 scoped_ptr<KeysContext> keys_context( 831 scoped_ptr<KeysContext> keys_context(
819 new KeysContext(pending_callback, weak_ptr_factory_.GetWeakPtr())); 832 new KeysContext(pending_callback, weak_ptr_factory_.GetWeakPtr()));
820 833
821 keys_context->backend_iterator = backend_->CreateIterator(); 834 keys_context->backend_iterator = backend_->CreateIterator();
822 disk_cache::Backend::Iterator& iterator = *keys_context->backend_iterator; 835 disk_cache::Backend::Iterator& iterator = *keys_context->backend_iterator;
823 disk_cache::Entry** enumerated_entry = &keys_context->enumerated_entry; 836 disk_cache::Entry** enumerated_entry = &keys_context->enumerated_entry;
824 837
825 net::CompletionCallback open_entry_callback = 838 net::CompletionCallback open_entry_callback =
826 base::Bind(KeysDidOpenNextEntry, base::Passed(keys_context.Pass())); 839 base::Bind(KeysDidOpenNextEntry, base::Passed(keys_context.Pass()));
827 840
828 int rv = iterator.OpenNextEntry(enumerated_entry, open_entry_callback); 841 int rv = iterator.OpenNextEntry(enumerated_entry, open_entry_callback);
829 842
830 if (rv != net::ERR_IO_PENDING) 843 if (rv != net::ERR_IO_PENDING)
831 open_entry_callback.Run(rv); 844 open_entry_callback.Run(rv);
832 } 845 }
833 846
834 void ServiceWorkerCache::Close(const base::Closure& callback) { 847 void ServiceWorkerCache::Close(const base::Closure& callback) {
835 DCHECK(!initialized_ || backend_) 848 DCHECK(backend_state_ != BackendClosed)
836 << "Don't call ServiceWorkerCache::Close() twice."; 849 << "Don't call ServiceWorkerCache::Close() twice.";
837 850
851 backend_state_ = BackendClosed;
852
838 if (pending_ops_ > 0) { 853 if (pending_ops_ > 0) {
839 DCHECK(ops_complete_callback_.is_null()); 854 DCHECK(ops_complete_callback_.is_null());
840 initialized_ = true; // So that future operations halt.
841 ops_complete_callback_ = base::Bind( 855 ops_complete_callback_ = base::Bind(
842 &ServiceWorkerCache::Close, weak_ptr_factory_.GetWeakPtr(), callback); 856 &ServiceWorkerCache::Close, weak_ptr_factory_.GetWeakPtr(), callback);
843 return; 857 return;
844 } 858 }
845 859
846 initialized_ = true;
847 backend_.reset(); 860 backend_.reset();
848 callback.Run(); 861 callback.Run();
849 } 862 }
850 863
851 int64 ServiceWorkerCache::MemoryBackedSize() const { 864 int64 ServiceWorkerCache::MemoryBackedSize() const {
852 if (!backend_ || !memory_only_) 865 if (backend_state_ != BackendOpen || !memory_only_)
853 return 0; 866 return 0;
854 867
855 scoped_ptr<disk_cache::Backend::Iterator> backend_iter = 868 scoped_ptr<disk_cache::Backend::Iterator> backend_iter =
856 backend_->CreateIterator(); 869 backend_->CreateIterator();
857 disk_cache::Entry* entry = nullptr; 870 disk_cache::Entry* entry = nullptr;
858 871
859 int64 sum = 0; 872 int64 sum = 0;
860 873
861 std::vector<disk_cache::Entry*> entries; 874 std::vector<disk_cache::Entry*> entries;
862 int rv = net::OK; 875 int rv = net::OK;
(...skipping 17 matching lines...) Expand all
880 const GURL& origin, 893 const GURL& origin,
881 const base::FilePath& path, 894 const base::FilePath& path,
882 net::URLRequestContext* request_context, 895 net::URLRequestContext* request_context,
883 const scoped_refptr<storage::QuotaManagerProxy>& quota_manager_proxy, 896 const scoped_refptr<storage::QuotaManagerProxy>& quota_manager_proxy,
884 base::WeakPtr<storage::BlobStorageContext> blob_context) 897 base::WeakPtr<storage::BlobStorageContext> blob_context)
885 : origin_(origin), 898 : origin_(origin),
886 path_(path), 899 path_(path),
887 request_context_(request_context), 900 request_context_(request_context),
888 quota_manager_proxy_(quota_manager_proxy), 901 quota_manager_proxy_(quota_manager_proxy),
889 blob_storage_context_(blob_context), 902 blob_storage_context_(blob_context),
890 initialized_(false), 903 backend_state_(BackendUninitialized),
891 memory_only_(path.empty()), 904 memory_only_(path.empty()),
892 pending_ops_(0), 905 pending_ops_(0),
893 weak_ptr_factory_(this) { 906 weak_ptr_factory_(this) {
894 } 907 }
895 908
896 // static 909 // static
897 void ServiceWorkerCache::PutImpl(scoped_ptr<PutContext> put_context) { 910 void ServiceWorkerCache::PutImpl(scoped_ptr<PutContext> put_context) {
898 if (!put_context->cache || !put_context->cache->backend_) { 911 if (!put_context->cache ||
912 put_context->cache->backend_state_ != BackendOpen) {
899 put_context->callback.Run(ErrorTypeStorage, 913 put_context->callback.Run(ErrorTypeStorage,
900 scoped_ptr<ServiceWorkerResponse>(), 914 scoped_ptr<ServiceWorkerResponse>(),
901 scoped_ptr<storage::BlobDataHandle>()); 915 scoped_ptr<storage::BlobDataHandle>());
902 return; 916 return;
903 } 917 }
904 918
905 scoped_ptr<ServiceWorkerFetchRequest> request_copy( 919 scoped_ptr<ServiceWorkerFetchRequest> request_copy(
906 new ServiceWorkerFetchRequest(*put_context->request)); 920 new ServiceWorkerFetchRequest(*put_context->request));
907 ServiceWorkerCache* cache_ptr = put_context->cache.get(); 921 ServiceWorkerCache* cache_ptr = put_context->cache.get();
908 922
909 cache_ptr->Delete(request_copy.Pass(), 923 cache_ptr->Delete(request_copy.Pass(),
910 base::Bind(PutDidDelete, base::Passed(put_context.Pass()))); 924 base::Bind(PutDidDelete, base::Passed(put_context.Pass())));
911 } 925 }
912 926
913 // static 927 // static
914 void ServiceWorkerCache::PutDidDelete(scoped_ptr<PutContext> put_context, 928 void ServiceWorkerCache::PutDidDelete(scoped_ptr<PutContext> put_context,
915 ErrorType delete_error) { 929 ErrorType delete_error) {
916 if (!put_context->cache || !put_context->cache->backend_) { 930 if (!put_context->cache ||
931 put_context->cache->backend_state_ != BackendOpen) {
917 put_context->callback.Run(ErrorTypeStorage, 932 put_context->callback.Run(ErrorTypeStorage,
918 scoped_ptr<ServiceWorkerResponse>(), 933 scoped_ptr<ServiceWorkerResponse>(),
919 scoped_ptr<storage::BlobDataHandle>()); 934 scoped_ptr<storage::BlobDataHandle>());
920 return; 935 return;
921 } 936 }
922 937
923 disk_cache::Entry** entry_ptr = &put_context->cache_entry; 938 disk_cache::Entry** entry_ptr = &put_context->cache_entry;
924 ServiceWorkerFetchRequest* request_ptr = put_context->request.get(); 939 ServiceWorkerFetchRequest* request_ptr = put_context->request.get();
925 disk_cache::Backend* backend_ptr = put_context->cache->backend_.get(); 940 disk_cache::Backend* backend_ptr = put_context->cache->backend_.get();
926 941
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
1094 return; 1109 return;
1095 } 1110 }
1096 1111
1097 base::WeakPtr<ServiceWorkerCache> cache = keys_context->cache; 1112 base::WeakPtr<ServiceWorkerCache> cache = keys_context->cache;
1098 if (rv < 0 || !cache) { 1113 if (rv < 0 || !cache) {
1099 keys_context->original_callback.Run(ErrorTypeStorage, 1114 keys_context->original_callback.Run(ErrorTypeStorage,
1100 scoped_ptr<Requests>()); 1115 scoped_ptr<Requests>());
1101 return; 1116 return;
1102 } 1117 }
1103 1118
1104 if (!cache->backend_) { 1119 if (cache->backend_state_ != BackendOpen) {
1105 keys_context->original_callback.Run(ErrorTypeNotFound, 1120 keys_context->original_callback.Run(ErrorTypeNotFound,
1106 scoped_ptr<Requests>()); 1121 scoped_ptr<Requests>());
1107 return; 1122 return;
1108 } 1123 }
1109 1124
1110 // Store the entry. 1125 // Store the entry.
1111 keys_context->entries.push_back(keys_context->enumerated_entry); 1126 keys_context->entries.push_back(keys_context->enumerated_entry);
1112 keys_context->enumerated_entry = NULL; 1127 keys_context->enumerated_entry = NULL;
1113 1128
1114 // Enumerate the next entry. 1129 // Enumerate the next entry.
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
1194 kMaxCacheBytes, 1209 kMaxCacheBytes,
1195 false, /* force */ 1210 false, /* force */
1196 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE).get(), 1211 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE).get(),
1197 NULL, 1212 NULL,
1198 backend, 1213 backend,
1199 create_cache_callback); 1214 create_cache_callback);
1200 if (rv != net::ERR_IO_PENDING) 1215 if (rv != net::ERR_IO_PENDING)
1201 create_cache_callback.Run(rv); 1216 create_cache_callback.Run(rv);
1202 } 1217 }
1203 1218
1204 void ServiceWorkerCache::Init(const base::Closure& callback) { 1219 void ServiceWorkerCache::InitBackend(const base::Closure& callback) {
1205 DCHECK(!initialized_); 1220 DCHECK(backend_state_ == BackendUninitialized);
1206 init_callbacks_.push_back(callback); 1221 init_callbacks_.push_back(callback);
1207 1222
1208 // If this isn't the first call to Init then return as the initialization 1223 // If this isn't the first call to Init then return as the initialization
1209 // has already started. 1224 // has already started.
1210 if (init_callbacks_.size() > 1u) 1225 if (init_callbacks_.size() > 1u)
1211 return; 1226 return;
1212 1227
1213 CreateBackend(base::Bind(&ServiceWorkerCache::InitDone, 1228 CreateBackend(base::Bind(&ServiceWorkerCache::InitDone,
1214 weak_ptr_factory_.GetWeakPtr())); 1229 weak_ptr_factory_.GetWeakPtr()));
1215 } 1230 }
1216 1231
1217 void ServiceWorkerCache::InitDone(ErrorType error) { 1232 void ServiceWorkerCache::InitDone(ErrorType error) {
1218 initialized_ = true; 1233 backend_state_ =
1234 (error == ErrorTypeOK && backend_) ? BackendOpen : BackendClosed;
1219 for (std::vector<base::Closure>::iterator it = init_callbacks_.begin(); 1235 for (std::vector<base::Closure>::iterator it = init_callbacks_.begin();
1220 it != init_callbacks_.end(); 1236 it != init_callbacks_.end();
1221 ++it) { 1237 ++it) {
1222 it->Run(); 1238 it->Run();
1223 } 1239 }
1224 init_callbacks_.clear(); 1240 init_callbacks_.clear();
1225 } 1241 }
1226 1242
1227 void ServiceWorkerCache::DecPendingOps() { 1243 void ServiceWorkerCache::DecPendingOps() {
1228 DCHECK(pending_ops_ > 0); 1244 DCHECK(pending_ops_ > 0);
(...skipping 21 matching lines...) Expand all
1250 1266
1251 void ServiceWorkerCache::PendingRequestsCallback( 1267 void ServiceWorkerCache::PendingRequestsCallback(
1252 const RequestsCallback& callback, 1268 const RequestsCallback& callback,
1253 ErrorType error, 1269 ErrorType error,
1254 scoped_ptr<Requests> requests) { 1270 scoped_ptr<Requests> requests) {
1255 callback.Run(error, requests.Pass()); 1271 callback.Run(error, requests.Pass());
1256 DecPendingOps(); 1272 DecPendingOps();
1257 } 1273 }
1258 1274
1259 } // namespace content 1275 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698