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/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" |
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/stl_util.h" |
14 #include "base/strings/string_number_conversions.h" | 14 #include "base/strings/string_number_conversions.h" |
15 #include "base/strings/string_util.h" | 15 #include "base/strings/string_util.h" |
16 #include "content/browser/service_worker/service_worker_cache.h" | 16 #include "content/browser/service_worker/service_worker_cache.h" |
17 #include "content/browser/service_worker/service_worker_cache.pb.h" | 17 #include "content/browser/service_worker/service_worker_cache.pb.h" |
18 #include "content/public/browser/browser_thread.h" | 18 #include "content/public/browser/browser_thread.h" |
19 #include "net/base/directory_lister.h" | 19 #include "net/base/directory_lister.h" |
20 #include "net/base/net_errors.h" | 20 #include "net/base/net_errors.h" |
21 #include "webkit/browser/blob/blob_storage_context.h" | 21 #include "webkit/browser/blob/blob_storage_context.h" |
22 | 22 |
23 namespace content { | 23 namespace content { |
24 | 24 |
25 // static | |
26 const int ServiceWorkerCacheStorage::kInvalidCacheID = -1; | |
27 | |
28 // The meta information related to each ServiceWorkerCache that the | |
29 // ServiceWorkerCacheManager needs to keep track of. | |
30 // TODO(jkarlin): Add reference counting so that the deletion of javascript | |
31 // objects can delete the ServiceWorkerCache. | |
32 struct ServiceWorkerCacheStorage::CacheContext { | |
33 CacheContext(const std::string& name, | |
34 CacheID id, | |
35 scoped_ptr<ServiceWorkerCache> cache) | |
36 : name(name), id(id), cache(cache.Pass()) {} | |
37 std::string name; | |
38 CacheID id; | |
39 scoped_ptr<ServiceWorkerCache> cache; | |
40 }; | |
41 | 25 |
42 // Handles the loading and clean up of ServiceWorkerCache objects. The | 26 // Handles the loading and clean up of ServiceWorkerCache objects. The |
43 // callback of every public method is guaranteed to be called. | 27 // callback of every public method is guaranteed to be called. |
44 class ServiceWorkerCacheStorage::CacheLoader { | 28 class ServiceWorkerCacheStorage::CacheLoader { |
45 public: | 29 public: |
46 typedef base::Callback<void(scoped_ptr<ServiceWorkerCache>)> CacheCallback; | 30 typedef base::Callback<void(const scoped_refptr<ServiceWorkerCache>&)> |
| 31 CacheCallback; |
47 typedef base::Callback<void(bool)> BoolCallback; | 32 typedef base::Callback<void(bool)> BoolCallback; |
48 typedef base::Callback<void(scoped_ptr<std::vector<std::string> >)> | 33 typedef base::Callback<void(scoped_ptr<std::vector<std::string> >)> |
49 StringsCallback; | 34 StringsCallback; |
50 | 35 |
51 CacheLoader(base::SequencedTaskRunner* cache_task_runner, | 36 CacheLoader(base::SequencedTaskRunner* cache_task_runner, |
52 net::URLRequestContext* request_context, | 37 net::URLRequestContext* request_context, |
53 base::WeakPtr<storage::BlobStorageContext> blob_context) | 38 base::WeakPtr<storage::BlobStorageContext> blob_context) |
54 : cache_task_runner_(cache_task_runner), | 39 : cache_task_runner_(cache_task_runner), |
55 request_context_(request_context), | 40 request_context_(request_context), |
56 blob_context_(blob_context) {} | 41 blob_context_(blob_context) {} |
57 | 42 |
58 virtual ~CacheLoader() {} | 43 virtual ~CacheLoader() {} |
59 | 44 |
60 // Loads the given cache_name, the cache is NULL if it fails. If the cache | 45 // Loads the given cache_name, the cache is NULL if it fails. If the cache |
61 // doesn't exist a new one is created. | 46 // doesn't exist a new one is created. |
62 virtual scoped_ptr<ServiceWorkerCache> CreateServiceWorkerCache( | 47 virtual scoped_refptr<ServiceWorkerCache> CreateServiceWorkerCache( |
63 const std::string& cache_name) = 0; | 48 const std::string& cache_name) = 0; |
64 | 49 |
65 // 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. |
66 virtual void CreateCache(const std::string& cache_name, | 51 virtual void CreateCache(const std::string& cache_name, |
67 const CacheCallback& callback) = 0; | 52 const CacheCallback& callback) = 0; |
68 | 53 |
69 // 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 |
70 // removing the cache's directory. | 55 // removing the cache's directory. |
71 virtual void CleanUpDeletedCache(const std::string& key, | 56 virtual void CleanUpDeletedCache(const std::string& key, |
72 const BoolCallback& callback) = 0; | 57 const BoolCallback& callback) = 0; |
73 | 58 |
74 // Writes the cache names (and sizes) to disk if applicable. | 59 // Writes the cache names (and sizes) to disk if applicable. |
75 virtual void WriteIndex(const CacheMap& caches, | 60 virtual void WriteIndex(const CacheMap& caches, |
76 const BoolCallback& callback) = 0; | 61 const BoolCallback& callback) = 0; |
77 | 62 |
78 // Loads the cache names from disk if applicable. | 63 // Loads the cache names from disk if applicable. |
79 virtual void LoadIndex(scoped_ptr<std::vector<std::string> > cache_names, | 64 virtual void LoadIndex(scoped_ptr<std::vector<std::string> > cache_names, |
80 const StringsCallback& callback) = 0; | 65 const StringsCallback& callback) = 0; |
81 | 66 |
82 protected: | 67 protected: |
83 scoped_refptr<base::SequencedTaskRunner> cache_task_runner_; | 68 scoped_refptr<base::SequencedTaskRunner> cache_task_runner_; |
84 net::URLRequestContext* request_context_; | 69 net::URLRequestContext* request_context_; |
85 base::WeakPtr<storage::BlobStorageContext> blob_context_; | 70 base::WeakPtr<storage::BlobStorageContext> blob_context_; |
86 }; | 71 }; |
87 | 72 |
| 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 |
| 75 // used again. Therefore this class holds a reference to each cache until the |
| 76 // cache is deleted. |
88 class ServiceWorkerCacheStorage::MemoryLoader | 77 class ServiceWorkerCacheStorage::MemoryLoader |
89 : public ServiceWorkerCacheStorage::CacheLoader { | 78 : public ServiceWorkerCacheStorage::CacheLoader { |
90 public: | 79 public: |
91 MemoryLoader(base::SequencedTaskRunner* cache_task_runner, | 80 MemoryLoader(base::SequencedTaskRunner* cache_task_runner, |
92 net::URLRequestContext* request_context, | 81 net::URLRequestContext* request_context, |
93 base::WeakPtr<storage::BlobStorageContext> blob_context) | 82 base::WeakPtr<storage::BlobStorageContext> blob_context) |
94 : CacheLoader(cache_task_runner, request_context, blob_context) {} | 83 : CacheLoader(cache_task_runner, request_context, blob_context) {} |
95 | 84 |
96 virtual scoped_ptr<ServiceWorkerCache> CreateServiceWorkerCache( | 85 virtual scoped_refptr<ServiceWorkerCache> CreateServiceWorkerCache( |
97 const std::string& cache_name) OVERRIDE { | 86 const std::string& cache_name) OVERRIDE { |
98 return ServiceWorkerCache::CreateMemoryCache(request_context_, | 87 return ServiceWorkerCache::CreateMemoryCache(request_context_, |
99 blob_context_); | 88 blob_context_); |
100 } | 89 } |
101 | 90 |
102 virtual void CreateCache(const std::string& cache_name, | 91 virtual void CreateCache(const std::string& cache_name, |
103 const CacheCallback& callback) OVERRIDE { | 92 const CacheCallback& callback) OVERRIDE { |
104 callback.Run(CreateServiceWorkerCache(cache_name).Pass()); | 93 scoped_refptr<ServiceWorkerCache> cache = |
| 94 ServiceWorkerCache::CreateMemoryCache(request_context_, blob_context_); |
| 95 cache_refs_.insert(std::make_pair(cache_name, cache)); |
| 96 callback.Run(cache); |
105 } | 97 } |
106 | 98 |
107 virtual void CleanUpDeletedCache(const std::string& cache_name, | 99 virtual void CleanUpDeletedCache(const std::string& cache_name, |
108 const BoolCallback& callback) OVERRIDE { | 100 const BoolCallback& callback) OVERRIDE { |
| 101 CacheRefMap::iterator it = cache_refs_.find(cache_name); |
| 102 DCHECK(it != cache_refs_.end()); |
| 103 cache_refs_.erase(it); |
109 callback.Run(true); | 104 callback.Run(true); |
110 } | 105 } |
111 | 106 |
112 virtual void WriteIndex(const CacheMap& caches, | 107 virtual void WriteIndex(const CacheMap& caches, |
113 const BoolCallback& callback) OVERRIDE { | 108 const BoolCallback& callback) OVERRIDE { |
114 callback.Run(false); | 109 callback.Run(false); |
115 } | 110 } |
116 | 111 |
117 virtual void LoadIndex(scoped_ptr<std::vector<std::string> > cache_names, | 112 virtual void LoadIndex(scoped_ptr<std::vector<std::string> > cache_names, |
118 const StringsCallback& callback) OVERRIDE { | 113 const StringsCallback& callback) OVERRIDE { |
119 callback.Run(cache_names.Pass()); | 114 callback.Run(cache_names.Pass()); |
120 } | 115 } |
121 | 116 |
122 private: | 117 private: |
| 118 typedef std::map<std::string, scoped_refptr<ServiceWorkerCache> > CacheRefMap; |
123 virtual ~MemoryLoader() {} | 119 virtual ~MemoryLoader() {} |
| 120 |
| 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 |
| 123 // freed. |
| 124 CacheRefMap cache_refs_; |
124 }; | 125 }; |
125 | 126 |
126 class ServiceWorkerCacheStorage::SimpleCacheLoader | 127 class ServiceWorkerCacheStorage::SimpleCacheLoader |
127 : public ServiceWorkerCacheStorage::CacheLoader { | 128 : public ServiceWorkerCacheStorage::CacheLoader { |
128 public: | 129 public: |
129 SimpleCacheLoader(const base::FilePath& origin_path, | 130 SimpleCacheLoader(const base::FilePath& origin_path, |
130 base::SequencedTaskRunner* cache_task_runner, | 131 base::SequencedTaskRunner* cache_task_runner, |
131 net::URLRequestContext* request_context, | 132 net::URLRequestContext* request_context, |
132 base::WeakPtr<storage::BlobStorageContext> blob_context) | 133 base::WeakPtr<storage::BlobStorageContext> blob_context) |
133 : CacheLoader(cache_task_runner, request_context, blob_context), | 134 : CacheLoader(cache_task_runner, request_context, blob_context), |
134 origin_path_(origin_path), | 135 origin_path_(origin_path), |
135 weak_ptr_factory_(this) {} | 136 weak_ptr_factory_(this) {} |
136 | 137 |
137 virtual scoped_ptr<ServiceWorkerCache> CreateServiceWorkerCache( | 138 virtual scoped_refptr<ServiceWorkerCache> CreateServiceWorkerCache( |
138 const std::string& cache_name) OVERRIDE { | 139 const std::string& cache_name) OVERRIDE { |
139 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 140 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
140 | 141 |
141 return ServiceWorkerCache::CreatePersistentCache( | 142 return ServiceWorkerCache::CreatePersistentCache( |
142 CreatePersistentCachePath(origin_path_, cache_name), | 143 CreatePersistentCachePath(origin_path_, cache_name), |
143 request_context_, | 144 request_context_, |
144 blob_context_); | 145 blob_context_); |
145 } | 146 } |
146 | 147 |
147 virtual void CreateCache(const std::string& cache_name, | 148 virtual void CreateCache(const std::string& cache_name, |
(...skipping 21 matching lines...) Expand all Loading... |
169 if (base::PathExists(cache_path)) | 170 if (base::PathExists(cache_path)) |
170 base::DeleteFile(cache_path, /* recursive */ true); | 171 base::DeleteFile(cache_path, /* recursive */ true); |
171 return base::CreateDirectory(cache_path); | 172 return base::CreateDirectory(cache_path); |
172 } | 173 } |
173 | 174 |
174 static void CreateCachePreppedDir(const std::string& cache_name, | 175 static void CreateCachePreppedDir(const std::string& cache_name, |
175 const CacheCallback& callback, | 176 const CacheCallback& callback, |
176 base::WeakPtr<SimpleCacheLoader> loader, | 177 base::WeakPtr<SimpleCacheLoader> loader, |
177 bool success) { | 178 bool success) { |
178 if (!success || !loader) { | 179 if (!success || !loader) { |
179 callback.Run(scoped_ptr<ServiceWorkerCache>()); | 180 callback.Run(scoped_refptr<ServiceWorkerCache>()); |
180 return; | 181 return; |
181 } | 182 } |
182 | 183 |
183 callback.Run(loader->CreateServiceWorkerCache(cache_name)); | 184 callback.Run(loader->CreateServiceWorkerCache(cache_name)); |
184 } | 185 } |
185 | 186 |
186 virtual void CleanUpDeletedCache(const std::string& cache_name, | 187 virtual void CleanUpDeletedCache(const std::string& cache_name, |
187 const BoolCallback& callback) OVERRIDE { | 188 const BoolCallback& callback) OVERRIDE { |
188 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 189 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
189 | 190 |
(...skipping 21 matching lines...) Expand all Loading... |
211 const BoolCallback& callback) OVERRIDE { | 212 const BoolCallback& callback) OVERRIDE { |
212 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 213 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
213 | 214 |
214 // 1. Create the index file as a string. (WriteIndex) | 215 // 1. Create the index file as a string. (WriteIndex) |
215 // 2. Write the file to disk. (WriteIndexWriteToFileInPool) | 216 // 2. Write the file to disk. (WriteIndexWriteToFileInPool) |
216 | 217 |
217 ServiceWorkerCacheStorageIndex index; | 218 ServiceWorkerCacheStorageIndex index; |
218 | 219 |
219 for (CacheMap::const_iterator it = caches.begin(); it != caches.end(); | 220 for (CacheMap::const_iterator it = caches.begin(); it != caches.end(); |
220 ++it) { | 221 ++it) { |
221 const CacheContext* cache = it->second; | |
222 ServiceWorkerCacheStorageIndex::Cache* index_cache = index.add_cache(); | 222 ServiceWorkerCacheStorageIndex::Cache* index_cache = index.add_cache(); |
223 index_cache->set_name(cache->name); | 223 index_cache->set_name(it->first); |
224 index_cache->set_size(0); // TODO(jkarlin): Make this real. | 224 index_cache->set_size(0); // TODO(jkarlin): Make this real. |
225 } | 225 } |
226 | 226 |
227 std::string serialized; | 227 std::string serialized; |
228 bool success = index.SerializeToString(&serialized); | 228 bool success = index.SerializeToString(&serialized); |
229 DCHECK(success); | 229 DCHECK(success); |
230 | 230 |
231 base::FilePath tmp_path = origin_path_.AppendASCII("index.txt.tmp"); | 231 base::FilePath tmp_path = origin_path_.AppendASCII("index.txt.tmp"); |
232 base::FilePath index_path = origin_path_.AppendASCII("index.txt"); | 232 base::FilePath index_path = origin_path_.AppendASCII("index.txt"); |
233 | 233 |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
330 base::WeakPtrFactory<SimpleCacheLoader> weak_ptr_factory_; | 330 base::WeakPtrFactory<SimpleCacheLoader> weak_ptr_factory_; |
331 }; | 331 }; |
332 | 332 |
333 ServiceWorkerCacheStorage::ServiceWorkerCacheStorage( | 333 ServiceWorkerCacheStorage::ServiceWorkerCacheStorage( |
334 const base::FilePath& path, | 334 const base::FilePath& path, |
335 bool memory_only, | 335 bool memory_only, |
336 base::SequencedTaskRunner* cache_task_runner, | 336 base::SequencedTaskRunner* cache_task_runner, |
337 net::URLRequestContext* request_context, | 337 net::URLRequestContext* request_context, |
338 base::WeakPtr<storage::BlobStorageContext> blob_context) | 338 base::WeakPtr<storage::BlobStorageContext> blob_context) |
339 : initialized_(false), | 339 : initialized_(false), |
340 next_cache_id_(0), | |
341 origin_path_(path), | 340 origin_path_(path), |
342 cache_task_runner_(cache_task_runner), | 341 cache_task_runner_(cache_task_runner), |
| 342 memory_only_(memory_only), |
343 weak_factory_(this) { | 343 weak_factory_(this) { |
344 if (memory_only) | 344 if (memory_only) |
345 cache_loader_.reset(new MemoryLoader( | 345 cache_loader_.reset(new MemoryLoader( |
346 cache_task_runner_.get(), request_context, blob_context)); | 346 cache_task_runner_.get(), request_context, blob_context)); |
347 else | 347 else |
348 cache_loader_.reset(new SimpleCacheLoader( | 348 cache_loader_.reset(new SimpleCacheLoader( |
349 origin_path_, cache_task_runner_.get(), request_context, blob_context)); | 349 origin_path_, cache_task_runner_.get(), request_context, blob_context)); |
350 } | 350 } |
351 | 351 |
352 ServiceWorkerCacheStorage::~ServiceWorkerCacheStorage() { | 352 ServiceWorkerCacheStorage::~ServiceWorkerCacheStorage() { |
353 STLDeleteContainerPairSecondPointers(cache_map_.begin(), cache_map_.end()); | |
354 } | 353 } |
355 | 354 |
356 void ServiceWorkerCacheStorage::CreateCache( | 355 void ServiceWorkerCacheStorage::CreateCache( |
357 const std::string& cache_name, | 356 const std::string& cache_name, |
358 const CacheAndErrorCallback& callback) { | 357 const CacheAndErrorCallback& callback) { |
359 if (!initialized_) { | 358 if (!initialized_) { |
360 LazyInit(base::Bind(&ServiceWorkerCacheStorage::CreateCache, | 359 LazyInit(base::Bind(&ServiceWorkerCacheStorage::CreateCache, |
361 weak_factory_.GetWeakPtr(), | 360 weak_factory_.GetWeakPtr(), |
362 cache_name, | 361 cache_name, |
363 callback)); | 362 callback)); |
364 return; | 363 return; |
365 } | 364 } |
366 | 365 |
367 if (GetLoadedCache(cache_name)) { | 366 if (cache_map_.find(cache_name) != cache_map_.end()) { |
368 callback.Run(kInvalidCacheID, CACHE_STORAGE_ERROR_EXISTS); | 367 callback.Run(scoped_refptr<ServiceWorkerCache>(), |
| 368 CACHE_STORAGE_ERROR_EXISTS); |
369 return; | 369 return; |
370 } | 370 } |
371 | 371 |
372 cache_loader_->CreateCache( | 372 cache_loader_->CreateCache( |
373 cache_name, | 373 cache_name, |
374 base::Bind(&ServiceWorkerCacheStorage::CreateCacheDidCreateCache, | 374 base::Bind(&ServiceWorkerCacheStorage::CreateCacheDidCreateCache, |
375 weak_factory_.GetWeakPtr(), | 375 weak_factory_.GetWeakPtr(), |
376 cache_name, | 376 cache_name, |
377 callback)); | 377 callback)); |
378 } | 378 } |
379 | 379 |
380 void ServiceWorkerCacheStorage::GetCache( | 380 void ServiceWorkerCacheStorage::GetCache( |
381 const std::string& cache_name, | 381 const std::string& cache_name, |
382 const CacheAndErrorCallback& callback) { | 382 const CacheAndErrorCallback& callback) { |
383 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 383 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
384 | 384 |
385 if (!initialized_) { | 385 if (!initialized_) { |
386 LazyInit(base::Bind(&ServiceWorkerCacheStorage::GetCache, | 386 LazyInit(base::Bind(&ServiceWorkerCacheStorage::GetCache, |
387 weak_factory_.GetWeakPtr(), | 387 weak_factory_.GetWeakPtr(), |
388 cache_name, | 388 cache_name, |
389 callback)); | 389 callback)); |
390 return; | 390 return; |
391 } | 391 } |
392 | 392 |
393 CacheContext* cache_context = GetLoadedCache(cache_name); | 393 scoped_refptr<ServiceWorkerCache> cache = GetLoadedCache(cache_name); |
394 if (!cache_context) { | 394 if (!cache.get()) { |
395 callback.Run(kInvalidCacheID, CACHE_STORAGE_ERROR_NOT_FOUND); | 395 callback.Run(scoped_refptr<ServiceWorkerCache>(), |
| 396 CACHE_STORAGE_ERROR_NOT_FOUND); |
396 return; | 397 return; |
397 } | 398 } |
398 | 399 |
399 callback.Run(cache_context->id, CACHE_STORAGE_ERROR_NO_ERROR); | 400 callback.Run(cache, CACHE_STORAGE_ERROR_NO_ERROR); |
400 } | 401 } |
401 | 402 |
402 void ServiceWorkerCacheStorage::HasCache(const std::string& cache_name, | 403 void ServiceWorkerCacheStorage::HasCache(const std::string& cache_name, |
403 const BoolAndErrorCallback& callback) { | 404 const BoolAndErrorCallback& callback) { |
404 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 405 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
405 | 406 |
406 if (!initialized_) { | 407 if (!initialized_) { |
407 LazyInit(base::Bind(&ServiceWorkerCacheStorage::HasCache, | 408 LazyInit(base::Bind(&ServiceWorkerCacheStorage::HasCache, |
408 weak_factory_.GetWeakPtr(), | 409 weak_factory_.GetWeakPtr(), |
409 cache_name, | 410 cache_name, |
410 callback)); | 411 callback)); |
411 return; | 412 return; |
412 } | 413 } |
413 | 414 |
414 bool has_cache = GetLoadedCache(cache_name) != NULL; | 415 bool has_cache = cache_map_.find(cache_name) != cache_map_.end(); |
415 | 416 |
416 callback.Run(has_cache, CACHE_STORAGE_ERROR_NO_ERROR); | 417 callback.Run(has_cache, CACHE_STORAGE_ERROR_NO_ERROR); |
417 } | 418 } |
418 | 419 |
419 void ServiceWorkerCacheStorage::DeleteCache( | 420 void ServiceWorkerCacheStorage::DeleteCache( |
420 const std::string& cache_name, | 421 const std::string& cache_name, |
421 const BoolAndErrorCallback& callback) { | 422 const BoolAndErrorCallback& callback) { |
422 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 423 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
423 | 424 |
424 if (!initialized_) { | 425 if (!initialized_) { |
425 LazyInit(base::Bind(&ServiceWorkerCacheStorage::DeleteCache, | 426 LazyInit(base::Bind(&ServiceWorkerCacheStorage::DeleteCache, |
426 weak_factory_.GetWeakPtr(), | 427 weak_factory_.GetWeakPtr(), |
427 cache_name, | 428 cache_name, |
428 callback)); | 429 callback)); |
429 return; | 430 return; |
430 } | 431 } |
431 | 432 |
432 scoped_ptr<CacheContext> cache_context(GetLoadedCache(cache_name)); | 433 |
433 if (!cache_context) { | 434 CacheMap::iterator it = cache_map_.find(cache_name); |
| 435 if (it == cache_map_.end()) { |
434 callback.Run(false, CACHE_STORAGE_ERROR_NOT_FOUND); | 436 callback.Run(false, CACHE_STORAGE_ERROR_NOT_FOUND); |
435 return; | 437 return; |
436 } | 438 } |
437 | 439 |
438 name_map_.erase(cache_name); | 440 base::WeakPtr<ServiceWorkerCache> cache = it->second; |
439 cache_map_.erase(cache_context->id); | 441 if (cache) |
440 cache_context.reset(); | 442 cache->Close(); |
| 443 |
| 444 cache_map_.erase(it); |
441 | 445 |
442 // Update the Index | 446 // Update the Index |
443 cache_loader_->WriteIndex( | 447 cache_loader_->WriteIndex( |
444 cache_map_, | 448 cache_map_, |
445 base::Bind(&ServiceWorkerCacheStorage::DeleteCacheDidWriteIndex, | 449 base::Bind(&ServiceWorkerCacheStorage::DeleteCacheDidWriteIndex, |
446 weak_factory_.GetWeakPtr(), | 450 weak_factory_.GetWeakPtr(), |
447 cache_name, | 451 cache_name, |
448 callback)); | 452 callback)); |
449 } | 453 } |
450 | 454 |
451 void ServiceWorkerCacheStorage::EnumerateCaches( | 455 void ServiceWorkerCacheStorage::EnumerateCaches( |
452 const StringsAndErrorCallback& callback) { | 456 const StringsAndErrorCallback& callback) { |
453 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 457 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
454 | 458 |
455 if (!initialized_) { | 459 if (!initialized_) { |
456 LazyInit(base::Bind(&ServiceWorkerCacheStorage::EnumerateCaches, | 460 LazyInit(base::Bind(&ServiceWorkerCacheStorage::EnumerateCaches, |
457 weak_factory_.GetWeakPtr(), | 461 weak_factory_.GetWeakPtr(), |
458 callback)); | 462 callback)); |
459 return; | 463 return; |
460 } | 464 } |
461 | 465 |
462 std::vector<std::string> names; | 466 std::vector<std::string> names; |
463 for (NameMap::const_iterator it = name_map_.begin(); it != name_map_.end(); | 467 for (CacheMap::const_iterator it = cache_map_.begin(); it != cache_map_.end(); |
464 ++it) { | 468 ++it) { |
465 names.push_back(it->first); | 469 names.push_back(it->first); |
466 } | 470 } |
467 | 471 |
468 callback.Run(names, CACHE_STORAGE_ERROR_NO_ERROR); | 472 callback.Run(names, CACHE_STORAGE_ERROR_NO_ERROR); |
469 } | 473 } |
470 | 474 |
471 // Init is run lazily so that it is called on the proper MessageLoop. | 475 // Init is run lazily so that it is called on the proper MessageLoop. |
472 void ServiceWorkerCacheStorage::LazyInit(const base::Closure& callback) { | 476 void ServiceWorkerCacheStorage::LazyInit(const base::Closure& callback) { |
473 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 477 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
(...skipping 19 matching lines...) Expand all Loading... |
493 base::Bind(&ServiceWorkerCacheStorage::LazyInitDidLoadIndex, | 497 base::Bind(&ServiceWorkerCacheStorage::LazyInitDidLoadIndex, |
494 weak_factory_.GetWeakPtr(), | 498 weak_factory_.GetWeakPtr(), |
495 callback)); | 499 callback)); |
496 } | 500 } |
497 | 501 |
498 void ServiceWorkerCacheStorage::LazyInitDidLoadIndex( | 502 void ServiceWorkerCacheStorage::LazyInitDidLoadIndex( |
499 const base::Closure& callback, | 503 const base::Closure& callback, |
500 scoped_ptr<std::vector<std::string> > indexed_cache_names) { | 504 scoped_ptr<std::vector<std::string> > indexed_cache_names) { |
501 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 505 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
502 | 506 |
503 for (std::vector<std::string>::iterator it = indexed_cache_names->begin(); | 507 |
504 it != indexed_cache_names->end(); | 508 for (size_t i = 0u, max = indexed_cache_names->size(); i < max; ++i) { |
505 ++it) { | 509 cache_map_.insert(std::make_pair(indexed_cache_names->at(i), |
506 scoped_ptr<ServiceWorkerCache> cache = | 510 base::WeakPtr<ServiceWorkerCache>())); |
507 cache_loader_->CreateServiceWorkerCache(*it); | |
508 if (!cache) | |
509 continue; | |
510 AddCacheToMaps(*it, cache.Pass()); | |
511 } | 511 } |
512 | 512 |
513 initialized_ = true; | 513 initialized_ = true; |
514 for (std::vector<base::Closure>::iterator it = init_callbacks_.begin(); | 514 for (std::vector<base::Closure>::iterator it = init_callbacks_.begin(); |
515 it != init_callbacks_.end(); | 515 it != init_callbacks_.end(); |
516 ++it) { | 516 ++it) { |
517 it->Run(); | 517 it->Run(); |
518 } | 518 } |
519 init_callbacks_.clear(); | 519 init_callbacks_.clear(); |
520 } | 520 } |
521 | 521 |
522 ServiceWorkerCacheStorage::CacheContext* | |
523 ServiceWorkerCacheStorage::AddCacheToMaps( | |
524 const std::string& cache_name, | |
525 scoped_ptr<ServiceWorkerCache> cache) { | |
526 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
527 | |
528 CacheID id = next_cache_id_++; | |
529 CacheContext* cache_context = new CacheContext(cache_name, id, cache.Pass()); | |
530 cache_map_.insert(std::make_pair(id, cache_context)); // Takes ownership | |
531 name_map_.insert(std::make_pair(cache_name, id)); | |
532 return cache_context; | |
533 } | |
534 | |
535 void ServiceWorkerCacheStorage::CreateCacheDidCreateCache( | 522 void ServiceWorkerCacheStorage::CreateCacheDidCreateCache( |
536 const std::string& cache_name, | 523 const std::string& cache_name, |
537 const CacheAndErrorCallback& callback, | 524 const CacheAndErrorCallback& callback, |
538 scoped_ptr<ServiceWorkerCache> cache) { | 525 const scoped_refptr<ServiceWorkerCache>& cache) { |
539 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 526 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
540 | 527 |
541 if (!cache) { | 528 if (!cache.get()) { |
542 callback.Run(kInvalidCacheID, CACHE_STORAGE_ERROR_CLOSING); | 529 callback.Run(scoped_refptr<ServiceWorkerCache>(), |
| 530 CACHE_STORAGE_ERROR_CLOSING); |
543 return; | 531 return; |
544 } | 532 } |
545 | 533 |
546 CacheContext* cache_context = AddCacheToMaps(cache_name, cache.Pass()); | 534 cache_map_.insert(std::make_pair(cache_name, cache->AsWeakPtr())); |
547 | 535 |
548 cache_loader_->WriteIndex( | 536 cache_loader_->WriteIndex( |
549 cache_map_, | 537 cache_map_, |
550 base::Bind(&ServiceWorkerCacheStorage::CreateCacheDidWriteIndex, | 538 base::Bind(&ServiceWorkerCacheStorage::CreateCacheDidWriteIndex, |
551 weak_factory_.GetWeakPtr(), | 539 weak_factory_.GetWeakPtr(), |
552 callback, | 540 callback, |
553 cache_context->cache->AsWeakPtr(), | 541 cache)); |
554 cache_context->id)); | |
555 } | 542 } |
556 | 543 |
557 void ServiceWorkerCacheStorage::CreateCacheDidWriteIndex( | 544 void ServiceWorkerCacheStorage::CreateCacheDidWriteIndex( |
558 const CacheAndErrorCallback& callback, | 545 const CacheAndErrorCallback& callback, |
559 base::WeakPtr<ServiceWorkerCache> cache, | 546 const scoped_refptr<ServiceWorkerCache>& cache, |
560 CacheID id, | |
561 bool success) { | 547 bool success) { |
562 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 548 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
563 if (!cache) { | 549 DCHECK(cache.get()); |
564 callback.Run(kInvalidCacheID, CACHE_STORAGE_ERROR_CLOSING); | |
565 return; | |
566 } | |
567 | 550 |
568 callback.Run(id, CACHE_STORAGE_ERROR_NO_ERROR); | 551 callback.Run(cache, CACHE_STORAGE_ERROR_NO_ERROR); |
569 } | 552 } |
570 | 553 |
571 void ServiceWorkerCacheStorage::DeleteCacheDidWriteIndex( | 554 void ServiceWorkerCacheStorage::DeleteCacheDidWriteIndex( |
572 const std::string& cache_name, | 555 const std::string& cache_name, |
573 const BoolAndErrorCallback& callback, | 556 const BoolAndErrorCallback& callback, |
574 bool success) { | 557 bool success) { |
575 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 558 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
576 | 559 |
577 cache_loader_->CleanUpDeletedCache( | 560 cache_loader_->CleanUpDeletedCache( |
578 cache_name, | 561 cache_name, |
579 base::Bind(&ServiceWorkerCacheStorage::DeleteCacheDidCleanUp, | 562 base::Bind(&ServiceWorkerCacheStorage::DeleteCacheDidCleanUp, |
580 weak_factory_.GetWeakPtr(), | 563 weak_factory_.GetWeakPtr(), |
581 callback)); | 564 callback)); |
582 } | 565 } |
583 | 566 |
584 void ServiceWorkerCacheStorage::DeleteCacheDidCleanUp( | 567 void ServiceWorkerCacheStorage::DeleteCacheDidCleanUp( |
585 const BoolAndErrorCallback& callback, | 568 const BoolAndErrorCallback& callback, |
586 bool success) { | 569 bool success) { |
587 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 570 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
588 | 571 |
589 callback.Run(true, CACHE_STORAGE_ERROR_NO_ERROR); | 572 callback.Run(true, CACHE_STORAGE_ERROR_NO_ERROR); |
590 } | 573 } |
591 | 574 |
592 ServiceWorkerCacheStorage::CacheContext* | 575 scoped_refptr<ServiceWorkerCache> ServiceWorkerCacheStorage::GetLoadedCache( |
593 ServiceWorkerCacheStorage::GetLoadedCache(const std::string& cache_name) const { | 576 const std::string& cache_name) { |
594 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 577 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
595 DCHECK(initialized_); | 578 DCHECK(initialized_); |
596 | 579 |
597 NameMap::const_iterator name_iter = name_map_.find(cache_name); | 580 CacheMap::iterator map_iter = cache_map_.find(cache_name); |
598 if (name_iter == name_map_.end()) | 581 if (map_iter == cache_map_.end()) |
599 return NULL; | 582 return scoped_refptr<ServiceWorkerCache>(); |
600 | 583 |
601 CacheMap::const_iterator map_iter = cache_map_.find(name_iter->second); | 584 base::WeakPtr<ServiceWorkerCache> cache = map_iter->second; |
602 DCHECK(map_iter != cache_map_.end()); | 585 |
603 return map_iter->second; | 586 if (!cache) { |
| 587 scoped_refptr<ServiceWorkerCache> new_cache = |
| 588 cache_loader_->CreateServiceWorkerCache(cache_name); |
| 589 map_iter->second = new_cache->AsWeakPtr(); |
| 590 return new_cache; |
| 591 } |
| 592 |
| 593 return make_scoped_refptr(cache.get()); |
604 } | 594 } |
605 | 595 |
606 } // namespace content | 596 } // namespace content |
OLD | NEW |