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/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/file_util.h" | 9 #include "base/file_util.h" |
10 #include "base/files/memory_mapped_file.h" | 10 #include "base/files/memory_mapped_file.h" |
11 #include "base/memory/ref_counted.h" | 11 #include "base/memory/ref_counted.h" |
12 #include "base/sha1.h" | 12 #include "base/sha1.h" |
13 #include "base/stl_util.h" | |
13 #include "base/strings/string_number_conversions.h" | 14 #include "base/strings/string_number_conversions.h" |
14 #include "base/strings/string_util.h" | 15 #include "base/strings/string_util.h" |
15 #include "content/browser/service_worker/service_worker_cache.h" | 16 #include "content/browser/service_worker/service_worker_cache.h" |
16 #include "content/browser/service_worker/service_worker_cache.pb.h" | 17 #include "content/browser/service_worker/service_worker_cache.pb.h" |
17 #include "content/public/browser/browser_thread.h" | 18 #include "content/public/browser/browser_thread.h" |
18 #include "net/base/directory_lister.h" | 19 #include "net/base/directory_lister.h" |
19 #include "net/base/net_errors.h" | 20 #include "net/base/net_errors.h" |
20 #include "webkit/browser/blob/blob_storage_context.h" | 21 #include "webkit/browser/blob/blob_storage_context.h" |
21 | 22 |
22 namespace content { | 23 namespace content { |
23 | 24 |
25 // The meta information related to each ServiceWorkerCache that the | |
26 // ServiceWorkerCacheManager needs to keep track of. | |
27 // TODO(jkarlin): Add reference counting. | |
falken
2014/08/26 06:31:32
Depending on how long you plan to take, it might b
jkarlin
2014/08/26 12:03:10
Done.
| |
28 struct ServiceWorkerCacheStorage::CacheContext { | |
29 CacheContext(const std::string& name, | |
30 CacheID id, | |
31 scoped_ptr<ServiceWorkerCache> cache) | |
32 : name(name), id(id), cache(cache.Pass()) {} | |
33 std::string name; | |
34 CacheID id; | |
35 scoped_ptr<ServiceWorkerCache> cache; | |
36 }; | |
37 | |
24 // Handles the loading and clean up of ServiceWorkerCache objects. | 38 // Handles the loading and clean up of ServiceWorkerCache objects. |
25 class ServiceWorkerCacheStorage::CacheLoader | 39 class ServiceWorkerCacheStorage::CacheLoader |
26 : public base::RefCountedThreadSafe< | 40 : public base::RefCountedThreadSafe< |
27 ServiceWorkerCacheStorage::CacheLoader> { | 41 ServiceWorkerCacheStorage::CacheLoader> { |
28 public: | 42 public: |
29 typedef base::Callback<void(scoped_ptr<ServiceWorkerCache>)> CacheCallback; | 43 typedef base::Callback<void(scoped_ptr<ServiceWorkerCache>)> CacheCallback; |
30 typedef base::Callback<void(bool)> BoolCallback; | 44 typedef base::Callback<void(bool)> BoolCallback; |
31 typedef base::Callback<void(scoped_ptr<std::vector<std::string> >)> | 45 typedef base::Callback<void(scoped_ptr<std::vector<std::string> >)> |
32 StringsCallback; | 46 StringsCallback; |
33 | 47 |
(...skipping 12 matching lines...) Expand all Loading... | |
46 // Deletes any pre-existing cache of the same name and then loads it. | 60 // Deletes any pre-existing cache of the same name and then loads it. |
47 virtual void CreateCache(const std::string& cache_name, | 61 virtual void CreateCache(const std::string& cache_name, |
48 const CacheCallback& callback) = 0; | 62 const CacheCallback& callback) = 0; |
49 | 63 |
50 // After the backend has been deleted, do any extra house keeping such as | 64 // After the backend has been deleted, do any extra house keeping such as |
51 // removing the cache's directory. | 65 // removing the cache's directory. |
52 virtual void CleanUpDeletedCache(const std::string& key, | 66 virtual void CleanUpDeletedCache(const std::string& key, |
53 const BoolCallback& callback) = 0; | 67 const BoolCallback& callback) = 0; |
54 | 68 |
55 // Writes the cache names (and sizes) to disk if applicable. | 69 // Writes the cache names (and sizes) to disk if applicable. |
56 virtual void WriteIndex(CacheMap* caches, const BoolCallback& callback) = 0; | 70 virtual void WriteIndex(const CacheMap& caches, |
71 const BoolCallback& callback) = 0; | |
57 | 72 |
58 // Loads the cache names from disk if applicable. | 73 // Loads the cache names from disk if applicable. |
59 virtual void LoadIndex(scoped_ptr<std::vector<std::string> > cache_names, | 74 virtual void LoadIndex(scoped_ptr<std::vector<std::string> > cache_names, |
60 const StringsCallback& callback) = 0; | 75 const StringsCallback& callback) = 0; |
61 | 76 |
62 protected: | 77 protected: |
63 friend class base::RefCountedThreadSafe< | 78 friend class base::RefCountedThreadSafe< |
64 ServiceWorkerCacheStorage::CacheLoader>; | 79 ServiceWorkerCacheStorage::CacheLoader>; |
65 | 80 |
66 virtual ~CacheLoader() {}; | 81 virtual ~CacheLoader() {}; |
(...skipping 12 matching lines...) Expand all Loading... | |
79 base::WeakPtr<storage::BlobStorageContext> blob_context) | 94 base::WeakPtr<storage::BlobStorageContext> blob_context) |
80 : CacheLoader(cache_task_runner, request_context, blob_context) {} | 95 : CacheLoader(cache_task_runner, request_context, blob_context) {} |
81 virtual void LoadCache(const std::string& cache_name, | 96 virtual void LoadCache(const std::string& cache_name, |
82 const CacheCallback& callback) OVERRIDE { | 97 const CacheCallback& callback) OVERRIDE { |
83 NOTREACHED(); | 98 NOTREACHED(); |
84 } | 99 } |
85 | 100 |
86 virtual void CreateCache(const std::string& cache_name, | 101 virtual void CreateCache(const std::string& cache_name, |
87 const CacheCallback& callback) OVERRIDE { | 102 const CacheCallback& callback) OVERRIDE { |
88 scoped_ptr<ServiceWorkerCache> cache = | 103 scoped_ptr<ServiceWorkerCache> cache = |
89 ServiceWorkerCache::CreateMemoryCache( | 104 ServiceWorkerCache::CreateMemoryCache(request_context_, blob_context_); |
90 cache_name, request_context_, blob_context_); | |
91 callback.Run(cache.Pass()); | 105 callback.Run(cache.Pass()); |
92 } | 106 } |
93 | 107 |
94 virtual void CleanUpDeletedCache(const std::string& cache_name, | 108 virtual void CleanUpDeletedCache(const std::string& cache_name, |
95 const BoolCallback& callback) OVERRIDE { | 109 const BoolCallback& callback) OVERRIDE { |
96 callback.Run(true); | 110 callback.Run(true); |
97 } | 111 } |
98 | 112 |
99 virtual void WriteIndex(CacheMap* caches, | 113 virtual void WriteIndex(const CacheMap& caches, |
100 const BoolCallback& callback) OVERRIDE { | 114 const BoolCallback& callback) OVERRIDE { |
101 callback.Run(false); | 115 callback.Run(false); |
102 } | 116 } |
103 | 117 |
104 virtual void LoadIndex(scoped_ptr<std::vector<std::string> > cache_names, | 118 virtual void LoadIndex(scoped_ptr<std::vector<std::string> > cache_names, |
105 const StringsCallback& callback) OVERRIDE { | 119 const StringsCallback& callback) OVERRIDE { |
106 callback.Run(cache_names.Pass()); | 120 callback.Run(cache_names.Pass()); |
107 } | 121 } |
108 | 122 |
109 private: | 123 private: |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
160 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 174 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
161 | 175 |
162 if (!dir_rv) { | 176 if (!dir_rv) { |
163 callback.Run(scoped_ptr<ServiceWorkerCache>()); | 177 callback.Run(scoped_ptr<ServiceWorkerCache>()); |
164 return; | 178 return; |
165 } | 179 } |
166 | 180 |
167 scoped_ptr<ServiceWorkerCache> cache = | 181 scoped_ptr<ServiceWorkerCache> cache = |
168 ServiceWorkerCache::CreatePersistentCache( | 182 ServiceWorkerCache::CreatePersistentCache( |
169 CreatePersistentCachePath(origin_path_, cache_name), | 183 CreatePersistentCachePath(origin_path_, cache_name), |
170 cache_name, | |
171 request_context_, | 184 request_context_, |
172 blob_context_); | 185 blob_context_); |
173 callback.Run(cache.Pass()); | 186 callback.Run(cache.Pass()); |
174 } | 187 } |
175 | 188 |
176 virtual void CreateCache(const std::string& cache_name, | 189 virtual void CreateCache(const std::string& cache_name, |
177 const CacheCallback& callback) OVERRIDE { | 190 const CacheCallback& callback) OVERRIDE { |
178 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 191 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
179 | 192 |
180 // 1. Delete the cache's directory if it exists. | 193 // 1. Delete the cache's directory if it exists. |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
236 void CleanUpDeleteCacheDirInPool( | 249 void CleanUpDeleteCacheDirInPool( |
237 const base::FilePath& cache_path, | 250 const base::FilePath& cache_path, |
238 const BoolCallback& callback, | 251 const BoolCallback& callback, |
239 const scoped_refptr<base::MessageLoopProxy>& original_loop) { | 252 const scoped_refptr<base::MessageLoopProxy>& original_loop) { |
240 DCHECK(cache_task_runner_->RunsTasksOnCurrentThread()); | 253 DCHECK(cache_task_runner_->RunsTasksOnCurrentThread()); |
241 | 254 |
242 bool rv = base::DeleteFile(cache_path, true); | 255 bool rv = base::DeleteFile(cache_path, true); |
243 original_loop->PostTask(FROM_HERE, base::Bind(callback, rv)); | 256 original_loop->PostTask(FROM_HERE, base::Bind(callback, rv)); |
244 } | 257 } |
245 | 258 |
246 virtual void WriteIndex(CacheMap* caches, | 259 virtual void WriteIndex(const CacheMap& caches, |
247 const BoolCallback& callback) OVERRIDE { | 260 const BoolCallback& callback) OVERRIDE { |
248 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 261 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
249 | 262 |
250 // 1. Create the index file as a string. (WriteIndex) | 263 // 1. Create the index file as a string. (WriteIndex) |
251 // 2. Write the file to disk. (WriteIndexWriteToFileInPool) | 264 // 2. Write the file to disk. (WriteIndexWriteToFileInPool) |
252 | 265 |
253 ServiceWorkerCacheStorageIndex index; | 266 ServiceWorkerCacheStorageIndex index; |
254 | 267 |
255 for (CacheMap::const_iterator iter(caches); !iter.IsAtEnd(); | 268 for (CacheMap::const_iterator it = caches.begin(); it != caches.end(); |
256 iter.Advance()) { | 269 ++it) { |
257 const ServiceWorkerCache* cache = iter.GetCurrentValue(); | 270 const CacheContext* cache = it->second; |
258 ServiceWorkerCacheStorageIndex::Cache* index_cache = index.add_cache(); | 271 ServiceWorkerCacheStorageIndex::Cache* index_cache = index.add_cache(); |
259 index_cache->set_name(cache->name()); | 272 index_cache->set_name(cache->name); |
260 index_cache->set_size(0); // TODO(jkarlin): Make this real. | 273 index_cache->set_size(0); // TODO(jkarlin): Make this real. |
261 } | 274 } |
262 | 275 |
263 std::string serialized; | 276 std::string serialized; |
264 bool success = index.SerializeToString(&serialized); | 277 bool success = index.SerializeToString(&serialized); |
265 DCHECK(success); | 278 DCHECK(success); |
266 | 279 |
267 base::FilePath tmp_path = origin_path_.AppendASCII("index.txt.tmp"); | 280 base::FilePath tmp_path = origin_path_.AppendASCII("index.txt.tmp"); |
268 base::FilePath index_path = origin_path_.AppendASCII("index.txt"); | 281 base::FilePath index_path = origin_path_.AppendASCII("index.txt"); |
269 | 282 |
270 cache_task_runner_->PostTask( | 283 cache_task_runner_->PostTask( |
271 FROM_HERE, | 284 FROM_HERE, |
272 base::Bind(&SimpleCacheLoader::WriteIndexWriteToFileInPool, | 285 base::Bind(&SimpleCacheLoader::WriteIndexWriteToFileInPool, |
273 this, | 286 this, |
274 tmp_path, | 287 tmp_path, |
275 index_path, | 288 index_path, |
276 serialized, | 289 serialized, |
277 caches, | |
278 callback, | 290 callback, |
279 base::MessageLoopProxy::current())); | 291 base::MessageLoopProxy::current())); |
280 } | 292 } |
281 | 293 |
282 void WriteIndexWriteToFileInPool( | 294 void WriteIndexWriteToFileInPool( |
283 const base::FilePath& tmp_path, | 295 const base::FilePath& tmp_path, |
284 const base::FilePath& index_path, | 296 const base::FilePath& index_path, |
285 const std::string& data, | 297 const std::string& data, |
286 CacheMap* caches, | |
287 const BoolCallback& callback, | 298 const BoolCallback& callback, |
288 const scoped_refptr<base::MessageLoopProxy>& original_loop) { | 299 const scoped_refptr<base::MessageLoopProxy>& original_loop) { |
289 DCHECK(cache_task_runner_->RunsTasksOnCurrentThread()); | 300 DCHECK(cache_task_runner_->RunsTasksOnCurrentThread()); |
290 | 301 |
291 int bytes_written = base::WriteFile(tmp_path, data.c_str(), data.size()); | 302 int bytes_written = base::WriteFile(tmp_path, data.c_str(), data.size()); |
292 if (bytes_written != implicit_cast<int>(data.size())) { | 303 if (bytes_written != implicit_cast<int>(data.size())) { |
293 base::DeleteFile(tmp_path, /* recursive */ false); | 304 base::DeleteFile(tmp_path, /* recursive */ false); |
294 original_loop->PostTask(FROM_HERE, base::Bind(callback, false)); | 305 original_loop->PostTask(FROM_HERE, base::Bind(callback, false)); |
295 } | 306 } |
296 | 307 |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
372 const base::FilePath origin_path_; | 383 const base::FilePath origin_path_; |
373 }; | 384 }; |
374 | 385 |
375 ServiceWorkerCacheStorage::ServiceWorkerCacheStorage( | 386 ServiceWorkerCacheStorage::ServiceWorkerCacheStorage( |
376 const base::FilePath& path, | 387 const base::FilePath& path, |
377 bool memory_only, | 388 bool memory_only, |
378 base::SequencedTaskRunner* cache_task_runner, | 389 base::SequencedTaskRunner* cache_task_runner, |
379 net::URLRequestContext* request_context, | 390 net::URLRequestContext* request_context, |
380 base::WeakPtr<storage::BlobStorageContext> blob_context) | 391 base::WeakPtr<storage::BlobStorageContext> blob_context) |
381 : initialized_(false), | 392 : initialized_(false), |
393 next_cache_id_(0), | |
382 origin_path_(path), | 394 origin_path_(path), |
383 cache_task_runner_(cache_task_runner), | 395 cache_task_runner_(cache_task_runner), |
384 weak_factory_(this) { | 396 weak_factory_(this) { |
385 if (memory_only) | 397 if (memory_only) |
386 cache_loader_ = | 398 cache_loader_ = |
387 new MemoryLoader(cache_task_runner_, request_context, blob_context); | 399 new MemoryLoader(cache_task_runner_, request_context, blob_context); |
388 else | 400 else |
389 cache_loader_ = new SimpleCacheLoader( | 401 cache_loader_ = new SimpleCacheLoader( |
390 origin_path_, cache_task_runner_, request_context, blob_context); | 402 origin_path_, cache_task_runner_, request_context, blob_context); |
391 } | 403 } |
392 | 404 |
393 ServiceWorkerCacheStorage::~ServiceWorkerCacheStorage() { | 405 ServiceWorkerCacheStorage::~ServiceWorkerCacheStorage() { |
406 STLDeleteContainerPairSecondPointers(cache_map_.begin(), cache_map_.end()); | |
394 } | 407 } |
395 | 408 |
396 void ServiceWorkerCacheStorage::CreateCache( | 409 void ServiceWorkerCacheStorage::CreateCache( |
397 const std::string& cache_name, | 410 const std::string& cache_name, |
398 const CacheAndErrorCallback& callback) { | 411 const CacheAndErrorCallback& callback) { |
399 if (!initialized_) { | 412 if (!initialized_) { |
400 LazyInit(base::Bind(&ServiceWorkerCacheStorage::CreateCache, | 413 LazyInit(base::Bind(&ServiceWorkerCacheStorage::CreateCache, |
401 weak_factory_.GetWeakPtr(), | 414 weak_factory_.GetWeakPtr(), |
402 cache_name, | 415 cache_name, |
403 callback)); | 416 callback)); |
404 return; | 417 return; |
405 } | 418 } |
406 | 419 |
407 if (cache_name.empty()) { | 420 if (cache_name.empty()) { |
408 callback.Run(0, CACHE_STORAGE_ERROR_EMPTY_KEY); | 421 callback.Run(-1, CACHE_STORAGE_ERROR_EMPTY_KEY); |
falken
2014/08/26 06:31:33
Should we have a kInvalidCacheId constant?
jkarlin
2014/08/26 12:03:10
Done. Now used in the tests as well.
| |
409 return; | 422 return; |
410 } | 423 } |
411 | 424 |
412 if (GetLoadedCache(cache_name)) { | 425 if (GetLoadedCache(cache_name)) { |
413 callback.Run(0, CACHE_STORAGE_ERROR_EXISTS); | 426 callback.Run(-1, CACHE_STORAGE_ERROR_EXISTS); |
414 return; | 427 return; |
415 } | 428 } |
416 | 429 |
417 cache_loader_->CreateCache( | 430 cache_loader_->CreateCache( |
418 cache_name, | 431 cache_name, |
419 base::Bind(&ServiceWorkerCacheStorage::CreateCacheDidCreateCache, | 432 base::Bind(&ServiceWorkerCacheStorage::CreateCacheDidCreateCache, |
420 weak_factory_.GetWeakPtr(), | 433 weak_factory_.GetWeakPtr(), |
421 cache_name, | 434 cache_name, |
422 callback)); | 435 callback)); |
423 } | 436 } |
424 | 437 |
425 void ServiceWorkerCacheStorage::GetCache( | 438 void ServiceWorkerCacheStorage::GetCache( |
426 const std::string& cache_name, | 439 const std::string& cache_name, |
427 const CacheAndErrorCallback& callback) { | 440 const CacheAndErrorCallback& callback) { |
428 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 441 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
429 | 442 |
430 if (!initialized_) { | 443 if (!initialized_) { |
431 LazyInit(base::Bind(&ServiceWorkerCacheStorage::GetCache, | 444 LazyInit(base::Bind(&ServiceWorkerCacheStorage::GetCache, |
432 weak_factory_.GetWeakPtr(), | 445 weak_factory_.GetWeakPtr(), |
433 cache_name, | 446 cache_name, |
434 callback)); | 447 callback)); |
435 return; | 448 return; |
436 } | 449 } |
437 | 450 |
438 if (cache_name.empty()) { | 451 if (cache_name.empty()) { |
439 callback.Run(0, CACHE_STORAGE_ERROR_EMPTY_KEY); | 452 callback.Run(-1, CACHE_STORAGE_ERROR_EMPTY_KEY); |
440 return; | 453 return; |
441 } | 454 } |
442 | 455 |
443 ServiceWorkerCache* cache = GetLoadedCache(cache_name); | 456 CacheContext* cache_context = GetLoadedCache(cache_name); |
444 if (!cache) { | 457 if (!cache_context) { |
445 callback.Run(0, CACHE_STORAGE_ERROR_NOT_FOUND); | 458 callback.Run(-1, CACHE_STORAGE_ERROR_NOT_FOUND); |
446 return; | 459 return; |
447 } | 460 } |
448 | 461 |
462 ServiceWorkerCache* cache = cache_context->cache.get(); | |
449 cache->CreateBackend(base::Bind(&ServiceWorkerCacheStorage::DidCreateBackend, | 463 cache->CreateBackend(base::Bind(&ServiceWorkerCacheStorage::DidCreateBackend, |
450 weak_factory_.GetWeakPtr(), | 464 weak_factory_.GetWeakPtr(), |
451 cache->AsWeakPtr(), | 465 cache->AsWeakPtr(), |
466 cache_context->id, | |
452 callback)); | 467 callback)); |
453 } | 468 } |
454 | 469 |
455 void ServiceWorkerCacheStorage::HasCache(const std::string& cache_name, | 470 void ServiceWorkerCacheStorage::HasCache(const std::string& cache_name, |
456 const BoolAndErrorCallback& callback) { | 471 const BoolAndErrorCallback& callback) { |
457 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 472 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
458 | 473 |
459 if (!initialized_) { | 474 if (!initialized_) { |
460 LazyInit(base::Bind(&ServiceWorkerCacheStorage::HasCache, | 475 LazyInit(base::Bind(&ServiceWorkerCacheStorage::HasCache, |
461 weak_factory_.GetWeakPtr(), | 476 weak_factory_.GetWeakPtr(), |
(...skipping 23 matching lines...) Expand all Loading... | |
485 cache_name, | 500 cache_name, |
486 callback)); | 501 callback)); |
487 return; | 502 return; |
488 } | 503 } |
489 | 504 |
490 if (cache_name.empty()) { | 505 if (cache_name.empty()) { |
491 callback.Run(false, CACHE_STORAGE_ERROR_EMPTY_KEY); | 506 callback.Run(false, CACHE_STORAGE_ERROR_EMPTY_KEY); |
492 return; | 507 return; |
493 } | 508 } |
494 | 509 |
495 ServiceWorkerCache* cache = GetLoadedCache(cache_name); | 510 scoped_ptr<CacheContext> cache_context(GetLoadedCache(cache_name)); |
falken
2014/08/26 06:31:32
It's a bit subtle that the raw pointer returned by
jkarlin
2014/08/26 12:03:10
Agree. Specifically call .reset() now to make it
| |
496 if (!cache) { | 511 if (!cache_context) { |
497 callback.Run(false, CACHE_STORAGE_ERROR_NOT_FOUND); | 512 callback.Run(false, CACHE_STORAGE_ERROR_NOT_FOUND); |
498 return; | 513 return; |
499 } | 514 } |
500 | 515 |
501 name_map_.erase(cache_name); | 516 name_map_.erase(cache_name); |
502 cache_map_.Remove(cache->id()); // deletes cache | 517 cache_map_.erase(cache_context->id); |
503 | 518 |
504 // Update the Index | 519 // Update the Index |
505 cache_loader_->WriteIndex( | 520 cache_loader_->WriteIndex( |
506 &cache_map_, | 521 cache_map_, |
507 base::Bind(&ServiceWorkerCacheStorage::DeleteCacheDidWriteIndex, | 522 base::Bind(&ServiceWorkerCacheStorage::DeleteCacheDidWriteIndex, |
508 weak_factory_.GetWeakPtr(), | 523 weak_factory_.GetWeakPtr(), |
509 cache_name, | 524 cache_name, |
510 callback)); | 525 callback)); |
511 } | 526 } |
512 | 527 |
513 void ServiceWorkerCacheStorage::EnumerateCaches( | 528 void ServiceWorkerCacheStorage::EnumerateCaches( |
514 const StringsAndErrorCallback& callback) { | 529 const StringsAndErrorCallback& callback) { |
515 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 530 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
516 | 531 |
517 if (!initialized_) { | 532 if (!initialized_) { |
518 LazyInit(base::Bind(&ServiceWorkerCacheStorage::EnumerateCaches, | 533 LazyInit(base::Bind(&ServiceWorkerCacheStorage::EnumerateCaches, |
519 weak_factory_.GetWeakPtr(), | 534 weak_factory_.GetWeakPtr(), |
520 callback)); | 535 callback)); |
521 return; | 536 return; |
522 } | 537 } |
523 | 538 |
524 std::vector<std::string> names; | 539 std::vector<std::string> names; |
525 for (NameMap::const_iterator it = name_map_.begin(); it != name_map_.end(); | 540 for (NameMap::const_iterator it = name_map_.begin(); it != name_map_.end(); |
526 ++it) { | 541 ++it) { |
527 names.push_back(it->first); | 542 names.push_back(it->first); |
528 } | 543 } |
529 | 544 |
530 callback.Run(names, CACHE_STORAGE_ERROR_NO_ERROR); | 545 callback.Run(names, CACHE_STORAGE_ERROR_NO_ERROR); |
531 } | 546 } |
532 | 547 |
533 void ServiceWorkerCacheStorage::DidCreateBackend( | 548 void ServiceWorkerCacheStorage::DidCreateBackend( |
534 base::WeakPtr<ServiceWorkerCache> cache, | 549 base::WeakPtr<ServiceWorkerCache> cache, |
550 CacheID cache_id, | |
535 const CacheAndErrorCallback& callback, | 551 const CacheAndErrorCallback& callback, |
536 bool success) { | 552 bool success) { |
537 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 553 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
538 | 554 |
539 if (!success || !cache) { | 555 if (!success || !cache) { |
540 // TODO(jkarlin): This should delete the directory and try again in case | 556 // TODO(jkarlin): This should delete the directory and try again in case |
541 // the cache is simply corrupt. | 557 // the cache is simply corrupt. |
542 callback.Run(0, CACHE_STORAGE_ERROR_STORAGE); | 558 callback.Run(-1, CACHE_STORAGE_ERROR_STORAGE); |
543 return; | 559 return; |
544 } | 560 } |
545 callback.Run(cache->id(), CACHE_STORAGE_ERROR_NO_ERROR); | 561 callback.Run(cache_id, CACHE_STORAGE_ERROR_NO_ERROR); |
546 } | 562 } |
547 | 563 |
548 // Init is run lazily so that it is called on the proper MessageLoop. | 564 // Init is run lazily so that it is called on the proper MessageLoop. |
549 void ServiceWorkerCacheStorage::LazyInit(const base::Closure& callback) { | 565 void ServiceWorkerCacheStorage::LazyInit(const base::Closure& callback) { |
550 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 566 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
551 DCHECK(!initialized_); | 567 DCHECK(!initialized_); |
552 | 568 |
553 init_callbacks_.push_back(callback); | 569 init_callbacks_.push_back(callback); |
554 | 570 |
555 // If this isn't the first call to LazyInit then return as the initialization | 571 // If this isn't the first call to LazyInit then return as the initialization |
(...skipping 28 matching lines...) Expand all Loading... | |
584 | 600 |
585 std::vector<std::string>::const_iterator iter = indexed_cache_names->begin(); | 601 std::vector<std::string>::const_iterator iter = indexed_cache_names->begin(); |
586 std::vector<std::string>::const_iterator iter_next = iter + 1; | 602 std::vector<std::string>::const_iterator iter_next = iter + 1; |
587 | 603 |
588 cache_loader_->LoadCache( | 604 cache_loader_->LoadCache( |
589 *iter, | 605 *iter, |
590 base::Bind(&ServiceWorkerCacheStorage::LazyInitIterateAndLoadCacheName, | 606 base::Bind(&ServiceWorkerCacheStorage::LazyInitIterateAndLoadCacheName, |
591 weak_factory_.GetWeakPtr(), | 607 weak_factory_.GetWeakPtr(), |
592 callback, | 608 callback, |
593 base::Passed(indexed_cache_names.Pass()), | 609 base::Passed(indexed_cache_names.Pass()), |
594 iter_next)); | 610 iter_next, |
611 *iter)); | |
595 } | 612 } |
596 | 613 |
597 void ServiceWorkerCacheStorage::LazyInitIterateAndLoadCacheName( | 614 void ServiceWorkerCacheStorage::LazyInitIterateAndLoadCacheName( |
598 const base::Closure& callback, | 615 const base::Closure& callback, |
599 scoped_ptr<std::vector<std::string> > indexed_cache_names, | 616 scoped_ptr<std::vector<std::string> > indexed_cache_names, |
600 const std::vector<std::string>::const_iterator& iter, | 617 const std::vector<std::string>::const_iterator& iter, |
618 const std::string& cache_name, | |
601 scoped_ptr<ServiceWorkerCache> cache) { | 619 scoped_ptr<ServiceWorkerCache> cache) { |
602 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 620 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
603 | 621 |
604 if (cache) | 622 if (cache) |
605 AddCacheToMaps(cache.Pass()); | 623 AddCacheToMaps(cache_name, cache.Pass()); |
606 | 624 |
607 if (iter == indexed_cache_names->end()) { | 625 if (iter == indexed_cache_names->end()) { |
608 LazyInitDone(); | 626 LazyInitDone(); |
609 return; | 627 return; |
610 } | 628 } |
611 | 629 |
612 std::vector<std::string>::const_iterator iter_next = iter + 1; | 630 std::vector<std::string>::const_iterator iter_next = iter + 1; |
613 cache_loader_->LoadCache( | 631 cache_loader_->LoadCache( |
614 *iter, | 632 *iter, |
615 base::Bind(&ServiceWorkerCacheStorage::LazyInitIterateAndLoadCacheName, | 633 base::Bind(&ServiceWorkerCacheStorage::LazyInitIterateAndLoadCacheName, |
616 weak_factory_.GetWeakPtr(), | 634 weak_factory_.GetWeakPtr(), |
617 callback, | 635 callback, |
618 base::Passed(indexed_cache_names.Pass()), | 636 base::Passed(indexed_cache_names.Pass()), |
619 iter_next)); | 637 iter_next, |
638 *iter)); | |
620 } | 639 } |
621 | 640 |
622 void ServiceWorkerCacheStorage::LazyInitDone() { | 641 void ServiceWorkerCacheStorage::LazyInitDone() { |
623 initialized_ = true; | 642 initialized_ = true; |
624 for (std::vector<base::Closure>::iterator it = init_callbacks_.begin(); | 643 for (std::vector<base::Closure>::iterator it = init_callbacks_.begin(); |
625 it != init_callbacks_.end(); | 644 it != init_callbacks_.end(); |
626 ++it) { | 645 ++it) { |
627 it->Run(); | 646 it->Run(); |
628 } | 647 } |
629 init_callbacks_.clear(); | 648 init_callbacks_.clear(); |
630 } | 649 } |
631 | 650 |
632 void ServiceWorkerCacheStorage::AddCacheToMaps( | 651 ServiceWorkerCacheStorage::CacheContext* |
633 scoped_ptr<ServiceWorkerCache> cache) { | 652 ServiceWorkerCacheStorage::AddCacheToMaps( |
653 const std::string& cache_name, | |
654 scoped_ptr<ServiceWorkerCache> sw_cache) { | |
falken
2014/08/26 06:31:32
nit: Why rename? The other ServiceWorkerCache obje
jkarlin
2014/08/26 12:03:10
Done.
| |
634 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 655 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
635 | 656 |
636 ServiceWorkerCache* cache_ptr = cache.release(); | 657 CacheID id = next_cache_id_++; |
637 CacheID id = cache_map_.Add(cache_ptr); | 658 CacheContext* cache_context = |
638 name_map_.insert(std::make_pair(cache_ptr->name(), id)); | 659 new CacheContext(cache_name, id, sw_cache.Pass()); |
639 cache_ptr->set_id(id); | 660 cache_map_.insert(std::make_pair(id, cache_context)); // Takes ownership |
661 name_map_.insert(std::make_pair(cache_name, id)); | |
662 return cache_context; | |
640 } | 663 } |
641 | 664 |
642 void ServiceWorkerCacheStorage::CreateCacheDidCreateCache( | 665 void ServiceWorkerCacheStorage::CreateCacheDidCreateCache( |
643 const std::string& cache_name, | 666 const std::string& cache_name, |
644 const CacheAndErrorCallback& callback, | 667 const CacheAndErrorCallback& callback, |
645 scoped_ptr<ServiceWorkerCache> cache) { | 668 scoped_ptr<ServiceWorkerCache> cache) { |
646 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 669 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
647 | 670 |
648 if (!cache) { | 671 if (!cache) { |
649 callback.Run(0, CACHE_STORAGE_ERROR_STORAGE); | 672 callback.Run(-1, CACHE_STORAGE_ERROR_CLOSING); |
650 return; | 673 return; |
651 } | 674 } |
652 | 675 |
653 base::WeakPtr<ServiceWorkerCache> cache_ptr = cache->AsWeakPtr(); | 676 CacheContext* cache_context = AddCacheToMaps(cache_name, cache.Pass()); |
654 | |
655 AddCacheToMaps(cache.Pass()); | |
656 | 677 |
657 cache_loader_->WriteIndex( | 678 cache_loader_->WriteIndex( |
658 &cache_map_, | 679 cache_map_, |
659 base::Bind( | 680 base::Bind(&ServiceWorkerCacheStorage::CreateCacheDidWriteIndex, |
660 &ServiceWorkerCacheStorage::CreateCacheDidWriteIndex, | 681 weak_factory_.GetWeakPtr(), |
661 weak_factory_.GetWeakPtr(), | 682 callback, |
662 callback, | 683 cache_context->cache->AsWeakPtr(), |
663 cache_ptr)); // cache is owned by this->CacheMap and won't be deleted | 684 cache_context->id)); |
664 } | 685 } |
665 | 686 |
666 void ServiceWorkerCacheStorage::CreateCacheDidWriteIndex( | 687 void ServiceWorkerCacheStorage::CreateCacheDidWriteIndex( |
667 const CacheAndErrorCallback& callback, | 688 const CacheAndErrorCallback& callback, |
668 base::WeakPtr<ServiceWorkerCache> cache, | 689 base::WeakPtr<ServiceWorkerCache> cache, |
690 CacheID id, | |
669 bool success) { | 691 bool success) { |
670 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 692 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
671 if (!cache) { | 693 if (!cache) { |
672 callback.Run(false, CACHE_STORAGE_ERROR_STORAGE); | 694 callback.Run(false, CACHE_STORAGE_ERROR_CLOSING); |
673 return; | 695 return; |
674 } | 696 } |
675 cache->CreateBackend(base::Bind(&ServiceWorkerCacheStorage::DidCreateBackend, | 697 cache->CreateBackend(base::Bind(&ServiceWorkerCacheStorage::DidCreateBackend, |
676 weak_factory_.GetWeakPtr(), | 698 weak_factory_.GetWeakPtr(), |
677 cache, | 699 cache, |
700 id, | |
678 callback)); | 701 callback)); |
679 } | 702 } |
680 | 703 |
681 void ServiceWorkerCacheStorage::DeleteCacheDidWriteIndex( | 704 void ServiceWorkerCacheStorage::DeleteCacheDidWriteIndex( |
682 const std::string& cache_name, | 705 const std::string& cache_name, |
683 const BoolAndErrorCallback& callback, | 706 const BoolAndErrorCallback& callback, |
684 bool success) { | 707 bool success) { |
685 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 708 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
686 | 709 |
687 cache_loader_->CleanUpDeletedCache( | 710 cache_loader_->CleanUpDeletedCache( |
688 cache_name, | 711 cache_name, |
689 base::Bind(&ServiceWorkerCacheStorage::DeleteCacheDidCleanUp, | 712 base::Bind(&ServiceWorkerCacheStorage::DeleteCacheDidCleanUp, |
690 weak_factory_.GetWeakPtr(), | 713 weak_factory_.GetWeakPtr(), |
691 callback)); | 714 callback)); |
692 } | 715 } |
693 | 716 |
694 void ServiceWorkerCacheStorage::DeleteCacheDidCleanUp( | 717 void ServiceWorkerCacheStorage::DeleteCacheDidCleanUp( |
695 const BoolAndErrorCallback& callback, | 718 const BoolAndErrorCallback& callback, |
696 bool success) { | 719 bool success) { |
697 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 720 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
698 | 721 |
699 callback.Run(true, CACHE_STORAGE_ERROR_NO_ERROR); | 722 callback.Run(true, CACHE_STORAGE_ERROR_NO_ERROR); |
700 } | 723 } |
701 | 724 |
702 ServiceWorkerCache* ServiceWorkerCacheStorage::GetLoadedCache( | 725 ServiceWorkerCacheStorage::CacheContext* |
703 const std::string& cache_name) const { | 726 ServiceWorkerCacheStorage::GetLoadedCache(const std::string& cache_name) const { |
704 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 727 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
705 DCHECK(initialized_); | 728 DCHECK(initialized_); |
706 | 729 |
707 NameMap::const_iterator it = name_map_.find(cache_name); | 730 NameMap::const_iterator name_iter = name_map_.find(cache_name); |
708 if (it == name_map_.end()) | 731 if (name_iter == name_map_.end()) |
709 return NULL; | 732 return NULL; |
710 | 733 |
711 ServiceWorkerCache* cache = cache_map_.Lookup(it->second); | 734 CacheMap::const_iterator map_iter = cache_map_.find(name_iter->second); |
712 DCHECK(cache); | 735 DCHECK(map_iter != cache_map_.end()); |
713 return cache; | 736 return map_iter->second; |
714 } | 737 } |
715 | 738 |
716 } // namespace content | 739 } // namespace content |
OLD | NEW |