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

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

Issue 565913002: Sort ServiceWorkerCacheStorage::Keys() by creation order. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Strings to StringVector 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_storage.h" 5 #include "content/browser/service_worker/service_worker_cache_storage.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/files/file_util.h" 9 #include "base/files/file_util.h"
10 #include "base/files/memory_mapped_file.h" 10 #include "base/files/memory_mapped_file.h"
(...skipping 13 matching lines...) Expand all
24 24
25 25
26 // Handles the loading and clean up of ServiceWorkerCache objects. The 26 // Handles the loading and clean up of ServiceWorkerCache objects. The
27 // callback of every public method is guaranteed to be called. 27 // callback of every public method is guaranteed to be called.
28 class ServiceWorkerCacheStorage::CacheLoader { 28 class ServiceWorkerCacheStorage::CacheLoader {
29 public: 29 public:
30 typedef base::Callback<void(const scoped_refptr<ServiceWorkerCache>&)> 30 typedef base::Callback<void(const scoped_refptr<ServiceWorkerCache>&)>
31 CacheCallback; 31 CacheCallback;
32 typedef base::Callback<void(bool)> BoolCallback; 32 typedef base::Callback<void(bool)> BoolCallback;
33 typedef base::Callback<void(scoped_ptr<std::vector<std::string> >)> 33 typedef base::Callback<void(scoped_ptr<std::vector<std::string> >)>
34 StringsCallback; 34 StringVectorCallback;
35 35
36 CacheLoader(base::SequencedTaskRunner* cache_task_runner, 36 CacheLoader(base::SequencedTaskRunner* cache_task_runner,
37 net::URLRequestContext* request_context, 37 net::URLRequestContext* request_context,
38 base::WeakPtr<storage::BlobStorageContext> blob_context) 38 base::WeakPtr<storage::BlobStorageContext> blob_context)
39 : cache_task_runner_(cache_task_runner), 39 : cache_task_runner_(cache_task_runner),
40 request_context_(request_context), 40 request_context_(request_context),
41 blob_context_(blob_context) {} 41 blob_context_(blob_context) {}
42 42
43 virtual ~CacheLoader() {} 43 virtual ~CacheLoader() {}
44 44
45 // Creates a ServiceWorkerCache with the given name. It does not attempt to 45 // Creates a ServiceWorkerCache with the given name. It does not attempt to
46 // load the backend, that happens lazily when the cache is used. 46 // load the backend, that happens lazily when the cache is used.
47 virtual scoped_refptr<ServiceWorkerCache> CreateServiceWorkerCache( 47 virtual scoped_refptr<ServiceWorkerCache> CreateServiceWorkerCache(
48 const std::string& cache_name) = 0; 48 const std::string& cache_name) = 0;
49 49
50 // Deletes any pre-existing cache of the same name and then loads it. 50 // Deletes any pre-existing cache of the same name and then loads it.
51 virtual void CreateCache(const std::string& cache_name, 51 virtual void CreateCache(const std::string& cache_name,
52 const CacheCallback& callback) = 0; 52 const CacheCallback& callback) = 0;
53 53
54 // After the backend has been deleted, do any extra house keeping such as 54 // After the backend has been deleted, do any extra house keeping such as
55 // removing the cache's directory. 55 // removing the cache's directory.
56 virtual void CleanUpDeletedCache(const std::string& key, 56 virtual void CleanUpDeletedCache(const std::string& key,
57 const BoolCallback& callback) = 0; 57 const BoolCallback& callback) = 0;
58 58
59 // Writes the cache names (and sizes) to disk if applicable. 59 // Writes the cache names (and sizes) to disk if applicable.
60 virtual void WriteIndex(const CacheMap& caches, 60 virtual void WriteIndex(const StringVector& cache_names,
61 const BoolCallback& callback) = 0; 61 const BoolCallback& callback) = 0;
62 62
63 // Loads the cache names from disk if applicable. 63 // Loads the cache names from disk if applicable.
64 virtual void LoadIndex(scoped_ptr<std::vector<std::string> > cache_names, 64 virtual void LoadIndex(scoped_ptr<std::vector<std::string> > cache_names,
65 const StringsCallback& callback) = 0; 65 const StringVectorCallback& callback) = 0;
66 66
67 protected: 67 protected:
68 scoped_refptr<base::SequencedTaskRunner> cache_task_runner_; 68 scoped_refptr<base::SequencedTaskRunner> cache_task_runner_;
69 net::URLRequestContext* request_context_; 69 net::URLRequestContext* request_context_;
70 base::WeakPtr<storage::BlobStorageContext> blob_context_; 70 base::WeakPtr<storage::BlobStorageContext> blob_context_;
71 }; 71 };
72 72
73 // Creates memory-only ServiceWorkerCaches. Because these caches have no 73 // Creates memory-only ServiceWorkerCaches. Because these caches have no
74 // persistent storage it is not safe to free them from memory if they might be 74 // persistent storage it is not safe to free them from memory if they might be
75 // used again. Therefore this class holds a reference to each cache until the 75 // used again. Therefore this class holds a reference to each cache until the
(...skipping 21 matching lines...) Expand all
97 } 97 }
98 98
99 virtual void CleanUpDeletedCache(const std::string& cache_name, 99 virtual void CleanUpDeletedCache(const std::string& cache_name,
100 const BoolCallback& callback) OVERRIDE { 100 const BoolCallback& callback) OVERRIDE {
101 CacheRefMap::iterator it = cache_refs_.find(cache_name); 101 CacheRefMap::iterator it = cache_refs_.find(cache_name);
102 DCHECK(it != cache_refs_.end()); 102 DCHECK(it != cache_refs_.end());
103 cache_refs_.erase(it); 103 cache_refs_.erase(it);
104 callback.Run(true); 104 callback.Run(true);
105 } 105 }
106 106
107 virtual void WriteIndex(const CacheMap& caches, 107 virtual void WriteIndex(const StringVector& cache_names,
108 const BoolCallback& callback) OVERRIDE { 108 const BoolCallback& callback) OVERRIDE {
109 callback.Run(false); 109 callback.Run(false);
110 } 110 }
111 111
112 virtual void LoadIndex(scoped_ptr<std::vector<std::string> > cache_names, 112 virtual void LoadIndex(scoped_ptr<std::vector<std::string> > cache_names,
113 const StringsCallback& callback) OVERRIDE { 113 const StringVectorCallback& callback) OVERRIDE {
114 callback.Run(cache_names.Pass()); 114 callback.Run(cache_names.Pass());
115 } 115 }
116 116
117 private: 117 private:
118 typedef std::map<std::string, scoped_refptr<ServiceWorkerCache> > CacheRefMap; 118 typedef std::map<std::string, scoped_refptr<ServiceWorkerCache> > CacheRefMap;
119 virtual ~MemoryLoader() {} 119 virtual ~MemoryLoader() {}
120 120
121 // Keep a reference to each cache to ensure that it's not freed before the 121 // Keep a reference to each cache to ensure that it's not freed before the
122 // client calls ServiceWorkerCacheStorage::Delete or the CacheStorage is 122 // client calls ServiceWorkerCacheStorage::Delete or the CacheStorage is
123 // freed. 123 // freed.
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
201 } 201 }
202 202
203 static void CleanUpDeleteCacheDirInPool( 203 static void CleanUpDeleteCacheDirInPool(
204 const base::FilePath& cache_path, 204 const base::FilePath& cache_path,
205 const BoolCallback& callback, 205 const BoolCallback& callback,
206 const scoped_refptr<base::MessageLoopProxy>& original_loop) { 206 const scoped_refptr<base::MessageLoopProxy>& original_loop) {
207 bool rv = base::DeleteFile(cache_path, true); 207 bool rv = base::DeleteFile(cache_path, true);
208 original_loop->PostTask(FROM_HERE, base::Bind(callback, rv)); 208 original_loop->PostTask(FROM_HERE, base::Bind(callback, rv));
209 } 209 }
210 210
211 virtual void WriteIndex(const CacheMap& caches, 211 virtual void WriteIndex(const StringVector& cache_names,
212 const BoolCallback& callback) OVERRIDE { 212 const BoolCallback& callback) OVERRIDE {
213 DCHECK_CURRENTLY_ON(BrowserThread::IO); 213 DCHECK_CURRENTLY_ON(BrowserThread::IO);
214 214
215 // 1. Create the index file as a string. (WriteIndex) 215 // 1. Create the index file as a string. (WriteIndex)
216 // 2. Write the file to disk. (WriteIndexWriteToFileInPool) 216 // 2. Write the file to disk. (WriteIndexWriteToFileInPool)
217 217
218 ServiceWorkerCacheStorageIndex index; 218 ServiceWorkerCacheStorageIndex index;
219 219
220 for (CacheMap::const_iterator it = caches.begin(); it != caches.end(); 220 for (size_t i = 0u, max = cache_names.size(); i < max; ++i) {
221 ++it) {
222 ServiceWorkerCacheStorageIndex::Cache* index_cache = index.add_cache(); 221 ServiceWorkerCacheStorageIndex::Cache* index_cache = index.add_cache();
223 index_cache->set_name(it->first); 222 index_cache->set_name(cache_names[i]);
224 index_cache->set_size(0); // TODO(jkarlin): Make this real. 223 index_cache->set_size(0); // TODO(jkarlin): Make this real.
225 } 224 }
226 225
227 std::string serialized; 226 std::string serialized;
228 bool success = index.SerializeToString(&serialized); 227 bool success = index.SerializeToString(&serialized);
229 DCHECK(success); 228 DCHECK(success);
230 229
231 base::FilePath tmp_path = origin_path_.AppendASCII("index.txt.tmp"); 230 base::FilePath tmp_path = origin_path_.AppendASCII("index.txt.tmp");
232 base::FilePath index_path = origin_path_.AppendASCII("index.txt"); 231 base::FilePath index_path = origin_path_.AppendASCII("index.txt");
233 232
(...skipping 18 matching lines...) Expand all
252 base::DeleteFile(tmp_path, /* recursive */ false); 251 base::DeleteFile(tmp_path, /* recursive */ false);
253 original_loop->PostTask(FROM_HERE, base::Bind(callback, false)); 252 original_loop->PostTask(FROM_HERE, base::Bind(callback, false));
254 } 253 }
255 254
256 // Atomically rename the temporary index file to become the real one. 255 // Atomically rename the temporary index file to become the real one.
257 bool rv = base::ReplaceFile(tmp_path, index_path, NULL); 256 bool rv = base::ReplaceFile(tmp_path, index_path, NULL);
258 original_loop->PostTask(FROM_HERE, base::Bind(callback, rv)); 257 original_loop->PostTask(FROM_HERE, base::Bind(callback, rv));
259 } 258 }
260 259
261 virtual void LoadIndex(scoped_ptr<std::vector<std::string> > names, 260 virtual void LoadIndex(scoped_ptr<std::vector<std::string> > names,
262 const StringsCallback& callback) OVERRIDE { 261 const StringVectorCallback& callback) OVERRIDE {
263 DCHECK_CURRENTLY_ON(BrowserThread::IO); 262 DCHECK_CURRENTLY_ON(BrowserThread::IO);
264 263
265 // 1. Read the file from disk. (LoadIndexReadFileInPool) 264 // 1. Read the file from disk. (LoadIndexReadFileInPool)
266 // 2. Parse file and return the names of the caches (LoadIndexDidReadFile) 265 // 2. Parse file and return the names of the caches (LoadIndexDidReadFile)
267 266
268 base::FilePath index_path = origin_path_.AppendASCII("index.txt"); 267 base::FilePath index_path = origin_path_.AppendASCII("index.txt");
269 268
270 cache_task_runner_->PostTask( 269 cache_task_runner_->PostTask(
271 FROM_HERE, 270 FROM_HERE,
272 base::Bind(&SimpleCacheLoader::LoadIndexReadFileInPool, 271 base::Bind(&SimpleCacheLoader::LoadIndexReadFileInPool,
273 index_path, 272 index_path,
274 base::Passed(names.Pass()), 273 base::Passed(names.Pass()),
275 callback, 274 callback,
276 base::MessageLoopProxy::current())); 275 base::MessageLoopProxy::current()));
277 } 276 }
278 277
279 static void LoadIndexReadFileInPool( 278 static void LoadIndexReadFileInPool(
280 const base::FilePath& index_path, 279 const base::FilePath& index_path,
281 scoped_ptr<std::vector<std::string> > names, 280 scoped_ptr<std::vector<std::string> > names,
282 const StringsCallback& callback, 281 const StringVectorCallback& callback,
283 const scoped_refptr<base::MessageLoopProxy>& original_loop) { 282 const scoped_refptr<base::MessageLoopProxy>& original_loop) {
284 std::string body; 283 std::string body;
285 base::ReadFileToString(index_path, &body); 284 base::ReadFileToString(index_path, &body);
286 285
287 original_loop->PostTask(FROM_HERE, 286 original_loop->PostTask(FROM_HERE,
288 base::Bind(&SimpleCacheLoader::LoadIndexDidReadFile, 287 base::Bind(&SimpleCacheLoader::LoadIndexDidReadFile,
289 base::Passed(names.Pass()), 288 base::Passed(names.Pass()),
290 callback, 289 callback,
291 body)); 290 body));
292 } 291 }
293 292
294 static void LoadIndexDidReadFile(scoped_ptr<std::vector<std::string> > names, 293 static void LoadIndexDidReadFile(scoped_ptr<std::vector<std::string> > names,
295 const StringsCallback& callback, 294 const StringVectorCallback& callback,
296 const std::string& serialized) { 295 const std::string& serialized) {
297 DCHECK_CURRENTLY_ON(BrowserThread::IO); 296 DCHECK_CURRENTLY_ON(BrowserThread::IO);
298 297
299 ServiceWorkerCacheStorageIndex index; 298 ServiceWorkerCacheStorageIndex index;
300 if (index.ParseFromString(serialized)) { 299 if (index.ParseFromString(serialized)) {
301 for (int i = 0, max = index.cache_size(); i < max; ++i) { 300 for (int i = 0, max = index.cache_size(); i < max; ++i) {
302 const ServiceWorkerCacheStorageIndex::Cache& cache = index.cache(i); 301 const ServiceWorkerCacheStorageIndex::Cache& cache = index.cache(i);
303 names->push_back(cache.name()); 302 names->push_back(cache.name());
304 } 303 }
305 } 304 }
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
435 callback.Run(false, CACHE_STORAGE_ERROR_NOT_FOUND); 434 callback.Run(false, CACHE_STORAGE_ERROR_NOT_FOUND);
436 return; 435 return;
437 } 436 }
438 437
439 base::WeakPtr<ServiceWorkerCache> cache = it->second; 438 base::WeakPtr<ServiceWorkerCache> cache = it->second;
440 if (cache) 439 if (cache)
441 cache->Close(); 440 cache->Close();
442 441
443 cache_map_.erase(it); 442 cache_map_.erase(it);
444 443
444 // Delete the name from ordered_cache_names_.
445 StringVector::iterator iter = std::find(
446 ordered_cache_names_.begin(), ordered_cache_names_.end(), cache_name);
447 DCHECK(iter != ordered_cache_names_.end());
448 ordered_cache_names_.erase(iter);
449
445 // Update the Index 450 // Update the Index
446 cache_loader_->WriteIndex( 451 cache_loader_->WriteIndex(
447 cache_map_, 452 ordered_cache_names_,
448 base::Bind(&ServiceWorkerCacheStorage::DeleteCacheDidWriteIndex, 453 base::Bind(&ServiceWorkerCacheStorage::DeleteCacheDidWriteIndex,
449 weak_factory_.GetWeakPtr(), 454 weak_factory_.GetWeakPtr(),
450 cache_name, 455 cache_name,
451 callback)); 456 callback));
452 } 457 }
453 458
454 void ServiceWorkerCacheStorage::EnumerateCaches( 459 void ServiceWorkerCacheStorage::EnumerateCaches(
455 const StringsAndErrorCallback& callback) { 460 const StringsAndErrorCallback& callback) {
456 DCHECK_CURRENTLY_ON(BrowserThread::IO); 461 DCHECK_CURRENTLY_ON(BrowserThread::IO);
457 462
458 if (!initialized_) { 463 if (!initialized_) {
459 LazyInit(base::Bind(&ServiceWorkerCacheStorage::EnumerateCaches, 464 LazyInit(base::Bind(&ServiceWorkerCacheStorage::EnumerateCaches,
460 weak_factory_.GetWeakPtr(), 465 weak_factory_.GetWeakPtr(),
461 callback)); 466 callback));
462 return; 467 return;
463 } 468 }
464 469
465 std::vector<std::string> names; 470 callback.Run(ordered_cache_names_, CACHE_STORAGE_ERROR_NO_ERROR);
466 for (CacheMap::const_iterator it = cache_map_.begin(); it != cache_map_.end();
467 ++it) {
468 names.push_back(it->first);
469 }
470
471 callback.Run(names, CACHE_STORAGE_ERROR_NO_ERROR);
472 } 471 }
473 472
474 // Init is run lazily so that it is called on the proper MessageLoop. 473 // Init is run lazily so that it is called on the proper MessageLoop.
475 void ServiceWorkerCacheStorage::LazyInit(const base::Closure& callback) { 474 void ServiceWorkerCacheStorage::LazyInit(const base::Closure& callback) {
476 DCHECK_CURRENTLY_ON(BrowserThread::IO); 475 DCHECK_CURRENTLY_ON(BrowserThread::IO);
477 DCHECK(!initialized_); 476 DCHECK(!initialized_);
478 477
479 init_callbacks_.push_back(callback); 478 init_callbacks_.push_back(callback);
480 479
481 // If this isn't the first call to LazyInit then return as the initialization 480 // If this isn't the first call to LazyInit then return as the initialization
(...skipping 17 matching lines...) Expand all
499 } 498 }
500 499
501 void ServiceWorkerCacheStorage::LazyInitDidLoadIndex( 500 void ServiceWorkerCacheStorage::LazyInitDidLoadIndex(
502 const base::Closure& callback, 501 const base::Closure& callback,
503 scoped_ptr<std::vector<std::string> > indexed_cache_names) { 502 scoped_ptr<std::vector<std::string> > indexed_cache_names) {
504 DCHECK_CURRENTLY_ON(BrowserThread::IO); 503 DCHECK_CURRENTLY_ON(BrowserThread::IO);
505 504
506 for (size_t i = 0u, max = indexed_cache_names->size(); i < max; ++i) { 505 for (size_t i = 0u, max = indexed_cache_names->size(); i < max; ++i) {
507 cache_map_.insert(std::make_pair(indexed_cache_names->at(i), 506 cache_map_.insert(std::make_pair(indexed_cache_names->at(i),
508 base::WeakPtr<ServiceWorkerCache>())); 507 base::WeakPtr<ServiceWorkerCache>()));
508 ordered_cache_names_.push_back(indexed_cache_names->at(i));
509 } 509 }
510 510
511 initialized_ = true; 511 initialized_ = true;
512 for (std::vector<base::Closure>::iterator it = init_callbacks_.begin(); 512 for (std::vector<base::Closure>::iterator it = init_callbacks_.begin();
513 it != init_callbacks_.end(); 513 it != init_callbacks_.end();
514 ++it) { 514 ++it) {
515 it->Run(); 515 it->Run();
516 } 516 }
517 init_callbacks_.clear(); 517 init_callbacks_.clear();
518 } 518 }
519 519
520 void ServiceWorkerCacheStorage::CreateCacheDidCreateCache( 520 void ServiceWorkerCacheStorage::CreateCacheDidCreateCache(
521 const std::string& cache_name, 521 const std::string& cache_name,
522 const CacheAndErrorCallback& callback, 522 const CacheAndErrorCallback& callback,
523 const scoped_refptr<ServiceWorkerCache>& cache) { 523 const scoped_refptr<ServiceWorkerCache>& cache) {
524 DCHECK_CURRENTLY_ON(BrowserThread::IO); 524 DCHECK_CURRENTLY_ON(BrowserThread::IO);
525 525
526 if (!cache.get()) { 526 if (!cache.get()) {
527 callback.Run(scoped_refptr<ServiceWorkerCache>(), 527 callback.Run(scoped_refptr<ServiceWorkerCache>(),
528 CACHE_STORAGE_ERROR_CLOSING); 528 CACHE_STORAGE_ERROR_CLOSING);
529 return; 529 return;
530 } 530 }
531 531
532 cache_map_.insert(std::make_pair(cache_name, cache->AsWeakPtr())); 532 cache_map_.insert(std::make_pair(cache_name, cache->AsWeakPtr()));
533 ordered_cache_names_.push_back(cache_name);
533 534
534 cache_loader_->WriteIndex( 535 cache_loader_->WriteIndex(
535 cache_map_, 536 ordered_cache_names_,
536 base::Bind(&ServiceWorkerCacheStorage::CreateCacheDidWriteIndex, 537 base::Bind(&ServiceWorkerCacheStorage::CreateCacheDidWriteIndex,
537 weak_factory_.GetWeakPtr(), 538 weak_factory_.GetWeakPtr(),
538 callback, 539 callback,
539 cache)); 540 cache));
540 } 541 }
541 542
542 void ServiceWorkerCacheStorage::CreateCacheDidWriteIndex( 543 void ServiceWorkerCacheStorage::CreateCacheDidWriteIndex(
543 const CacheAndErrorCallback& callback, 544 const CacheAndErrorCallback& callback,
544 const scoped_refptr<ServiceWorkerCache>& cache, 545 const scoped_refptr<ServiceWorkerCache>& cache,
545 bool success) { 546 bool success) {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
585 scoped_refptr<ServiceWorkerCache> new_cache = 586 scoped_refptr<ServiceWorkerCache> new_cache =
586 cache_loader_->CreateServiceWorkerCache(cache_name); 587 cache_loader_->CreateServiceWorkerCache(cache_name);
587 map_iter->second = new_cache->AsWeakPtr(); 588 map_iter->second = new_cache->AsWeakPtr();
588 return new_cache; 589 return new_cache;
589 } 590 }
590 591
591 return make_scoped_refptr(cache.get()); 592 return make_scoped_refptr(cache.get());
592 } 593 }
593 594
594 } // namespace content 595 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698