Chromium Code Reviews| 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 |