OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "net/http/mock_http_cache.h" | 5 #include "net/http/mock_http_cache.h" |
6 | 6 |
7 #include <limits> | 7 #include <limits> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
67 }; | 67 }; |
68 | 68 |
69 MockDiskEntry::MockDiskEntry(const std::string& key) | 69 MockDiskEntry::MockDiskEntry(const std::string& key) |
70 : key_(key), | 70 : key_(key), |
71 doomed_(false), | 71 doomed_(false), |
72 sparse_(false), | 72 sparse_(false), |
73 fail_requests_(false), | 73 fail_requests_(false), |
74 fail_sparse_requests_(false), | 74 fail_sparse_requests_(false), |
75 busy_(false), | 75 busy_(false), |
76 delayed_(false), | 76 delayed_(false), |
77 cancel_(false) { | 77 cancel_(false), |
78 defer_op_(DEFER_NONE), | |
79 resume_return_code_(0) { | |
78 test_mode_ = GetTestModeForEntry(key); | 80 test_mode_ = GetTestModeForEntry(key); |
79 } | 81 } |
80 | 82 |
81 void MockDiskEntry::Doom() { | 83 void MockDiskEntry::Doom() { |
82 doomed_ = true; | 84 doomed_ = true; |
83 } | 85 } |
84 | 86 |
85 void MockDiskEntry::Close() { | 87 void MockDiskEntry::Close() { |
86 Release(); | 88 Release(); |
87 } | 89 } |
(...skipping 30 matching lines...) Expand all Loading... | |
118 return ERR_FAILED; | 120 return ERR_FAILED; |
119 if (static_cast<size_t>(offset) == data_[index].size()) | 121 if (static_cast<size_t>(offset) == data_[index].size()) |
120 return 0; | 122 return 0; |
121 | 123 |
122 int num = std::min(buf_len, static_cast<int>(data_[index].size()) - offset); | 124 int num = std::min(buf_len, static_cast<int>(data_[index].size()) - offset); |
123 memcpy(buf->data(), &data_[index][offset], num); | 125 memcpy(buf->data(), &data_[index][offset], num); |
124 | 126 |
125 if (MockHttpCache::GetTestMode(test_mode_) & TEST_MODE_SYNC_CACHE_READ) | 127 if (MockHttpCache::GetTestMode(test_mode_) & TEST_MODE_SYNC_CACHE_READ) |
126 return num; | 128 return num; |
127 | 129 |
130 // Pause and resume. | |
131 if (defer_op_ == DEFER_READ) { | |
132 defer_op_ = DEFER_NONE; | |
133 resume_callback_ = callback; | |
134 resume_return_code_ = num; | |
135 return ERR_IO_PENDING; | |
136 } | |
137 | |
128 CallbackLater(callback, num); | 138 CallbackLater(callback, num); |
129 return ERR_IO_PENDING; | 139 return ERR_IO_PENDING; |
130 } | 140 } |
131 | 141 |
142 int MockDiskEntry::ResumeCacheOperation() { | |
143 DCHECK(!resume_callback_.is_null()); | |
144 CallbackLater(resume_callback_, resume_return_code_); | |
145 resume_callback_.Reset(); | |
146 resume_return_code_ = 0; | |
147 return ERR_IO_PENDING; | |
148 } | |
149 | |
132 int MockDiskEntry::WriteData(int index, | 150 int MockDiskEntry::WriteData(int index, |
133 int offset, | 151 int offset, |
134 IOBuffer* buf, | 152 IOBuffer* buf, |
135 int buf_len, | 153 int buf_len, |
136 const CompletionCallback& callback, | 154 const CompletionCallback& callback, |
137 bool truncate) { | 155 bool truncate) { |
138 DCHECK(index >= 0 && index < kNumCacheEntryDataIndices); | 156 DCHECK(index >= 0 && index < kNumCacheEntryDataIndices); |
139 DCHECK(!callback.is_null()); | 157 DCHECK(!callback.is_null()); |
140 DCHECK(truncate); | 158 DCHECK(truncate); |
141 | 159 |
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
369 | 387 |
370 //----------------------------------------------------------------------------- | 388 //----------------------------------------------------------------------------- |
371 | 389 |
372 MockDiskCache::MockDiskCache() | 390 MockDiskCache::MockDiskCache() |
373 : open_count_(0), | 391 : open_count_(0), |
374 create_count_(0), | 392 create_count_(0), |
375 doomed_count_(0), | 393 doomed_count_(0), |
376 fail_requests_(false), | 394 fail_requests_(false), |
377 soft_failures_(false), | 395 soft_failures_(false), |
378 double_create_check_(true), | 396 double_create_check_(true), |
379 fail_sparse_requests_(false) {} | 397 fail_sparse_requests_(false), |
398 defer_op_(DEFER_NONE), | |
399 resume_return_code_(0) {} | |
380 | 400 |
381 MockDiskCache::~MockDiskCache() { | 401 MockDiskCache::~MockDiskCache() { |
382 ReleaseAll(); | 402 ReleaseAll(); |
383 } | 403 } |
384 | 404 |
385 CacheType MockDiskCache::GetCacheType() const { | 405 CacheType MockDiskCache::GetCacheType() const { |
386 return DISK_CACHE; | 406 return DISK_CACHE; |
387 } | 407 } |
388 | 408 |
389 int32_t MockDiskCache::GetEntryCount() const { | 409 int32_t MockDiskCache::GetEntryCount() const { |
390 return static_cast<int32_t>(entries_.size()); | 410 return static_cast<int32_t>(entries_.size()); |
391 } | 411 } |
392 | 412 |
393 int MockDiskCache::OpenEntry(const std::string& key, | 413 int MockDiskCache::OpenEntry(const std::string& key, |
394 disk_cache::Entry** entry, | 414 disk_cache::Entry** entry, |
395 const CompletionCallback& callback) { | 415 const CompletionCallback& callback) { |
396 DCHECK(!callback.is_null()); | 416 DCHECK(!callback.is_null()); |
397 if (fail_requests_) | 417 if (fail_requests_) |
398 return ERR_CACHE_OPEN_FAILURE; | 418 return ERR_CACHE_OPEN_FAILURE; |
399 | 419 |
400 EntryMap::iterator it = entries_.find(key); | 420 EntryMap::iterator it = entries_.find(key); |
401 if (it == entries_.end()) | 421 if (it == entries_.end()) |
402 return ERR_CACHE_OPEN_FAILURE; | 422 return ERR_CACHE_OPEN_FAILURE; |
403 | 423 |
404 if (it->second->is_doomed()) { | 424 if (it->second->is_doomed()) { |
405 it->second->Release(); | 425 // It's possible that the entry was doomed directly by invoking |
jkarlin
2017/07/12 16:15:54
There is a lot of new code here to track doomed en
shivanisha
2017/07/12 17:56:31
Keeping track of doomed_entries seems kind of good
shivanisha
2017/07/13 14:47:26
Let me know if you prefer to have the closure appr
| |
426 // MockDiskEntry::Doom and thus was not inserted into the doomed_entries_ | |
427 // map. Insert it now. | |
428 if (doomed_entries_.count(key)) | |
429 doomed_entries_[key]->Release(); | |
430 doomed_entries_[key] = it->second; | |
406 entries_.erase(it); | 431 entries_.erase(it); |
407 return ERR_CACHE_OPEN_FAILURE; | 432 return ERR_CACHE_OPEN_FAILURE; |
408 } | 433 } |
409 | 434 |
410 open_count_++; | 435 open_count_++; |
411 | 436 |
412 it->second->AddRef(); | 437 it->second->AddRef(); |
413 *entry = it->second; | 438 *entry = it->second; |
414 | 439 |
415 if (soft_failures_) | 440 if (soft_failures_) |
(...skipping 14 matching lines...) Expand all Loading... | |
430 return ERR_CACHE_CREATE_FAILURE; | 455 return ERR_CACHE_CREATE_FAILURE; |
431 | 456 |
432 EntryMap::iterator it = entries_.find(key); | 457 EntryMap::iterator it = entries_.find(key); |
433 if (it != entries_.end()) { | 458 if (it != entries_.end()) { |
434 if (!it->second->is_doomed()) { | 459 if (!it->second->is_doomed()) { |
435 if (double_create_check_) | 460 if (double_create_check_) |
436 NOTREACHED(); | 461 NOTREACHED(); |
437 else | 462 else |
438 return ERR_CACHE_CREATE_FAILURE; | 463 return ERR_CACHE_CREATE_FAILURE; |
439 } | 464 } |
440 it->second->Release(); | 465 // It's possible that the entry was doomed directly by invoking |
466 // MockDiskEntry::Doom and thus was not inserted into the doomed_entries_ | |
467 // map. Insert it now. | |
468 if (doomed_entries_.count(key)) | |
469 doomed_entries_[key]->Release(); | |
470 doomed_entries_[key] = it->second; | |
441 entries_.erase(it); | 471 entries_.erase(it); |
442 } | 472 } |
443 | 473 |
444 create_count_++; | 474 create_count_++; |
445 | 475 |
446 MockDiskEntry* new_entry = new MockDiskEntry(key); | 476 MockDiskEntry* new_entry = new MockDiskEntry(key); |
447 | 477 |
448 new_entry->AddRef(); | 478 new_entry->AddRef(); |
449 entries_[key] = new_entry; | 479 entries_[key] = new_entry; |
450 | 480 |
451 new_entry->AddRef(); | 481 new_entry->AddRef(); |
452 *entry = new_entry; | 482 *entry = new_entry; |
453 | 483 |
454 if (soft_failures_) | 484 if (soft_failures_) |
455 new_entry->set_fail_requests(); | 485 new_entry->set_fail_requests(); |
456 | 486 |
457 if (fail_sparse_requests_) | 487 if (fail_sparse_requests_) |
458 new_entry->set_fail_sparse_requests(); | 488 new_entry->set_fail_sparse_requests(); |
459 | 489 |
460 if (GetTestModeForEntry(key) & TEST_MODE_SYNC_CACHE_START) | 490 if (GetTestModeForEntry(key) & TEST_MODE_SYNC_CACHE_START) |
461 return OK; | 491 return OK; |
462 | 492 |
493 // Pause and resume. | |
494 if (defer_op_ == DEFER_CREATE) { | |
495 defer_op_ = DEFER_NONE; | |
496 resume_callback_ = callback; | |
497 resume_return_code_ = OK; | |
498 return ERR_IO_PENDING; | |
499 } | |
500 | |
463 CallbackLater(callback, OK); | 501 CallbackLater(callback, OK); |
464 return ERR_IO_PENDING; | 502 return ERR_IO_PENDING; |
465 } | 503 } |
466 | 504 |
467 int MockDiskCache::DoomEntry(const std::string& key, | 505 int MockDiskCache::DoomEntry(const std::string& key, |
468 const CompletionCallback& callback) { | 506 const CompletionCallback& callback) { |
469 DCHECK(!callback.is_null()); | 507 DCHECK(!callback.is_null()); |
470 EntryMap::iterator it = entries_.find(key); | 508 EntryMap::iterator it = entries_.find(key); |
471 if (it != entries_.end()) { | 509 if (it != entries_.end()) { |
472 it->second->Release(); | 510 if (doomed_entries_.count(key)) |
511 doomed_entries_[key]->Release(); | |
512 doomed_entries_[key] = it->second; | |
473 entries_.erase(it); | 513 entries_.erase(it); |
474 doomed_count_++; | 514 doomed_count_++; |
475 } | 515 } |
476 | 516 |
477 if (GetTestModeForEntry(key) & TEST_MODE_SYNC_CACHE_START) | 517 if (GetTestModeForEntry(key) & TEST_MODE_SYNC_CACHE_START) |
478 return OK; | 518 return OK; |
479 | 519 |
480 CallbackLater(callback, OK); | 520 CallbackLater(callback, OK); |
481 return ERR_IO_PENDING; | 521 return ERR_IO_PENDING; |
482 } | 522 } |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
519 void MockDiskCache::OnExternalCacheHit(const std::string& key) { | 559 void MockDiskCache::OnExternalCacheHit(const std::string& key) { |
520 } | 560 } |
521 | 561 |
522 size_t MockDiskCache::DumpMemoryStats( | 562 size_t MockDiskCache::DumpMemoryStats( |
523 base::trace_event::ProcessMemoryDump* pmd, | 563 base::trace_event::ProcessMemoryDump* pmd, |
524 const std::string& parent_absolute_name) const { | 564 const std::string& parent_absolute_name) const { |
525 return 0u; | 565 return 0u; |
526 } | 566 } |
527 | 567 |
528 void MockDiskCache::ReleaseAll() { | 568 void MockDiskCache::ReleaseAll() { |
529 EntryMap::iterator it = entries_.begin(); | 569 for (auto entry : entries_) |
530 for (; it != entries_.end(); ++it) | 570 entry.second->Release(); |
531 it->second->Release(); | |
532 entries_.clear(); | 571 entries_.clear(); |
572 | |
573 for (auto doomed : doomed_entries_) | |
574 doomed.second->Release(); | |
575 doomed_entries_.clear(); | |
533 } | 576 } |
534 | 577 |
535 void MockDiskCache::CallbackLater(const CompletionCallback& callback, | 578 void MockDiskCache::CallbackLater(const CompletionCallback& callback, |
536 int result) { | 579 int result) { |
537 base::ThreadTaskRunnerHandle::Get()->PostTask( | 580 base::ThreadTaskRunnerHandle::Get()->PostTask( |
538 FROM_HERE, base::Bind(&CallbackForwader, callback, result)); | 581 FROM_HERE, base::Bind(&CallbackForwader, callback, result)); |
539 } | 582 } |
540 | 583 |
541 bool MockDiskCache::IsDiskEntryDoomed(const std::string& key) { | 584 bool MockDiskCache::IsDiskEntryDoomed(const std::string& key) { |
585 auto doomed_it = doomed_entries_.find(key); | |
586 if (doomed_it != doomed_entries_.end()) | |
587 return true; | |
588 | |
589 auto it = entries_.find(key); | |
590 if (it != entries_.end()) | |
591 return it->second->is_doomed(); | |
592 | |
593 return false; | |
594 } | |
595 | |
596 bool MockDiskCache::IsDiskEntryNotDoomed(const std::string& key) { | |
597 auto it = entries_.find(key); | |
598 if (it != entries_.end()) | |
599 return !it->second->is_doomed(); | |
600 | |
601 return false; | |
602 } | |
603 | |
604 int MockDiskCache::ResumeCacheOperation() { | |
605 DCHECK(!resume_callback_.is_null()); | |
606 CallbackLater(resume_callback_, resume_return_code_); | |
607 resume_callback_.Reset(); | |
608 resume_return_code_ = 0; | |
609 return ERR_IO_PENDING; | |
610 } | |
611 | |
612 void MockDiskCache::SetDefer(const std::string& key, const DeferOp defer_op) { | |
542 auto it = entries_.find(key); | 613 auto it = entries_.find(key); |
543 if (it == entries_.end()) | 614 if (it == entries_.end()) |
544 return false; | 615 return; |
545 return it->second->is_doomed(); | 616 it->second->SetDefer(defer_op); |
617 } | |
618 | |
619 int MockDiskCache::ResumeCacheOperation(const std::string& key) { | |
620 auto it = entries_.find(key); | |
621 if (it != entries_.end()) | |
622 return it->second->ResumeCacheOperation(); | |
623 | |
624 return ERR_UNEXPECTED; | |
625 } | |
626 | |
627 int MockDiskCache::ResumeDoomedEntryCacheOperation(const std::string& key) { | |
628 auto doomed_it = doomed_entries_.find(key); | |
629 if (doomed_it != doomed_entries_.end()) | |
630 return doomed_it->second->ResumeCacheOperation(); | |
631 | |
632 auto it = entries_.find(key); | |
633 if (it != entries_.end()) { | |
634 DCHECK(it->second->is_doomed()); | |
635 return it->second->ResumeCacheOperation(); | |
636 } | |
637 | |
638 return ERR_UNEXPECTED; | |
546 } | 639 } |
547 | 640 |
548 //----------------------------------------------------------------------------- | 641 //----------------------------------------------------------------------------- |
549 | 642 |
550 int MockBackendFactory::CreateBackend( | 643 int MockBackendFactory::CreateBackend( |
551 NetLog* net_log, | 644 NetLog* net_log, |
552 std::unique_ptr<disk_cache::Backend>* backend, | 645 std::unique_ptr<disk_cache::Backend>* backend, |
553 const CompletionCallback& callback) { | 646 const CompletionCallback& callback) { |
554 backend->reset(new MockDiskCache()); | 647 backend->reset(new MockDiskCache()); |
555 return OK; | 648 return OK; |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
746 if (!callback_.is_null()) { | 839 if (!callback_.is_null()) { |
747 if (!fail_) | 840 if (!fail_) |
748 backend_->reset(new MockDiskCache()); | 841 backend_->reset(new MockDiskCache()); |
749 CompletionCallback cb = callback_; | 842 CompletionCallback cb = callback_; |
750 callback_.Reset(); | 843 callback_.Reset(); |
751 cb.Run(Result()); // This object can be deleted here. | 844 cb.Run(Result()); // This object can be deleted here. |
752 } | 845 } |
753 } | 846 } |
754 | 847 |
755 } // namespace net | 848 } // namespace net |
OLD | NEW |