| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/http_cache.h" | 5 #include "net/http/http_cache.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/compiler_specific.h" | 9 #include "base/compiler_specific.h" |
| 10 | 10 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 44 //----------------------------------------------------------------------------- | 44 //----------------------------------------------------------------------------- |
| 45 | 45 |
| 46 HttpCache::ActiveEntry::ActiveEntry(disk_cache::Entry* e) | 46 HttpCache::ActiveEntry::ActiveEntry(disk_cache::Entry* e) |
| 47 : disk_entry(e), | 47 : disk_entry(e), |
| 48 writer(NULL), | 48 writer(NULL), |
| 49 will_process_pending_queue(false), | 49 will_process_pending_queue(false), |
| 50 doomed(false) { | 50 doomed(false) { |
| 51 } | 51 } |
| 52 | 52 |
| 53 HttpCache::ActiveEntry::~ActiveEntry() { | 53 HttpCache::ActiveEntry::~ActiveEntry() { |
| 54 if (disk_entry) | 54 if (disk_entry) { |
| 55 disk_entry->Close(); | 55 disk_entry->Close(); |
| 56 disk_entry = NULL; |
| 57 } |
| 56 } | 58 } |
| 57 | 59 |
| 58 //----------------------------------------------------------------------------- | 60 //----------------------------------------------------------------------------- |
| 59 | 61 |
| 60 // This structure keeps track of work items that are attempting to create or | 62 // This structure keeps track of work items that are attempting to create or |
| 61 // open cache entries or the backend itself. | 63 // open cache entries or the backend itself. |
| 62 struct HttpCache::PendingOp { | 64 struct HttpCache::PendingOp { |
| 63 PendingOp() : disk_entry(NULL), writer(NULL), callback(NULL) {} | 65 PendingOp() : disk_entry(NULL), writer(NULL), callback(NULL) {} |
| 64 ~PendingOp() {} | 66 ~PendingOp() {} |
| 65 | 67 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 87 : operation_(operation), trans_(trans), entry_(entry), callback_(NULL), | 89 : operation_(operation), trans_(trans), entry_(entry), callback_(NULL), |
| 88 backend_(NULL) {} | 90 backend_(NULL) {} |
| 89 WorkItem(WorkItemOperation operation, Transaction* trans, | 91 WorkItem(WorkItemOperation operation, Transaction* trans, |
| 90 CompletionCallback* cb, disk_cache::Backend** backend) | 92 CompletionCallback* cb, disk_cache::Backend** backend) |
| 91 : operation_(operation), trans_(trans), entry_(NULL), callback_(cb), | 93 : operation_(operation), trans_(trans), entry_(NULL), callback_(cb), |
| 92 backend_(backend) {} | 94 backend_(backend) {} |
| 93 ~WorkItem() {} | 95 ~WorkItem() {} |
| 94 | 96 |
| 95 // Calls back the transaction with the result of the operation. | 97 // Calls back the transaction with the result of the operation. |
| 96 void NotifyTransaction(int result, ActiveEntry* entry) { | 98 void NotifyTransaction(int result, ActiveEntry* entry) { |
| 99 // TODO(rvargas): convert to DCHECK after fixing bug 47895. |
| 100 CHECK(!entry || entry->disk_entry); |
| 97 if (entry_) | 101 if (entry_) |
| 98 *entry_ = entry; | 102 *entry_ = entry; |
| 99 if (trans_) | 103 if (trans_) |
| 100 trans_->io_callback()->Run(result); | 104 trans_->io_callback()->Run(result); |
| 101 } | 105 } |
| 102 | 106 |
| 103 // Notifies the caller about the operation completion. | 107 // Notifies the caller about the operation completion. |
| 104 void DoCallback(int result, disk_cache::Backend* backend) { | 108 void DoCallback(int result, disk_cache::Backend* backend) { |
| 105 if (backend_) | 109 if (backend_) |
| 106 *backend_ = backend; | 110 *backend_ = backend; |
| (...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 524 HttpCache::ActiveEntry* HttpCache::ActivateEntry( | 528 HttpCache::ActiveEntry* HttpCache::ActivateEntry( |
| 525 const std::string& key, | 529 const std::string& key, |
| 526 disk_cache::Entry* disk_entry) { | 530 disk_cache::Entry* disk_entry) { |
| 527 DCHECK(!FindActiveEntry(key)); | 531 DCHECK(!FindActiveEntry(key)); |
| 528 ActiveEntry* entry = new ActiveEntry(disk_entry); | 532 ActiveEntry* entry = new ActiveEntry(disk_entry); |
| 529 active_entries_[key] = entry; | 533 active_entries_[key] = entry; |
| 530 return entry; | 534 return entry; |
| 531 } | 535 } |
| 532 | 536 |
| 533 void HttpCache::DeactivateEntry(ActiveEntry* entry) { | 537 void HttpCache::DeactivateEntry(ActiveEntry* entry) { |
| 534 DCHECK(!entry->will_process_pending_queue); | 538 // TODO(rvargas): convert to DCHECKs after fixing bug 47895. |
| 535 DCHECK(!entry->doomed); | 539 CHECK(!entry->will_process_pending_queue); |
| 536 DCHECK(!entry->writer); | 540 CHECK(!entry->doomed); |
| 537 DCHECK(entry->readers.empty()); | 541 CHECK(!entry->writer); |
| 538 DCHECK(entry->pending_queue.empty()); | 542 CHECK(entry->disk_entry); |
| 543 CHECK(entry->readers.empty()); |
| 544 CHECK(entry->pending_queue.empty()); |
| 539 | 545 |
| 540 std::string key = entry->disk_entry->GetKey(); | 546 std::string key = entry->disk_entry->GetKey(); |
| 541 if (key.empty()) | 547 if (key.empty()) |
| 542 return SlowDeactivateEntry(entry); | 548 return SlowDeactivateEntry(entry); |
| 543 | 549 |
| 544 ActiveEntriesMap::iterator it = active_entries_.find(key); | 550 ActiveEntriesMap::iterator it = active_entries_.find(key); |
| 545 DCHECK(it != active_entries_.end()); | 551 CHECK(it != active_entries_.end()); |
| 546 DCHECK(it->second == entry); | 552 CHECK(it->second == entry); |
| 547 | 553 |
| 548 active_entries_.erase(it); | 554 active_entries_.erase(it); |
| 549 delete entry; | 555 delete entry; |
| 550 } | 556 } |
| 551 | 557 |
| 552 // We don't know this entry's key so we have to find it without it. | 558 // We don't know this entry's key so we have to find it without it. |
| 553 void HttpCache::SlowDeactivateEntry(ActiveEntry* entry) { | 559 void HttpCache::SlowDeactivateEntry(ActiveEntry* entry) { |
| 554 for (ActiveEntriesMap::iterator it = active_entries_.begin(); | 560 for (ActiveEntriesMap::iterator it = active_entries_.begin(); |
| 555 it != active_entries_.end(); ++it) { | 561 it != active_entries_.end(); ++it) { |
| 556 if (it->second == entry) { | 562 if (it->second == entry) { |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 655 | 661 |
| 656 void HttpCache::DestroyEntry(ActiveEntry* entry) { | 662 void HttpCache::DestroyEntry(ActiveEntry* entry) { |
| 657 if (entry->doomed) { | 663 if (entry->doomed) { |
| 658 FinalizeDoomedEntry(entry); | 664 FinalizeDoomedEntry(entry); |
| 659 } else { | 665 } else { |
| 660 DeactivateEntry(entry); | 666 DeactivateEntry(entry); |
| 661 } | 667 } |
| 662 } | 668 } |
| 663 | 669 |
| 664 int HttpCache::AddTransactionToEntry(ActiveEntry* entry, Transaction* trans) { | 670 int HttpCache::AddTransactionToEntry(ActiveEntry* entry, Transaction* trans) { |
| 665 DCHECK(entry); | 671 // TODO(rvargas): convert to DCHECKs after fixing bug 47895. |
| 672 CHECK(entry); |
| 673 CHECK(entry->disk_entry); |
| 666 | 674 |
| 667 // We implement a basic reader/writer lock for the disk cache entry. If | 675 // We implement a basic reader/writer lock for the disk cache entry. If |
| 668 // there is already a writer, then everyone has to wait for the writer to | 676 // there is already a writer, then everyone has to wait for the writer to |
| 669 // finish before they can access the cache entry. There can be multiple | 677 // finish before they can access the cache entry. There can be multiple |
| 670 // readers. | 678 // readers. |
| 671 // | 679 // |
| 672 // NOTE: If the transaction can only write, then the entry should not be in | 680 // NOTE: If the transaction can only write, then the entry should not be in |
| 673 // use (since any existing entry should have already been doomed). | 681 // use (since any existing entry should have already been doomed). |
| 674 | 682 |
| 675 if (entry->writer || entry->will_process_pending_queue) { | 683 if (entry->writer || entry->will_process_pending_queue) { |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 862 entry->will_process_pending_queue = true; | 870 entry->will_process_pending_queue = true; |
| 863 | 871 |
| 864 MessageLoop::current()->PostTask( | 872 MessageLoop::current()->PostTask( |
| 865 FROM_HERE, | 873 FROM_HERE, |
| 866 task_factory_.NewRunnableMethod(&HttpCache::OnProcessPendingQueue, | 874 task_factory_.NewRunnableMethod(&HttpCache::OnProcessPendingQueue, |
| 867 entry)); | 875 entry)); |
| 868 } | 876 } |
| 869 | 877 |
| 870 void HttpCache::OnProcessPendingQueue(ActiveEntry* entry) { | 878 void HttpCache::OnProcessPendingQueue(ActiveEntry* entry) { |
| 871 entry->will_process_pending_queue = false; | 879 entry->will_process_pending_queue = false; |
| 872 DCHECK(!entry->writer); | 880 // TODO(rvargas): convert to DCHECK after fixing bug 47895. |
| 881 CHECK(!entry->writer); |
| 873 | 882 |
| 874 // If no one is interested in this entry, then we can de-activate it. | 883 // If no one is interested in this entry, then we can de-activate it. |
| 875 if (entry->pending_queue.empty()) { | 884 if (entry->pending_queue.empty()) { |
| 876 if (entry->readers.empty()) | 885 if (entry->readers.empty()) |
| 877 DestroyEntry(entry); | 886 DestroyEntry(entry); |
| 878 return; | 887 return; |
| 879 } | 888 } |
| 880 | 889 |
| 881 // Promote next transaction from the pending queue. | 890 // Promote next transaction from the pending queue. |
| 882 Transaction* next = entry->pending_queue.front(); | 891 Transaction* next = entry->pending_queue.front(); |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1001 // This could be an external caller or a transaction waiting on Start(). | 1010 // This could be an external caller or a transaction waiting on Start(). |
| 1002 pending_item->DoCallback(result, temp_backend_); | 1011 pending_item->DoCallback(result, temp_backend_); |
| 1003 pending_item->NotifyTransaction(result, NULL); | 1012 pending_item->NotifyTransaction(result, NULL); |
| 1004 } | 1013 } |
| 1005 | 1014 |
| 1006 DeletePendingOp(pending_op); | 1015 DeletePendingOp(pending_op); |
| 1007 building_backend_ = false; | 1016 building_backend_ = false; |
| 1008 } | 1017 } |
| 1009 | 1018 |
| 1010 } // namespace net | 1019 } // namespace net |
| OLD | NEW |