OLD | NEW |
---|---|
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.h" | 5 #include "content/browser/cache_storage/cache_storage.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <set> | 9 #include <set> |
10 #include <string> | 10 #include <string> |
11 #include <unordered_map> | |
11 #include <utility> | 12 #include <utility> |
12 | 13 |
13 #include "base/barrier_closure.h" | 14 #include "base/barrier_closure.h" |
14 #include "base/files/file_util.h" | 15 #include "base/files/file_util.h" |
15 #include "base/files/memory_mapped_file.h" | 16 #include "base/files/memory_mapped_file.h" |
16 #include "base/guid.h" | 17 #include "base/guid.h" |
17 #include "base/location.h" | 18 #include "base/location.h" |
18 #include "base/memory/ptr_util.h" | 19 #include "base/memory/ptr_util.h" |
19 #include "base/memory/ref_counted.h" | 20 #include "base/memory/ref_counted.h" |
20 #include "base/metrics/histogram_macros.h" | 21 #include "base/metrics/histogram_macros.h" |
(...skipping 19 matching lines...) Expand all Loading... | |
40 | 41 |
41 namespace { | 42 namespace { |
42 | 43 |
43 std::string HexedHash(const std::string& value) { | 44 std::string HexedHash(const std::string& value) { |
44 std::string value_hash = base::SHA1HashString(value); | 45 std::string value_hash = base::SHA1HashString(value); |
45 std::string valued_hexed_hash = base::ToLowerASCII( | 46 std::string valued_hexed_hash = base::ToLowerASCII( |
46 base::HexEncode(value_hash.c_str(), value_hash.length())); | 47 base::HexEncode(value_hash.c_str(), value_hash.length())); |
47 return valued_hexed_hash; | 48 return valued_hexed_hash; |
48 } | 49 } |
49 | 50 |
50 void SizeRetrievedFromCache( | |
51 std::unique_ptr<CacheStorageCacheHandle> cache_handle, | |
52 const base::Closure& closure, | |
53 int64_t* accumulator, | |
54 int64_t size) { | |
55 *accumulator += size; | |
56 closure.Run(); | |
57 } | |
58 | |
59 void SizeRetrievedFromAllCaches(std::unique_ptr<int64_t> accumulator, | 51 void SizeRetrievedFromAllCaches(std::unique_ptr<int64_t> accumulator, |
60 const CacheStorage::SizeCallback& callback) { | 52 const CacheStorage::SizeCallback& callback) { |
61 base::ThreadTaskRunnerHandle::Get()->PostTask( | 53 base::ThreadTaskRunnerHandle::Get()->PostTask( |
62 FROM_HERE, base::Bind(callback, *accumulator)); | 54 FROM_HERE, base::Bind(callback, *accumulator)); |
63 } | 55 } |
64 | 56 |
57 void DoNothingWithBool(bool success) {} | |
58 | |
65 } // namespace | 59 } // namespace |
66 | 60 |
67 const char CacheStorage::kIndexFileName[] = "index.txt"; | 61 const char CacheStorage::kIndexFileName[] = "index.txt"; |
62 const int64_t CacheStorage::kSizeUnknown; | |
jkarlin
2016/11/11 18:24:57
Needs to be assigned something
cmumford
2016/11/22 17:45:03
It's initialized in the header, but because kSizeU
| |
68 | 63 |
69 struct CacheStorage::CacheMatchResponse { | 64 struct CacheStorage::CacheMatchResponse { |
70 CacheMatchResponse() = default; | 65 CacheMatchResponse() = default; |
71 ~CacheMatchResponse() = default; | 66 ~CacheMatchResponse() = default; |
72 | 67 |
73 CacheStorageError error; | 68 CacheStorageError error; |
74 std::unique_ptr<ServiceWorkerResponse> service_worker_response; | 69 std::unique_ptr<ServiceWorkerResponse> service_worker_response; |
75 std::unique_ptr<storage::BlobDataHandle> blob_data_handle; | 70 std::unique_ptr<storage::BlobDataHandle> blob_data_handle; |
76 }; | 71 }; |
77 | 72 |
73 class CacheStorage::CacheStorageIndex { | |
74 public: | |
75 CacheStorageIndex(const CacheStorageIndex& other) { | |
76 for (const auto& cache_metadata : other.ordered_cache_metadata_) | |
77 Insert(cache_metadata); | |
78 } | |
79 | |
80 CacheStorageIndex() = default; | |
81 | |
82 ~CacheStorageIndex() = default; | |
83 | |
84 CacheStorageIndex& operator=(CacheStorageIndex&& rhs) { | |
85 ordered_cache_metadata_ = std::move(rhs.ordered_cache_metadata_); | |
86 cache_metadata_map_ = std::move(rhs.cache_metadata_map_); | |
87 storage_size_ = rhs.storage_size_; | |
88 storage_size_dirty_ = rhs.storage_size_dirty_; | |
89 return *this; | |
90 } | |
91 | |
92 void Insert(const CacheMetadata& cache_metadata) { | |
93 DCHECK(cache_metadata_map_.find(cache_metadata.name) == | |
94 cache_metadata_map_.end()); | |
95 ordered_cache_metadata_.push_back(cache_metadata); | |
96 cache_metadata_map_[cache_metadata.name] = --ordered_cache_metadata_.end(); | |
97 storage_size_dirty_ = true; | |
98 } | |
99 | |
100 void Delete(const std::string& cache_name) { | |
101 auto it = cache_metadata_map_.find(cache_name); | |
102 DCHECK(it != cache_metadata_map_.end()); | |
103 ordered_cache_metadata_.erase(it->second); | |
104 cache_metadata_map_.erase(it); | |
105 storage_size_dirty_ = true; | |
106 } | |
107 | |
108 // Sets the cache size. Returns true if the new size is different than the | |
109 // current size else false. | |
110 bool SetCacheSize(const std::string& cache_name, int64_t size) { | |
111 auto it = cache_metadata_map_.find(cache_name); | |
112 if (it == cache_metadata_map_.end()) { | |
113 // Deleted (but still referenced) caches can still run. | |
114 return false; | |
115 } | |
116 if (it->second->size == size) | |
117 return false; | |
118 it->second->size = size; | |
119 storage_size_dirty_ = true; | |
120 return true; | |
121 } | |
122 | |
123 // The cache was modified, increasing/decreasing cache size by |size_delta|. | |
124 void SetCacheSizeModified(const std::string& cache_name, int64_t size_delta) { | |
125 DCHECK_NE(size_delta, 0); | |
126 | |
127 auto it = cache_metadata_map_.find(cache_name); | |
128 if (it == cache_metadata_map_.end()) { | |
129 // Deleted (but still referenced) caches can still run. | |
130 return; | |
131 } | |
132 DCHECK_NE(it->second->size, kSizeUnknown); | |
133 it->second->size += size_delta; | |
134 DCHECK_GE(it->second->size, 0U); | |
135 if (storage_size_dirty_ || storage_size_ == kSizeUnknown) | |
136 return; | |
137 DCHECK_NE(storage_size_, kSizeUnknown); | |
138 storage_size_ += size_delta; | |
139 DCHECK_GE(storage_size_, 0U); | |
140 } | |
141 | |
142 int64_t GetCacheSize(const std::string& cache_name) const { | |
143 const auto& it = cache_metadata_map_.find(cache_name); | |
144 if (it == cache_metadata_map_.end()) | |
145 return kSizeUnknown; | |
146 return it->second->size; | |
147 } | |
148 | |
149 const std::list<CacheMetadata>& ordered_cache_metadata() const { | |
150 return ordered_cache_metadata_; | |
151 } | |
152 | |
153 size_t num_entries() const { return ordered_cache_metadata_.size(); } | |
154 | |
155 int64_t GetStorageSize() { | |
156 if (storage_size_dirty_) | |
157 UpdateStorageSize(); | |
158 return storage_size_; | |
159 } | |
160 | |
161 private: | |
162 void UpdateStorageSize() { | |
163 DCHECK(storage_size_dirty_); | |
164 storage_size_dirty_ = false; | |
165 int64_t storage_size = 0; | |
166 storage_size_ = kSizeUnknown; | |
167 for (const CacheMetadata& info : ordered_cache_metadata_) { | |
168 if (info.size == kSizeUnknown) | |
169 return; | |
170 storage_size += info.size; | |
171 } | |
172 storage_size_ = storage_size; | |
173 } | |
174 // Use a list to keep saved iterators valid during insert/erase. | |
175 // Note: ordered by cache creation. | |
176 std::list<CacheMetadata> ordered_cache_metadata_; | |
177 std::unordered_map<std::string, std::list<CacheMetadata>::iterator> | |
178 cache_metadata_map_; | |
179 | |
180 // The total size of all caches in this store. | |
181 int64_t storage_size_ = CacheStorage::kSizeUnknown; | |
182 bool storage_size_dirty_ = true; | |
183 }; | |
184 | |
78 // Handles the loading and clean up of CacheStorageCache objects. | 185 // Handles the loading and clean up of CacheStorageCache objects. |
79 class CacheStorage::CacheLoader { | 186 class CacheStorage::CacheLoader { |
80 public: | 187 public: |
81 typedef base::Callback<void(std::unique_ptr<CacheStorageCache>)> | 188 typedef base::Callback<void(std::unique_ptr<CacheStorageCache>)> |
82 CacheCallback; | 189 CacheCallback; |
83 typedef base::Callback<void(bool)> BoolCallback; | 190 typedef base::Callback<void(bool)> BoolCallback; |
84 typedef base::Callback<void(std::unique_ptr<std::vector<std::string>>)> | 191 using CacheStorageIndexCallback = |
85 StringVectorCallback; | 192 base::Callback<void(std::unique_ptr<CacheStorageIndex>)>; |
86 | 193 |
87 CacheLoader( | 194 CacheLoader( |
88 base::SequencedTaskRunner* cache_task_runner, | 195 base::SequencedTaskRunner* cache_task_runner, |
89 scoped_refptr<net::URLRequestContextGetter> request_context_getter, | 196 scoped_refptr<net::URLRequestContextGetter> request_context_getter, |
90 storage::QuotaManagerProxy* quota_manager_proxy, | 197 storage::QuotaManagerProxy* quota_manager_proxy, |
91 base::WeakPtr<storage::BlobStorageContext> blob_context, | 198 base::WeakPtr<storage::BlobStorageContext> blob_context, |
92 CacheStorage* cache_storage, | 199 CacheStorage* cache_storage, |
93 const GURL& origin) | 200 const GURL& origin) |
94 : cache_task_runner_(cache_task_runner), | 201 : cache_task_runner_(cache_task_runner), |
95 request_context_getter_(request_context_getter), | 202 request_context_getter_(request_context_getter), |
96 quota_manager_proxy_(quota_manager_proxy), | 203 quota_manager_proxy_(quota_manager_proxy), |
97 blob_context_(blob_context), | 204 blob_context_(blob_context), |
98 cache_storage_(cache_storage), | 205 cache_storage_(cache_storage), |
99 origin_(origin) { | 206 origin_(origin) { |
100 DCHECK(!origin_.is_empty()); | 207 DCHECK(!origin_.is_empty()); |
101 } | 208 } |
102 | 209 |
103 virtual ~CacheLoader() {} | 210 virtual ~CacheLoader() {} |
104 | 211 |
105 // Creates a CacheStorageCache with the given name. It does not attempt to | 212 // Creates a CacheStorageCache with the given name. It does not attempt to |
106 // load the backend, that happens lazily when the cache is used. | 213 // load the backend, that happens lazily when the cache is used. |
107 virtual std::unique_ptr<CacheStorageCache> CreateCache( | 214 virtual std::unique_ptr<CacheStorageCache> CreateCache( |
108 const std::string& cache_name) = 0; | 215 const std::string& cache_name, |
216 int64_t cache_size) = 0; | |
109 | 217 |
110 // Deletes any pre-existing cache of the same name and then loads it. | 218 // Deletes any pre-existing cache of the same name and then loads it. |
111 virtual void PrepareNewCacheDestination(const std::string& cache_name, | 219 virtual void PrepareNewCacheDestination(const std::string& cache_name, |
112 const CacheCallback& callback) = 0; | 220 const CacheCallback& callback) = 0; |
113 | 221 |
114 // After the backend has been deleted, do any extra house keeping such as | 222 // After the backend has been deleted, do any extra house keeping such as |
115 // removing the cache's directory. | 223 // removing the cache's directory. |
116 virtual void CleanUpDeletedCache(CacheStorageCache* cache) = 0; | 224 virtual void CleanUpDeletedCache(CacheStorageCache* cache) = 0; |
117 | 225 |
118 // Writes the cache names (and sizes) to disk if applicable. | 226 // Writes the cache index to disk if applicable. |
119 virtual void WriteIndex(const StringVector& cache_names, | 227 virtual void WriteIndex(const CacheStorageIndex& index, |
120 const BoolCallback& callback) = 0; | 228 const BoolCallback& callback) = 0; |
121 | 229 |
122 // Loads the cache names from disk if applicable. | 230 // Loads the cache index from disk if applicable. |
123 virtual void LoadIndex(std::unique_ptr<std::vector<std::string>> cache_names, | 231 virtual void LoadIndex(const CacheStorageIndexCallback& callback) = 0; |
124 const StringVectorCallback& callback) = 0; | |
125 | 232 |
126 // Called when CacheStorage has created a cache. Used to hold onto a handle to | 233 // Called when CacheStorage has created a cache. Used to hold onto a handle to |
127 // the cache if necessary. | 234 // the cache if necessary. |
128 virtual void NotifyCacheCreated( | 235 virtual void NotifyCacheCreated( |
129 const std::string& cache_name, | 236 const std::string& cache_name, |
130 std::unique_ptr<CacheStorageCacheHandle> cache_handle) {} | 237 std::unique_ptr<CacheStorageCacheHandle> cache_handle) {} |
131 | 238 |
132 // Notification that the cache for |cache_handle| has been doomed. If the | 239 // Notification that the cache for |cache_handle| has been doomed. If the |
133 // loader is holding a handle to the cache, it should drop it now. | 240 // loader is holding a handle to the cache, it should drop it now. |
134 virtual void NotifyCacheDoomed( | 241 virtual void NotifyCacheDoomed( |
(...skipping 26 matching lines...) Expand all Loading... | |
161 base::WeakPtr<storage::BlobStorageContext> blob_context, | 268 base::WeakPtr<storage::BlobStorageContext> blob_context, |
162 CacheStorage* cache_storage, | 269 CacheStorage* cache_storage, |
163 const GURL& origin) | 270 const GURL& origin) |
164 : CacheLoader(cache_task_runner, | 271 : CacheLoader(cache_task_runner, |
165 request_context, | 272 request_context, |
166 quota_manager_proxy, | 273 quota_manager_proxy, |
167 blob_context, | 274 blob_context, |
168 cache_storage, | 275 cache_storage, |
169 origin) {} | 276 origin) {} |
170 | 277 |
171 std::unique_ptr<CacheStorageCache> CreateCache( | 278 std::unique_ptr<CacheStorageCache> CreateCache(const std::string& cache_name, |
172 const std::string& cache_name) override { | 279 int64_t cache_size) override { |
173 return CacheStorageCache::CreateMemoryCache( | 280 return CacheStorageCache::CreateMemoryCache( |
174 origin_, cache_name, cache_storage_, request_context_getter_, | 281 origin_, cache_name, cache_storage_, request_context_getter_, |
175 quota_manager_proxy_, blob_context_); | 282 quota_manager_proxy_, blob_context_); |
176 } | 283 } |
177 | 284 |
178 void PrepareNewCacheDestination(const std::string& cache_name, | 285 void PrepareNewCacheDestination(const std::string& cache_name, |
179 const CacheCallback& callback) override { | 286 const CacheCallback& callback) override { |
180 std::unique_ptr<CacheStorageCache> cache = CreateCache(cache_name); | 287 std::unique_ptr<CacheStorageCache> cache = |
288 CreateCache(cache_name, 0 /*cache_size*/); | |
181 callback.Run(std::move(cache)); | 289 callback.Run(std::move(cache)); |
182 } | 290 } |
183 | 291 |
184 void CleanUpDeletedCache(CacheStorageCache* cache) override {} | 292 void CleanUpDeletedCache(CacheStorageCache* cache) override {} |
185 | 293 |
186 void WriteIndex(const StringVector& cache_names, | 294 void WriteIndex(const CacheStorageIndex& index, |
187 const BoolCallback& callback) override { | 295 const BoolCallback& callback) override { |
188 callback.Run(true); | 296 callback.Run(true); |
189 } | 297 } |
190 | 298 |
191 void LoadIndex(std::unique_ptr<std::vector<std::string>> cache_names, | 299 void LoadIndex(const CacheStorageIndexCallback& callback) override { |
192 const StringVectorCallback& callback) override { | 300 callback.Run(base::MakeUnique<CacheStorageIndex>()); |
193 callback.Run(std::move(cache_names)); | |
194 } | 301 } |
195 | 302 |
196 void NotifyCacheCreated( | 303 void NotifyCacheCreated( |
197 const std::string& cache_name, | 304 const std::string& cache_name, |
198 std::unique_ptr<CacheStorageCacheHandle> cache_handle) override { | 305 std::unique_ptr<CacheStorageCacheHandle> cache_handle) override { |
199 DCHECK(!base::ContainsKey(cache_handles_, cache_name)); | 306 DCHECK(!base::ContainsKey(cache_handles_, cache_name)); |
200 cache_handles_.insert(std::make_pair(cache_name, std::move(cache_handle))); | 307 cache_handles_.insert(std::make_pair(cache_name, std::move(cache_handle))); |
201 }; | 308 }; |
202 | 309 |
203 void NotifyCacheDoomed( | 310 void NotifyCacheDoomed( |
(...skipping 25 matching lines...) Expand all Loading... | |
229 const GURL& origin) | 336 const GURL& origin) |
230 : CacheLoader(cache_task_runner, | 337 : CacheLoader(cache_task_runner, |
231 request_context, | 338 request_context, |
232 quota_manager_proxy, | 339 quota_manager_proxy, |
233 blob_context, | 340 blob_context, |
234 cache_storage, | 341 cache_storage, |
235 origin), | 342 origin), |
236 origin_path_(origin_path), | 343 origin_path_(origin_path), |
237 weak_ptr_factory_(this) {} | 344 weak_ptr_factory_(this) {} |
238 | 345 |
239 std::unique_ptr<CacheStorageCache> CreateCache( | 346 std::unique_ptr<CacheStorageCache> CreateCache(const std::string& cache_name, |
240 const std::string& cache_name) override { | 347 int64_t cache_size) override { |
241 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 348 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
242 DCHECK(base::ContainsKey(cache_name_to_cache_dir_, cache_name)); | 349 DCHECK(base::ContainsKey(cache_name_to_cache_dir_, cache_name)); |
243 | 350 |
244 std::string cache_dir = cache_name_to_cache_dir_[cache_name]; | 351 std::string cache_dir = cache_name_to_cache_dir_[cache_name]; |
245 base::FilePath cache_path = origin_path_.AppendASCII(cache_dir); | 352 base::FilePath cache_path = origin_path_.AppendASCII(cache_dir); |
246 return CacheStorageCache::CreatePersistentCache( | 353 return CacheStorageCache::CreatePersistentCache( |
247 origin_, cache_name, cache_storage_, cache_path, | 354 origin_, cache_name, cache_storage_, cache_path, |
248 request_context_getter_, quota_manager_proxy_, blob_context_); | 355 request_context_getter_, quota_manager_proxy_, blob_context_, |
356 cache_size); | |
249 } | 357 } |
250 | 358 |
251 void PrepareNewCacheDestination(const std::string& cache_name, | 359 void PrepareNewCacheDestination(const std::string& cache_name, |
252 const CacheCallback& callback) override { | 360 const CacheCallback& callback) override { |
253 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 361 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
254 | 362 |
255 PostTaskAndReplyWithResult( | 363 PostTaskAndReplyWithResult( |
256 cache_task_runner_.get(), FROM_HERE, | 364 cache_task_runner_.get(), FROM_HERE, |
257 base::Bind(&SimpleCacheLoader::PrepareNewCacheDirectoryInPool, | 365 base::Bind(&SimpleCacheLoader::PrepareNewCacheDirectoryInPool, |
258 origin_path_), | 366 origin_path_), |
(...skipping 16 matching lines...) Expand all Loading... | |
275 | 383 |
276 void PrepareNewCacheCreateCache(const std::string& cache_name, | 384 void PrepareNewCacheCreateCache(const std::string& cache_name, |
277 const CacheCallback& callback, | 385 const CacheCallback& callback, |
278 const std::string& cache_dir) { | 386 const std::string& cache_dir) { |
279 if (cache_dir.empty()) { | 387 if (cache_dir.empty()) { |
280 callback.Run(std::unique_ptr<CacheStorageCache>()); | 388 callback.Run(std::unique_ptr<CacheStorageCache>()); |
281 return; | 389 return; |
282 } | 390 } |
283 | 391 |
284 cache_name_to_cache_dir_[cache_name] = cache_dir; | 392 cache_name_to_cache_dir_[cache_name] = cache_dir; |
285 callback.Run(CreateCache(cache_name)); | 393 callback.Run(CreateCache(cache_name, CacheStorage::kSizeUnknown)); |
286 } | 394 } |
287 | 395 |
288 void CleanUpDeletedCache(CacheStorageCache* cache) override { | 396 void CleanUpDeletedCache(CacheStorageCache* cache) override { |
289 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 397 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
290 DCHECK(base::ContainsKey(doomed_cache_to_path_, cache)); | 398 DCHECK(base::ContainsKey(doomed_cache_to_path_, cache)); |
291 | 399 |
292 base::FilePath cache_path = | 400 base::FilePath cache_path = |
293 origin_path_.AppendASCII(doomed_cache_to_path_[cache]); | 401 origin_path_.AppendASCII(doomed_cache_to_path_[cache]); |
294 doomed_cache_to_path_.erase(cache); | 402 doomed_cache_to_path_.erase(cache); |
295 | 403 |
296 cache_task_runner_->PostTask( | 404 cache_task_runner_->PostTask( |
297 FROM_HERE, base::Bind(&SimpleCacheLoader::CleanUpDeleteCacheDirInPool, | 405 FROM_HERE, base::Bind(&SimpleCacheLoader::CleanUpDeleteCacheDirInPool, |
298 cache_path)); | 406 cache_path)); |
299 } | 407 } |
300 | 408 |
301 static void CleanUpDeleteCacheDirInPool(const base::FilePath& cache_path) { | 409 static void CleanUpDeleteCacheDirInPool(const base::FilePath& cache_path) { |
302 base::DeleteFile(cache_path, true /* recursive */); | 410 base::DeleteFile(cache_path, true /* recursive */); |
303 } | 411 } |
304 | 412 |
305 void WriteIndex(const StringVector& cache_names, | 413 void WriteIndex(const CacheStorageIndex& index, |
306 const BoolCallback& callback) override { | 414 const BoolCallback& callback) override { |
307 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 415 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
308 | 416 |
309 // 1. Create the index file as a string. (WriteIndex) | 417 // 1. Create the index file as a string. (WriteIndex) |
310 // 2. Write the file to disk. (WriteIndexWriteToFileInPool) | 418 // 2. Write the file to disk. (WriteIndexWriteToFileInPool) |
311 | 419 |
312 CacheStorageIndex index; | 420 content::CacheStorageIndex pb_index; |
jkarlin
2016/11/11 18:24:56
better to write it out, protobuf_index or proto_in
cmumford
2016/11/22 17:45:03
Done. I went with proto_index.
| |
313 index.set_origin(origin_.spec()); | 421 pb_index.set_origin(origin_.spec()); |
314 | 422 |
315 for (size_t i = 0u, max = cache_names.size(); i < max; ++i) { | 423 for (const auto& cache_metadata : index.ordered_cache_metadata()) { |
316 DCHECK(base::ContainsKey(cache_name_to_cache_dir_, cache_names[i])); | 424 DCHECK(base::ContainsKey(cache_name_to_cache_dir_, cache_metadata.name)); |
317 | 425 |
318 CacheStorageIndex::Cache* index_cache = index.add_cache(); | 426 content::CacheStorageIndex::Cache* index_cache = pb_index.add_cache(); |
319 index_cache->set_name(cache_names[i]); | 427 index_cache->set_name(cache_metadata.name); |
320 index_cache->set_cache_dir(cache_name_to_cache_dir_[cache_names[i]]); | 428 index_cache->set_cache_dir(cache_name_to_cache_dir_[cache_metadata.name]); |
429 if (cache_metadata.size == CacheStorage::kSizeUnknown) | |
430 index_cache->clear_size(); | |
431 else | |
432 index_cache->set_size(cache_metadata.size); | |
321 } | 433 } |
322 | 434 |
323 std::string serialized; | 435 std::string serialized; |
324 bool success = index.SerializeToString(&serialized); | 436 bool success = pb_index.SerializeToString(&serialized); |
325 DCHECK(success); | 437 DCHECK(success); |
326 | 438 |
327 base::FilePath tmp_path = origin_path_.AppendASCII("index.txt.tmp"); | 439 base::FilePath tmp_path = origin_path_.AppendASCII("index.txt.tmp"); |
328 base::FilePath index_path = | 440 base::FilePath index_path = |
329 origin_path_.AppendASCII(CacheStorage::kIndexFileName); | 441 origin_path_.AppendASCII(CacheStorage::kIndexFileName); |
330 | 442 |
331 PostTaskAndReplyWithResult( | 443 PostTaskAndReplyWithResult( |
332 cache_task_runner_.get(), FROM_HERE, | 444 cache_task_runner_.get(), FROM_HERE, |
333 base::Bind(&SimpleCacheLoader::WriteIndexWriteToFileInPool, tmp_path, | 445 base::Bind(&SimpleCacheLoader::WriteIndexWriteToFileInPool, tmp_path, |
334 index_path, serialized), | 446 index_path, serialized), |
335 callback); | 447 callback); |
336 } | 448 } |
337 | 449 |
338 static bool WriteIndexWriteToFileInPool(const base::FilePath& tmp_path, | 450 static bool WriteIndexWriteToFileInPool(const base::FilePath& tmp_path, |
339 const base::FilePath& index_path, | 451 const base::FilePath& index_path, |
340 const std::string& data) { | 452 const std::string& data) { |
341 int bytes_written = base::WriteFile(tmp_path, data.c_str(), data.size()); | 453 int bytes_written = base::WriteFile(tmp_path, data.c_str(), data.size()); |
342 if (bytes_written != base::checked_cast<int>(data.size())) { | 454 if (bytes_written != base::checked_cast<int>(data.size())) { |
343 base::DeleteFile(tmp_path, /* recursive */ false); | 455 base::DeleteFile(tmp_path, /* recursive */ false); |
344 return false; | 456 return false; |
345 } | 457 } |
346 | 458 |
347 // Atomically rename the temporary index file to become the real one. | 459 // Atomically rename the temporary index file to become the real one. |
348 return base::ReplaceFile(tmp_path, index_path, NULL); | 460 return base::ReplaceFile(tmp_path, index_path, NULL); |
349 } | 461 } |
350 | 462 |
351 void LoadIndex(std::unique_ptr<std::vector<std::string>> names, | 463 void LoadIndex(const CacheStorageIndexCallback& callback) override { |
352 const StringVectorCallback& callback) override { | |
353 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 464 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
354 | 465 |
355 // 1. Read the file from disk. (LoadIndexReadFileInPool) | |
356 // 2. Parse file and return the names of the caches (LoadIndexDidReadFile) | |
357 | |
358 base::FilePath index_path = | |
359 origin_path_.AppendASCII(CacheStorage::kIndexFileName); | |
360 | |
361 PostTaskAndReplyWithResult( | 466 PostTaskAndReplyWithResult( |
362 cache_task_runner_.get(), FROM_HERE, | 467 cache_task_runner_.get(), FROM_HERE, |
363 base::Bind(&SimpleCacheLoader::ReadAndMigrateIndexInPool, index_path), | 468 base::Bind(&SimpleCacheLoader::ReadAndMigrateIndexInPool, origin_path_), |
364 base::Bind(&SimpleCacheLoader::LoadIndexDidReadFile, | 469 base::Bind(&SimpleCacheLoader::LoadIndexDidReadIndex, |
365 weak_ptr_factory_.GetWeakPtr(), base::Passed(&names), | 470 weak_ptr_factory_.GetWeakPtr(), callback)); |
366 callback)); | |
367 } | 471 } |
368 | 472 |
369 void LoadIndexDidReadFile(std::unique_ptr<std::vector<std::string>> names, | 473 void LoadIndexDidReadIndex(const CacheStorageIndexCallback& callback, |
370 const StringVectorCallback& callback, | 474 content::CacheStorageIndex pb_index) { |
371 const std::string& serialized) { | |
372 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 475 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
373 | 476 |
374 std::unique_ptr<std::set<std::string>> cache_dirs( | 477 std::unique_ptr<std::set<std::string>> cache_dirs( |
375 new std::set<std::string>); | 478 new std::set<std::string>); |
376 | 479 |
377 CacheStorageIndex index; | 480 auto index = base::MakeUnique<CacheStorageIndex>(); |
378 if (index.ParseFromString(serialized)) { | 481 for (int i = 0, max = pb_index.cache_size(); i < max; ++i) { |
379 for (int i = 0, max = index.cache_size(); i < max; ++i) { | 482 const content::CacheStorageIndex::Cache& cache = pb_index.cache(i); |
380 const CacheStorageIndex::Cache& cache = index.cache(i); | 483 DCHECK(cache.has_cache_dir()); |
381 DCHECK(cache.has_cache_dir()); | 484 int64_t cache_size = |
382 names->push_back(cache.name()); | 485 cache.has_size() ? cache.size() : CacheStorage::kSizeUnknown; |
383 cache_name_to_cache_dir_[cache.name()] = cache.cache_dir(); | 486 index->Insert(CacheMetadata(cache.name(), cache_size)); |
384 cache_dirs->insert(cache.cache_dir()); | 487 cache_name_to_cache_dir_[cache.name()] = cache.cache_dir(); |
385 } | 488 cache_dirs->insert(cache.cache_dir()); |
386 } | 489 } |
387 | 490 |
388 cache_task_runner_->PostTask( | 491 cache_task_runner_->PostTask( |
389 FROM_HERE, base::Bind(&DeleteUnreferencedCachesInPool, origin_path_, | 492 FROM_HERE, base::Bind(&DeleteUnreferencedCachesInPool, origin_path_, |
390 base::Passed(&cache_dirs))); | 493 base::Passed(&cache_dirs))); |
391 callback.Run(std::move(names)); | 494 callback.Run(std::move(index)); |
392 } | 495 } |
393 | 496 |
394 void NotifyCacheDoomed( | 497 void NotifyCacheDoomed( |
395 std::unique_ptr<CacheStorageCacheHandle> cache_handle) override { | 498 std::unique_ptr<CacheStorageCacheHandle> cache_handle) override { |
396 DCHECK(base::ContainsKey(cache_name_to_cache_dir_, | 499 DCHECK(base::ContainsKey(cache_name_to_cache_dir_, |
397 cache_handle->value()->cache_name())); | 500 cache_handle->value()->cache_name())); |
398 auto iter = | 501 auto iter = |
399 cache_name_to_cache_dir_.find(cache_handle->value()->cache_name()); | 502 cache_name_to_cache_dir_.find(cache_handle->value()->cache_name()); |
400 doomed_cache_to_path_[cache_handle->value()] = iter->second; | 503 doomed_cache_to_path_[cache_handle->value()] = iter->second; |
401 cache_name_to_cache_dir_.erase(iter); | 504 cache_name_to_cache_dir_.erase(iter); |
(...skipping 15 matching lines...) Expand all Loading... | |
417 while (!(cache_path = file_enum.Next()).empty()) { | 520 while (!(cache_path = file_enum.Next()).empty()) { |
418 if (!base::ContainsKey(*cache_dirs, cache_path.BaseName().AsUTF8Unsafe())) | 521 if (!base::ContainsKey(*cache_dirs, cache_path.BaseName().AsUTF8Unsafe())) |
419 dirs_to_delete.push_back(cache_path); | 522 dirs_to_delete.push_back(cache_path); |
420 } | 523 } |
421 | 524 |
422 for (const base::FilePath& cache_path : dirs_to_delete) | 525 for (const base::FilePath& cache_path : dirs_to_delete) |
423 base::DeleteFile(cache_path, true /* recursive */); | 526 base::DeleteFile(cache_path, true /* recursive */); |
424 } | 527 } |
425 | 528 |
426 // Runs on cache_task_runner_ | 529 // Runs on cache_task_runner_ |
427 static std::string MigrateCachesIfNecessaryInPool( | 530 static content::CacheStorageIndex ReadAndMigrateIndexInPool( |
428 const std::string& body, | 531 const base::FilePath& origin_path) { |
429 const base::FilePath& index_path) { | 532 const base::FilePath index_path = |
430 CacheStorageIndex index; | 533 origin_path.AppendASCII(CacheStorage::kIndexFileName); |
431 if (!index.ParseFromString(body)) | |
432 return body; | |
433 | 534 |
434 base::FilePath origin_path = index_path.DirName(); | 535 content::CacheStorageIndex index; |
435 bool index_is_dirty = false; | 536 std::string body; |
436 const std::string kBadIndexState(""); | 537 if (!base::ReadFileToString(index_path, &body) || |
538 !index.ParseFromString(body)) | |
539 return content::CacheStorageIndex(); | |
540 body.clear(); | |
541 | |
542 base::File::Info file_info; | |
543 base::Time index_last_modified; | |
544 if (GetFileInfo(index_path, &file_info)) | |
545 index_last_modified = file_info.last_modified; | |
546 bool index_modified = false; | |
437 | 547 |
438 // Look for caches that have no cache_dir. Give any such caches a directory | 548 // Look for caches that have no cache_dir. Give any such caches a directory |
439 // with a random name and move them there. Then, rewrite the index file. | 549 // with a random name and move them there. Then, rewrite the index file. |
jkarlin
2016/11/11 18:24:56
Need to update this comment.
cmumford
2016/11/22 17:45:03
Done.
| |
440 for (int i = 0, max = index.cache_size(); i < max; ++i) { | 550 for (int i = 0, max = index.cache_size(); i < max; ++i) { |
441 const CacheStorageIndex::Cache& cache = index.cache(i); | 551 const content::CacheStorageIndex::Cache& cache = index.cache(i); |
442 if (!cache.has_cache_dir()) { | 552 if (cache.has_cache_dir()) { |
553 if (cache.has_size()) { | |
554 base::FilePath cache_dir = origin_path.AppendASCII(cache.cache_dir()); | |
555 if (!GetFileInfo(cache_dir, &file_info) || | |
556 index_last_modified <= file_info.last_modified) { | |
jkarlin
2016/11/11 18:24:56
So we need to guarantee that the backend (SimpleCa
cmumford
2016/11/22 17:45:03
Comment added to ScheduleWriteIndex.
| |
557 // Index is older than this cache, so invalidate index entries that | |
558 // may change as a result of cache operations. | |
559 index.mutable_cache(i)->clear_size(); | |
560 index_modified = true; | |
jkarlin
2016/11/11 18:24:56
Why do we need to write this back to disk?
cmumford
2016/11/22 17:45:03
Good point - clearing the size is sufficient.
| |
561 } | |
562 } | |
563 } else { | |
443 // Find a new home for the cache. | 564 // Find a new home for the cache. |
444 base::FilePath legacy_cache_path = | 565 base::FilePath legacy_cache_path = |
445 origin_path.AppendASCII(HexedHash(cache.name())); | 566 origin_path.AppendASCII(HexedHash(cache.name())); |
446 std::string cache_dir; | 567 std::string cache_dir; |
447 base::FilePath cache_path; | 568 base::FilePath cache_path; |
448 do { | 569 do { |
449 cache_dir = base::GenerateGUID(); | 570 cache_dir = base::GenerateGUID(); |
450 cache_path = origin_path.AppendASCII(cache_dir); | 571 cache_path = origin_path.AppendASCII(cache_dir); |
451 } while (base::PathExists(cache_path)); | 572 } while (base::PathExists(cache_path)); |
452 | 573 |
453 if (!base::Move(legacy_cache_path, cache_path)) { | 574 if (!base::Move(legacy_cache_path, cache_path)) { |
454 // If the move fails then the cache is in a bad state. Return an empty | 575 // If the move fails then the cache is in a bad state. Return an empty |
455 // index so that the CacheStorage can start fresh. The unreferenced | 576 // index so that the CacheStorage can start fresh. The unreferenced |
456 // caches will be discarded later in initialization. | 577 // caches will be discarded later in initialization. |
457 return kBadIndexState; | 578 return content::CacheStorageIndex(); |
458 } | 579 } |
459 | 580 |
460 index.mutable_cache(i)->set_cache_dir(cache_dir); | 581 index.mutable_cache(i)->set_cache_dir(cache_dir); |
461 index_is_dirty = true; | 582 index.mutable_cache(i)->clear_size(); |
583 index_modified = true; | |
462 } | 584 } |
463 } | 585 } |
464 | 586 |
465 if (index_is_dirty) { | 587 if (index_modified) { |
466 std::string new_body; | 588 if (!index.SerializeToString(&body)) |
467 if (!index.SerializeToString(&new_body)) | 589 return content::CacheStorageIndex(); |
468 return kBadIndexState; | 590 if (base::WriteFile(index_path, body.c_str(), body.size()) != |
469 if (base::WriteFile(index_path, new_body.c_str(), new_body.size()) != | 591 base::checked_cast<int>(body.size())) |
470 base::checked_cast<int>(new_body.size())) | 592 return content::CacheStorageIndex(); |
471 return kBadIndexState; | |
472 return new_body; | |
473 } | 593 } |
474 | 594 |
475 return body; | 595 return index; |
476 } | |
477 | |
478 // Runs on cache_task_runner_ | |
479 static std::string ReadAndMigrateIndexInPool( | |
480 const base::FilePath& index_path) { | |
481 std::string body; | |
482 base::ReadFileToString(index_path, &body); | |
483 | |
484 return MigrateCachesIfNecessaryInPool(body, index_path); | |
485 } | 596 } |
486 | 597 |
487 const base::FilePath origin_path_; | 598 const base::FilePath origin_path_; |
488 std::map<std::string, std::string> cache_name_to_cache_dir_; | 599 std::map<std::string, std::string> cache_name_to_cache_dir_; |
489 std::map<CacheStorageCache*, std::string> doomed_cache_to_path_; | 600 std::map<CacheStorageCache*, std::string> doomed_cache_to_path_; |
490 | 601 |
491 base::WeakPtrFactory<SimpleCacheLoader> weak_ptr_factory_; | 602 base::WeakPtrFactory<SimpleCacheLoader> weak_ptr_factory_; |
492 }; | 603 }; |
493 | 604 |
494 CacheStorage::CacheStorage( | 605 CacheStorage::CacheStorage( |
495 const base::FilePath& path, | 606 const base::FilePath& path, |
496 bool memory_only, | 607 bool memory_only, |
497 base::SequencedTaskRunner* cache_task_runner, | 608 base::SequencedTaskRunner* cache_task_runner, |
498 scoped_refptr<net::URLRequestContextGetter> request_context, | 609 scoped_refptr<net::URLRequestContextGetter> request_context, |
499 scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy, | 610 scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy, |
500 base::WeakPtr<storage::BlobStorageContext> blob_context, | 611 base::WeakPtr<storage::BlobStorageContext> blob_context, |
501 const GURL& origin) | 612 const GURL& origin) |
502 : initialized_(false), | 613 : initialized_(false), |
503 initializing_(false), | 614 initializing_(false), |
504 memory_only_(memory_only), | 615 memory_only_(memory_only), |
505 scheduler_(new CacheStorageScheduler( | 616 scheduler_(new CacheStorageScheduler( |
506 CacheStorageSchedulerClient::CLIENT_STORAGE)), | 617 CacheStorageSchedulerClient::CLIENT_STORAGE)), |
618 index_(base::MakeUnique<CacheStorageIndex>()), | |
507 origin_path_(path), | 619 origin_path_(path), |
508 cache_task_runner_(cache_task_runner), | 620 cache_task_runner_(cache_task_runner), |
509 quota_manager_proxy_(quota_manager_proxy), | 621 quota_manager_proxy_(quota_manager_proxy), |
510 origin_(origin), | 622 origin_(origin), |
511 weak_factory_(this) { | 623 weak_factory_(this) { |
512 if (memory_only) | 624 if (memory_only) |
513 cache_loader_.reset(new MemoryLoader( | 625 cache_loader_.reset(new MemoryLoader( |
514 cache_task_runner_.get(), std::move(request_context), | 626 cache_task_runner_.get(), std::move(request_context), |
515 quota_manager_proxy.get(), blob_context, this, origin)); | 627 quota_manager_proxy.get(), blob_context, this, origin)); |
516 else | 628 else |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
563 | 675 |
564 quota_manager_proxy_->NotifyStorageAccessed( | 676 quota_manager_proxy_->NotifyStorageAccessed( |
565 storage::QuotaClient::kServiceWorkerCache, origin_, | 677 storage::QuotaClient::kServiceWorkerCache, origin_, |
566 storage::kStorageTypeTemporary); | 678 storage::kStorageTypeTemporary); |
567 | 679 |
568 scheduler_->ScheduleOperation( | 680 scheduler_->ScheduleOperation( |
569 base::Bind(&CacheStorage::DeleteCacheImpl, weak_factory_.GetWeakPtr(), | 681 base::Bind(&CacheStorage::DeleteCacheImpl, weak_factory_.GetWeakPtr(), |
570 cache_name, scheduler_->WrapCallbackToRunNext(callback))); | 682 cache_name, scheduler_->WrapCallbackToRunNext(callback))); |
571 } | 683 } |
572 | 684 |
573 void CacheStorage::EnumerateCaches(const StringsCallback& callback) { | 685 void CacheStorage::EnumerateCaches(const CacheMetadataCallback& callback) { |
574 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 686 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
575 | 687 |
576 if (!initialized_) | 688 if (!initialized_) |
577 LazyInit(); | 689 LazyInit(); |
578 | 690 |
579 quota_manager_proxy_->NotifyStorageAccessed( | 691 quota_manager_proxy_->NotifyStorageAccessed( |
580 storage::QuotaClient::kServiceWorkerCache, origin_, | 692 storage::QuotaClient::kServiceWorkerCache, origin_, |
581 storage::kStorageTypeTemporary); | 693 storage::kStorageTypeTemporary); |
582 | 694 |
583 scheduler_->ScheduleOperation( | 695 scheduler_->ScheduleOperation( |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
639 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 751 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
640 | 752 |
641 if (!initialized_) | 753 if (!initialized_) |
642 LazyInit(); | 754 LazyInit(); |
643 | 755 |
644 scheduler_->ScheduleOperation( | 756 scheduler_->ScheduleOperation( |
645 base::Bind(&CacheStorage::SizeImpl, weak_factory_.GetWeakPtr(), | 757 base::Bind(&CacheStorage::SizeImpl, weak_factory_.GetWeakPtr(), |
646 scheduler_->WrapCallbackToRunNext(callback))); | 758 scheduler_->WrapCallbackToRunNext(callback))); |
647 } | 759 } |
648 | 760 |
761 void CacheStorage::ScheduleWriteIndex() { | |
762 // TODO(cmumford): Write in a lazy fashion to minimize writes. | |
763 cache_loader_->WriteIndex(*index_, base::Bind(&DoNothingWithBool)); | |
764 } | |
765 | |
766 void CacheStorage::CacheSizeSet(const CacheStorageCache* cache, | |
767 Whence whence, | |
768 int64_t size) { | |
769 switch (whence) { | |
770 case Whence::SET: | |
771 index_->SetCacheSize(cache->cache_name(), size); | |
772 break; | |
773 case Whence::DELTA: | |
774 if (!size) | |
775 return; | |
776 index_->SetCacheSizeModified(cache->cache_name(), size); | |
777 break; | |
778 } | |
779 ScheduleWriteIndex(); | |
780 } | |
781 | |
649 void CacheStorage::StartAsyncOperationForTesting() { | 782 void CacheStorage::StartAsyncOperationForTesting() { |
650 scheduler_->ScheduleOperation(base::Bind(&base::DoNothing)); | 783 scheduler_->ScheduleOperation(base::Bind(&base::DoNothing)); |
651 } | 784 } |
652 | 785 |
653 void CacheStorage::CompleteAsyncOperationForTesting() { | 786 void CacheStorage::CompleteAsyncOperationForTesting() { |
654 scheduler_->CompleteOperationAndRunNext(); | 787 scheduler_->CompleteOperationAndRunNext(); |
655 } | 788 } |
656 | 789 |
657 // Init is run lazily so that it is called on the proper MessageLoop. | 790 // Init is run lazily so that it is called on the proper MessageLoop. |
658 void CacheStorage::LazyInit() { | 791 void CacheStorage::LazyInit() { |
659 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 792 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
660 DCHECK(!initialized_); | 793 DCHECK(!initialized_); |
661 | 794 |
662 if (initializing_) | 795 if (initializing_) |
663 return; | 796 return; |
664 | 797 |
665 DCHECK(!scheduler_->ScheduledOperations()); | 798 DCHECK(!scheduler_->ScheduledOperations()); |
666 | 799 |
667 initializing_ = true; | 800 initializing_ = true; |
668 scheduler_->ScheduleOperation( | 801 scheduler_->ScheduleOperation( |
669 base::Bind(&CacheStorage::LazyInitImpl, weak_factory_.GetWeakPtr())); | 802 base::Bind(&CacheStorage::LazyInitImpl, weak_factory_.GetWeakPtr())); |
670 } | 803 } |
671 | 804 |
672 void CacheStorage::LazyInitImpl() { | 805 void CacheStorage::LazyInitImpl() { |
673 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 806 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
674 DCHECK(!initialized_); | 807 DCHECK(!initialized_); |
675 DCHECK(initializing_); | 808 DCHECK(initializing_); |
676 | 809 |
677 // 1. Get the list of cache names (async call) | 810 // 1. Get the cache index (async call) |
678 // 2. For each cache name, load the cache (async call) | 811 // 2. For each cache name, load the cache (async call) |
679 // 3. Once each load is complete, update the map variables. | 812 // 3. Once each load is complete, update the map variables. |
680 // 4. Call the list of waiting callbacks. | 813 // 4. Call the list of waiting callbacks. |
681 | 814 |
682 std::unique_ptr<std::vector<std::string>> indexed_cache_names( | 815 cache_loader_->LoadIndex(base::Bind(&CacheStorage::LazyInitDidLoadIndex, |
683 new std::vector<std::string>()); | |
684 | |
685 cache_loader_->LoadIndex(std::move(indexed_cache_names), | |
686 base::Bind(&CacheStorage::LazyInitDidLoadIndex, | |
687 weak_factory_.GetWeakPtr())); | 816 weak_factory_.GetWeakPtr())); |
688 } | 817 } |
689 | 818 |
690 void CacheStorage::LazyInitDidLoadIndex( | 819 void CacheStorage::LazyInitDidLoadIndex( |
691 std::unique_ptr<std::vector<std::string>> indexed_cache_names) { | 820 std::unique_ptr<CacheStorageIndex> index) { |
692 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 821 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
693 | 822 |
694 for (size_t i = 0u, max = indexed_cache_names->size(); i < max; ++i) { | 823 DCHECK(cache_map_.empty()); |
jkarlin
2016/11/11 18:24:56
Move this up a line with the other DCHECK
cmumford
2016/11/22 17:45:03
Done.
| |
695 cache_map_.insert(std::make_pair(indexed_cache_names->at(i), | 824 for (const auto& cache_metadata : index->ordered_cache_metadata()) { |
825 cache_map_.insert(std::make_pair(cache_metadata.name, | |
696 std::unique_ptr<CacheStorageCache>())); | 826 std::unique_ptr<CacheStorageCache>())); |
697 ordered_cache_names_.push_back(indexed_cache_names->at(i)); | |
698 } | 827 } |
699 | 828 |
829 index_.swap(index); | |
830 | |
700 initializing_ = false; | 831 initializing_ = false; |
701 initialized_ = true; | 832 initialized_ = true; |
702 | 833 |
703 scheduler_->CompleteOperationAndRunNext(); | 834 scheduler_->CompleteOperationAndRunNext(); |
704 } | 835 } |
705 | 836 |
706 void CacheStorage::OpenCacheImpl(const std::string& cache_name, | 837 void CacheStorage::OpenCacheImpl(const std::string& cache_name, |
707 const CacheAndErrorCallback& callback) { | 838 const CacheAndErrorCallback& callback) { |
708 std::unique_ptr<CacheStorageCacheHandle> cache_handle = | 839 std::unique_ptr<CacheStorageCacheHandle> cache_handle = |
709 GetLoadedCache(cache_name); | 840 GetLoadedCache(cache_name); |
(...skipping 18 matching lines...) Expand all Loading... | |
728 | 859 |
729 if (!cache) { | 860 if (!cache) { |
730 callback.Run(std::unique_ptr<CacheStorageCacheHandle>(), | 861 callback.Run(std::unique_ptr<CacheStorageCacheHandle>(), |
731 CACHE_STORAGE_ERROR_STORAGE); | 862 CACHE_STORAGE_ERROR_STORAGE); |
732 return; | 863 return; |
733 } | 864 } |
734 | 865 |
735 CacheStorageCache* cache_ptr = cache.get(); | 866 CacheStorageCache* cache_ptr = cache.get(); |
736 | 867 |
737 cache_map_.insert(std::make_pair(cache_name, std::move(cache))); | 868 cache_map_.insert(std::make_pair(cache_name, std::move(cache))); |
738 ordered_cache_names_.push_back(cache_name); | 869 index_->Insert(CacheMetadata(cache_name, cache_ptr->cache_size())); |
739 | 870 |
740 cache_loader_->WriteIndex( | 871 cache_loader_->WriteIndex( |
741 ordered_cache_names_, | 872 *index_, base::Bind(&CacheStorage::CreateCacheDidWriteIndex, |
742 base::Bind(&CacheStorage::CreateCacheDidWriteIndex, | 873 weak_factory_.GetWeakPtr(), callback, |
743 weak_factory_.GetWeakPtr(), callback, | 874 base::Passed(CreateCacheHandle(cache_ptr)))); |
744 base::Passed(CreateCacheHandle(cache_ptr)))); | |
745 | 875 |
746 cache_loader_->NotifyCacheCreated(cache_name, CreateCacheHandle(cache_ptr)); | 876 cache_loader_->NotifyCacheCreated(cache_name, CreateCacheHandle(cache_ptr)); |
747 } | 877 } |
748 | 878 |
749 void CacheStorage::CreateCacheDidWriteIndex( | 879 void CacheStorage::CreateCacheDidWriteIndex( |
750 const CacheAndErrorCallback& callback, | 880 const CacheAndErrorCallback& callback, |
751 std::unique_ptr<CacheStorageCacheHandle> cache_handle, | 881 std::unique_ptr<CacheStorageCacheHandle> cache_handle, |
752 bool success) { | 882 bool success) { |
753 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 883 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
754 DCHECK(cache_handle); | 884 DCHECK(cache_handle); |
(...skipping 10 matching lines...) Expand all Loading... | |
765 } | 895 } |
766 | 896 |
767 void CacheStorage::DeleteCacheImpl(const std::string& cache_name, | 897 void CacheStorage::DeleteCacheImpl(const std::string& cache_name, |
768 const BoolAndErrorCallback& callback) { | 898 const BoolAndErrorCallback& callback) { |
769 if (!GetLoadedCache(cache_name)) { | 899 if (!GetLoadedCache(cache_name)) { |
770 base::ThreadTaskRunnerHandle::Get()->PostTask( | 900 base::ThreadTaskRunnerHandle::Get()->PostTask( |
771 FROM_HERE, base::Bind(callback, false, CACHE_STORAGE_ERROR_NOT_FOUND)); | 901 FROM_HERE, base::Bind(callback, false, CACHE_STORAGE_ERROR_NOT_FOUND)); |
772 return; | 902 return; |
773 } | 903 } |
774 | 904 |
775 // Delete the name from ordered_cache_names_. | 905 // Save the current index so that it can be restored if the write fails. |
776 StringVector original_ordered_cache_names = ordered_cache_names_; | 906 // TODO(cmumford): Avoid creating a copy, and make CacheStorageCacheIndex |
777 StringVector::iterator iter = std::find( | 907 // DISALLOW_COPY_AND_ASSIGN. |
778 ordered_cache_names_.begin(), ordered_cache_names_.end(), cache_name); | 908 auto prior_index = base::MakeUnique<CacheStorageIndex>(*index_); |
779 DCHECK(iter != ordered_cache_names_.end()); | 909 index_->Delete(cache_name); |
780 ordered_cache_names_.erase(iter); | |
781 | 910 |
782 cache_loader_->WriteIndex(ordered_cache_names_, | 911 cache_loader_->WriteIndex( |
783 base::Bind(&CacheStorage::DeleteCacheDidWriteIndex, | 912 *index_, base::Bind(&CacheStorage::DeleteCacheDidWriteIndex, |
784 weak_factory_.GetWeakPtr(), cache_name, | 913 weak_factory_.GetWeakPtr(), cache_name, |
785 original_ordered_cache_names, callback)); | 914 base::Passed(std::move(prior_index)), callback)); |
786 } | 915 } |
787 | 916 |
788 void CacheStorage::DeleteCacheDidWriteIndex( | 917 void CacheStorage::DeleteCacheDidWriteIndex( |
789 const std::string& cache_name, | 918 const std::string& cache_name, |
790 const StringVector& original_ordered_cache_names, | 919 std::unique_ptr<CacheStorageIndex> index_before_delete, |
791 const BoolAndErrorCallback& callback, | 920 const BoolAndErrorCallback& callback, |
792 bool success) { | 921 bool success) { |
793 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 922 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
794 | 923 |
795 if (!success) { | 924 if (!success) { |
796 // Undo any changes if the change couldn't be written to disk. | 925 // Undo any changes if the change couldn't be written to disk. |
797 ordered_cache_names_ = original_ordered_cache_names; | 926 index_.swap(index_before_delete); |
798 callback.Run(false, CACHE_STORAGE_ERROR_STORAGE); | 927 callback.Run(false, CACHE_STORAGE_ERROR_STORAGE); |
799 return; | 928 return; |
800 } | 929 } |
801 | 930 |
802 // Make sure that a cache handle exists for the doomed cache to ensure that | 931 // Make sure that a cache handle exists for the doomed cache to ensure that |
803 // DeleteCacheFinalize is called. | 932 // DeleteCacheFinalize is called. |
804 std::unique_ptr<CacheStorageCacheHandle> cache_handle = | 933 std::unique_ptr<CacheStorageCacheHandle> cache_handle = |
805 GetLoadedCache(cache_name); | 934 GetLoadedCache(cache_name); |
806 | 935 |
807 CacheMap::iterator map_iter = cache_map_.find(cache_name); | 936 CacheMap::iterator map_iter = cache_map_.find(cache_name); |
808 doomed_caches_.insert( | 937 doomed_caches_.insert( |
809 std::make_pair(map_iter->second.get(), std::move(map_iter->second))); | 938 std::make_pair(map_iter->second.get(), std::move(map_iter->second))); |
810 cache_map_.erase(map_iter); | 939 cache_map_.erase(map_iter); |
811 | 940 |
812 cache_loader_->NotifyCacheDoomed(std::move(cache_handle)); | 941 cache_loader_->NotifyCacheDoomed(std::move(cache_handle)); |
813 | 942 |
814 callback.Run(true, CACHE_STORAGE_OK); | 943 callback.Run(true, CACHE_STORAGE_OK); |
815 } | 944 } |
816 | 945 |
817 // Call this once the last handle to a doomed cache is gone. It's okay if this | 946 // Call this once the last handle to a doomed cache is gone. It's okay if this |
818 // doesn't get to complete before shutdown, the cache will be removed from disk | 947 // doesn't get to complete before shutdown, the cache will be removed from disk |
819 // on next startup in that case. | 948 // on next startup in that case. |
820 void CacheStorage::DeleteCacheFinalize( | 949 void CacheStorage::DeleteCacheFinalize( |
821 std::unique_ptr<CacheStorageCache> doomed_cache) { | 950 std::unique_ptr<CacheStorageCache> doomed_cache) { |
822 CacheStorageCache* cache = doomed_cache.get(); | 951 CacheStorageCache* cache = doomed_cache.get(); |
952 cache->SetObserver(nullptr); | |
823 cache->Size(base::Bind(&CacheStorage::DeleteCacheDidGetSize, | 953 cache->Size(base::Bind(&CacheStorage::DeleteCacheDidGetSize, |
824 weak_factory_.GetWeakPtr(), | 954 weak_factory_.GetWeakPtr(), |
825 base::Passed(std::move(doomed_cache)))); | 955 base::Passed(std::move(doomed_cache)))); |
826 } | 956 } |
827 | 957 |
828 void CacheStorage::DeleteCacheDidGetSize( | 958 void CacheStorage::DeleteCacheDidGetSize( |
829 std::unique_ptr<CacheStorageCache> cache, | 959 std::unique_ptr<CacheStorageCache> cache, |
830 int64_t cache_size) { | 960 int64_t cache_size) { |
831 quota_manager_proxy_->NotifyStorageModified( | 961 quota_manager_proxy_->NotifyStorageModified( |
832 storage::QuotaClient::kServiceWorkerCache, origin_, | 962 storage::QuotaClient::kServiceWorkerCache, origin_, |
833 storage::kStorageTypeTemporary, -1 * cache_size); | 963 storage::kStorageTypeTemporary, -1 * cache_size); |
834 | 964 |
835 cache_loader_->CleanUpDeletedCache(cache.get()); | 965 cache_loader_->CleanUpDeletedCache(cache.get()); |
836 } | 966 } |
837 | 967 |
838 void CacheStorage::EnumerateCachesImpl(const StringsCallback& callback) { | 968 void CacheStorage::EnumerateCachesImpl(const CacheMetadataCallback& callback) { |
839 callback.Run(ordered_cache_names_); | 969 callback.Run(index_->ordered_cache_metadata()); |
840 } | 970 } |
841 | 971 |
842 void CacheStorage::MatchCacheImpl( | 972 void CacheStorage::MatchCacheImpl( |
843 const std::string& cache_name, | 973 const std::string& cache_name, |
844 std::unique_ptr<ServiceWorkerFetchRequest> request, | 974 std::unique_ptr<ServiceWorkerFetchRequest> request, |
845 const CacheStorageCacheQueryParams& match_params, | 975 const CacheStorageCacheQueryParams& match_params, |
846 const CacheStorageCache::ResponseCallback& callback) { | 976 const CacheStorageCache::ResponseCallback& callback) { |
847 std::unique_ptr<CacheStorageCacheHandle> cache_handle = | 977 std::unique_ptr<CacheStorageCacheHandle> cache_handle = |
848 GetLoadedCache(cache_name); | 978 GetLoadedCache(cache_name); |
849 | 979 |
(...skipping 20 matching lines...) Expand all Loading... | |
870 std::unique_ptr<ServiceWorkerResponse> response, | 1000 std::unique_ptr<ServiceWorkerResponse> response, |
871 std::unique_ptr<storage::BlobDataHandle> handle) { | 1001 std::unique_ptr<storage::BlobDataHandle> handle) { |
872 callback.Run(error, std::move(response), std::move(handle)); | 1002 callback.Run(error, std::move(response), std::move(handle)); |
873 } | 1003 } |
874 | 1004 |
875 void CacheStorage::MatchAllCachesImpl( | 1005 void CacheStorage::MatchAllCachesImpl( |
876 std::unique_ptr<ServiceWorkerFetchRequest> request, | 1006 std::unique_ptr<ServiceWorkerFetchRequest> request, |
877 const CacheStorageCacheQueryParams& match_params, | 1007 const CacheStorageCacheQueryParams& match_params, |
878 const CacheStorageCache::ResponseCallback& callback) { | 1008 const CacheStorageCache::ResponseCallback& callback) { |
879 std::vector<CacheMatchResponse>* match_responses = | 1009 std::vector<CacheMatchResponse>* match_responses = |
880 new std::vector<CacheMatchResponse>(ordered_cache_names_.size()); | 1010 new std::vector<CacheMatchResponse>(index_->num_entries()); |
881 | 1011 |
882 base::Closure barrier_closure = base::BarrierClosure( | 1012 base::Closure barrier_closure = base::BarrierClosure( |
883 ordered_cache_names_.size(), | 1013 index_->num_entries(), |
884 base::Bind(&CacheStorage::MatchAllCachesDidMatchAll, | 1014 base::Bind(&CacheStorage::MatchAllCachesDidMatchAll, |
885 weak_factory_.GetWeakPtr(), | 1015 weak_factory_.GetWeakPtr(), |
886 base::Passed(base::WrapUnique(match_responses)), callback)); | 1016 base::Passed(base::WrapUnique(match_responses)), callback)); |
887 | 1017 |
888 for (size_t i = 0, max = ordered_cache_names_.size(); i < max; ++i) { | 1018 size_t idx = 0, max = index_->num_entries(); |
jkarlin
2016/11/11 18:24:56
What's this about? index_->num_entries() == index
cmumford
2016/11/22 17:45:03
I'm assuming you were asking about using |max| and
| |
1019 for (const auto& cache_metadata : index_->ordered_cache_metadata()) { | |
889 std::unique_ptr<CacheStorageCacheHandle> cache_handle = | 1020 std::unique_ptr<CacheStorageCacheHandle> cache_handle = |
890 GetLoadedCache(ordered_cache_names_[i]); | 1021 GetLoadedCache(cache_metadata.name); |
891 DCHECK(cache_handle); | 1022 DCHECK(cache_handle); |
892 | 1023 |
893 CacheStorageCache* cache_ptr = cache_handle->value(); | 1024 CacheStorageCache* cache_ptr = cache_handle->value(); |
894 cache_ptr->Match(base::MakeUnique<ServiceWorkerFetchRequest>(*request), | 1025 cache_ptr->Match(base::MakeUnique<ServiceWorkerFetchRequest>(*request), |
895 match_params, | 1026 match_params, |
896 base::Bind(&CacheStorage::MatchAllCachesDidMatch, | 1027 base::Bind(&CacheStorage::MatchAllCachesDidMatch, |
897 weak_factory_.GetWeakPtr(), | 1028 weak_factory_.GetWeakPtr(), |
898 base::Passed(std::move(cache_handle)), | 1029 base::Passed(std::move(cache_handle)), |
899 &match_responses->at(i), barrier_closure)); | 1030 &match_responses->at(idx), barrier_closure)); |
1031 if (++idx > max) | |
1032 break; | |
900 } | 1033 } |
901 } | 1034 } |
902 | 1035 |
903 void CacheStorage::MatchAllCachesDidMatch( | 1036 void CacheStorage::MatchAllCachesDidMatch( |
904 std::unique_ptr<CacheStorageCacheHandle> cache_handle, | 1037 std::unique_ptr<CacheStorageCacheHandle> cache_handle, |
905 CacheMatchResponse* out_match_response, | 1038 CacheMatchResponse* out_match_response, |
906 const base::Closure& barrier_closure, | 1039 const base::Closure& barrier_closure, |
907 CacheStorageError error, | 1040 CacheStorageError error, |
908 std::unique_ptr<ServiceWorkerResponse> service_worker_response, | 1041 std::unique_ptr<ServiceWorkerResponse> service_worker_response, |
909 std::unique_ptr<storage::BlobDataHandle> handle) { | 1042 std::unique_ptr<storage::BlobDataHandle> handle) { |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
977 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 1110 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
978 DCHECK(initialized_); | 1111 DCHECK(initialized_); |
979 | 1112 |
980 CacheMap::iterator map_iter = cache_map_.find(cache_name); | 1113 CacheMap::iterator map_iter = cache_map_.find(cache_name); |
981 if (map_iter == cache_map_.end()) | 1114 if (map_iter == cache_map_.end()) |
982 return std::unique_ptr<CacheStorageCacheHandle>(); | 1115 return std::unique_ptr<CacheStorageCacheHandle>(); |
983 | 1116 |
984 CacheStorageCache* cache = map_iter->second.get(); | 1117 CacheStorageCache* cache = map_iter->second.get(); |
985 | 1118 |
986 if (!cache) { | 1119 if (!cache) { |
987 std::unique_ptr<CacheStorageCache> new_cache = | 1120 DCHECK(initialized_); |
jkarlin
2016/11/11 18:24:56
This is a duplicate of a DCHECK a few lines up
cmumford
2016/11/22 17:45:03
Done.
| |
988 cache_loader_->CreateCache(cache_name); | 1121 std::unique_ptr<CacheStorageCache> new_cache = cache_loader_->CreateCache( |
1122 cache_name, index_->GetCacheSize(cache_name)); | |
989 CacheStorageCache* cache_ptr = new_cache.get(); | 1123 CacheStorageCache* cache_ptr = new_cache.get(); |
990 map_iter->second = std::move(new_cache); | 1124 map_iter->second = std::move(new_cache); |
991 | 1125 |
992 return CreateCacheHandle(cache_ptr); | 1126 return CreateCacheHandle(cache_ptr); |
993 } | 1127 } |
994 | 1128 |
995 return CreateCacheHandle(cache); | 1129 return CreateCacheHandle(cache); |
996 } | 1130 } |
997 | 1131 |
1132 void CacheStorage::SizeRetrievedFromCache( | |
1133 std::unique_ptr<CacheStorageCacheHandle> cache_handle, | |
1134 const base::Closure& closure, | |
1135 int64_t* accumulator, | |
1136 int64_t size) { | |
1137 index_->SetCacheSize(cache_handle->value()->cache_name(), size); | |
1138 *accumulator += size; | |
1139 closure.Run(); | |
1140 } | |
1141 | |
1142 void CacheStorage::CloseAllCaches() { | |
jkarlin
2016/11/11 18:24:56
Who calls this?
cmumford
2016/11/22 17:45:03
Woops - I called this in CacheStorage::GetSizeThen
| |
1143 for (const CacheMetadata& cache_metadata : index_->ordered_cache_metadata()) { | |
1144 auto map_iter = cache_map_.find(cache_metadata.name); | |
jkarlin
2016/11/11 18:24:56
Why iterate over ordered_cache_metadata and then l
| |
1145 if (map_iter != cache_map_.end()) { | |
1146 CacheStorageCache* cache = map_iter->second.get(); | |
1147 if (cache) | |
1148 cache->Close(base::Bind(&base::DoNothing)); | |
1149 } | |
1150 } | |
1151 } | |
1152 | |
998 void CacheStorage::GetSizeThenCloseAllCachesImpl(const SizeCallback& callback) { | 1153 void CacheStorage::GetSizeThenCloseAllCachesImpl(const SizeCallback& callback) { |
999 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 1154 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
1000 DCHECK(initialized_); | 1155 DCHECK(initialized_); |
1001 | 1156 |
1002 std::unique_ptr<int64_t> accumulator(new int64_t(0)); | 1157 std::unique_ptr<int64_t> accumulator(new int64_t(0)); |
1003 int64_t* accumulator_ptr = accumulator.get(); | 1158 int64_t* accumulator_ptr = accumulator.get(); |
1004 | 1159 |
1005 base::Closure barrier_closure = base::BarrierClosure( | 1160 base::Closure barrier_closure = base::BarrierClosure( |
1006 ordered_cache_names_.size(), | 1161 index_->num_entries(), |
1007 base::Bind(&SizeRetrievedFromAllCaches, | 1162 base::Bind(&SizeRetrievedFromAllCaches, |
1008 base::Passed(std::move(accumulator)), callback)); | 1163 base::Passed(std::move(accumulator)), callback)); |
1009 | 1164 |
1010 for (const std::string& cache_name : ordered_cache_names_) { | 1165 for (const CacheMetadata& cache_metadata : index_->ordered_cache_metadata()) { |
1011 std::unique_ptr<CacheStorageCacheHandle> cache_handle = | 1166 auto cache_handle = GetLoadedCache(cache_metadata.name); |
1012 GetLoadedCache(cache_name); | |
1013 CacheStorageCache* cache = cache_handle->value(); | 1167 CacheStorageCache* cache = cache_handle->value(); |
1014 cache->GetSizeThenClose(base::Bind(&SizeRetrievedFromCache, | 1168 cache->GetSizeThenClose(base::Bind(&CacheStorage::SizeRetrievedFromCache, |
1169 weak_factory_.GetWeakPtr(), | |
1015 base::Passed(std::move(cache_handle)), | 1170 base::Passed(std::move(cache_handle)), |
1016 barrier_closure, accumulator_ptr)); | 1171 barrier_closure, accumulator_ptr)); |
1017 } | 1172 } |
1018 } | 1173 } |
1019 | 1174 |
1020 void CacheStorage::SizeImpl(const SizeCallback& callback) { | 1175 void CacheStorage::SizeImpl(const SizeCallback& callback) { |
1021 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 1176 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
1022 DCHECK(initialized_); | 1177 DCHECK(initialized_); |
1023 | 1178 |
1179 if (index_->GetStorageSize() != kSizeUnknown) { | |
1180 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
1181 FROM_HERE, base::Bind(callback, index_->GetStorageSize())); | |
1182 return; | |
1183 } | |
1184 | |
1024 std::unique_ptr<int64_t> accumulator(new int64_t(0)); | 1185 std::unique_ptr<int64_t> accumulator(new int64_t(0)); |
1025 int64_t* accumulator_ptr = accumulator.get(); | 1186 int64_t* accumulator_ptr = accumulator.get(); |
1026 | 1187 |
1027 base::Closure barrier_closure = base::BarrierClosure( | 1188 base::Closure barrier_closure = base::BarrierClosure( |
1028 ordered_cache_names_.size(), | 1189 index_->num_entries(), |
1029 base::Bind(&SizeRetrievedFromAllCaches, | 1190 base::Bind(&SizeRetrievedFromAllCaches, |
1030 base::Passed(std::move(accumulator)), callback)); | 1191 base::Passed(std::move(accumulator)), callback)); |
1031 | 1192 |
1032 for (const std::string& cache_name : ordered_cache_names_) { | 1193 for (const CacheMetadata& cache_metadata : index_->ordered_cache_metadata()) { |
1194 if (cache_metadata.size != CacheStorage::kSizeUnknown) { | |
1195 *accumulator_ptr += cache_metadata.size; | |
1196 barrier_closure.Run(); | |
jkarlin
2016/11/11 18:24:56
This can cause trouble. If all of the indexes have
cmumford
2016/11/22 17:45:03
Agreed, but SizeRetrievedFromAllCaches uses PostTa
jkarlin
2016/11/23 16:02:17
Ah, I was looking at SizeRetrievedFromCache which
| |
1197 continue; | |
1198 } | |
1033 std::unique_ptr<CacheStorageCacheHandle> cache_handle = | 1199 std::unique_ptr<CacheStorageCacheHandle> cache_handle = |
1034 GetLoadedCache(cache_name); | 1200 GetLoadedCache(cache_metadata.name); |
1035 CacheStorageCache* cache = cache_handle->value(); | 1201 CacheStorageCache* cache = cache_handle->value(); |
1036 cache->Size(base::Bind(&SizeRetrievedFromCache, | 1202 cache->Size(base::Bind(&CacheStorage::SizeRetrievedFromCache, |
1203 weak_factory_.GetWeakPtr(), | |
1037 base::Passed(std::move(cache_handle)), | 1204 base::Passed(std::move(cache_handle)), |
1038 barrier_closure, accumulator_ptr)); | 1205 barrier_closure, accumulator_ptr)); |
1039 } | 1206 } |
1040 } | 1207 } |
1041 | 1208 |
1042 } // namespace content | 1209 } // namespace content |
OLD | NEW |