Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(176)

Side by Side Diff: net/disk_cache/entry_impl.cc

Issue 8156: Switch MessagePumpForIO to use completion ports on Windows.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 12 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/disk_cache/disk_cache_test_base.cc ('k') | net/disk_cache/file_win.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 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/disk_cache/entry_impl.h" 5 #include "net/disk_cache/entry_impl.h"
6 6
7 #include "base/histogram.h" 7 #include "base/histogram.h"
8 #include "base/message_loop.h" 8 #include "base/message_loop.h"
9 #include "base/string_util.h" 9 #include "base/string_util.h"
10 #include "net/base/net_errors.h" 10 #include "net/base/net_errors.h"
11 #include "net/disk_cache/backend_impl.h" 11 #include "net/disk_cache/backend_impl.h"
12 #include "net/disk_cache/cache_util.h" 12 #include "net/disk_cache/cache_util.h"
13 13
14 using base::Time; 14 using base::Time;
15 using base::TimeDelta; 15 using base::TimeDelta;
16 16
17 namespace { 17 namespace {
18 18
19 // This is a simple Task to execute the callback (from the message loop instead 19 // This class implements FileIOCallback to buffer the callback from a file IO
20 // of the APC). 20 // operation from the actual net class.
21 class InvokeCallback : public Task {
22 public:
23 InvokeCallback(net::CompletionCallback* callback, int argument)
24 : callback_(callback), argument_(argument) {}
25
26 virtual void Run() {
27 callback_->Run(argument_);
28 }
29
30 private:
31 net::CompletionCallback* callback_;
32 int argument_;
33 DISALLOW_EVIL_CONSTRUCTORS(InvokeCallback);
34 };
35
36 // This class implements FileIOCallback to buffer the callback from an IO
37 // operation from the actual IO class.
38 class SyncCallback: public disk_cache::FileIOCallback { 21 class SyncCallback: public disk_cache::FileIOCallback {
39 public: 22 public:
40 SyncCallback(disk_cache::EntryImpl* entry, 23 SyncCallback(disk_cache::EntryImpl* entry,
41 net::CompletionCallback* callback ) 24 net::CompletionCallback* callback )
42 : entry_(entry), callback_(callback) { 25 : entry_(entry), callback_(callback) {
43 entry->AddRef(); 26 entry->AddRef();
44 entry->IncrementIoCount(); 27 entry->IncrementIoCount();
45 } 28 }
46 ~SyncCallback() {} 29 ~SyncCallback() {}
47 30
48 virtual void OnFileIOComplete(int bytes_copied); 31 virtual void OnFileIOComplete(int bytes_copied);
49 void Discard(); 32 void Discard();
50 private: 33 private:
51 disk_cache::EntryImpl* entry_; 34 disk_cache::EntryImpl* entry_;
52 net::CompletionCallback* callback_; 35 net::CompletionCallback* callback_;
53 36
54 DISALLOW_EVIL_CONSTRUCTORS(SyncCallback); 37 DISALLOW_EVIL_CONSTRUCTORS(SyncCallback);
55 }; 38 };
56 39
57 void SyncCallback::OnFileIOComplete(int bytes_copied) { 40 void SyncCallback::OnFileIOComplete(int bytes_copied) {
58 entry_->DecrementIoCount(); 41 entry_->DecrementIoCount();
59 entry_->Release(); 42 entry_->Release();
60 if (callback_) { 43 if (callback_)
61 InvokeCallback* task = new InvokeCallback(callback_, bytes_copied); 44 callback_->Run(bytes_copied);
62 MessageLoop::current()->PostTask(FROM_HERE, task);
63 }
64 delete this; 45 delete this;
65 } 46 }
66 47
67 void SyncCallback::Discard() { 48 void SyncCallback::Discard() {
68 callback_ = NULL; 49 callback_ = NULL;
69 OnFileIOComplete(0); 50 OnFileIOComplete(0);
70 } 51 }
71 52
72 // Clears buffer before offset and after valid_len, knowing that the size of 53 // Clears buffer before offset and after valid_len, knowing that the size of
73 // buffer is kMaxBlockSize. 54 // buffer is kMaxBlockSize.
(...skipping 475 matching lines...) Expand 10 before | Expand all | Expand 10 after
549 return true; 530 return true;
550 } 531 }
551 532
552 void EntryImpl::DeleteData(Addr address, int index) { 533 void EntryImpl::DeleteData(Addr address, int index) {
553 if (!address.is_initialized()) 534 if (!address.is_initialized())
554 return; 535 return;
555 if (address.is_separate_file()) { 536 if (address.is_separate_file()) {
556 if (files_[index]) 537 if (files_[index])
557 files_[index] = NULL; // Releases the object. 538 files_[index] = NULL; // Releases the object.
558 539
559 if (!DeleteCacheFile(backend_->GetFileName(address))) 540 if (!DeleteCacheFile(backend_->GetFileName(address))) {
541 UMA_HISTOGRAM_COUNTS(L"DiskCache.DeleteFailed", 1);
560 LOG(ERROR) << "Failed to delete " << backend_->GetFileName(address) << 542 LOG(ERROR) << "Failed to delete " << backend_->GetFileName(address) <<
561 " from the cache."; 543 " from the cache.";
544 }
562 } else { 545 } else {
563 backend_->DeleteBlock(address, true); 546 backend_->DeleteBlock(address, true);
564 } 547 }
565 } 548 }
566 549
567 void EntryImpl::UpdateRank(bool modified) { 550 void EntryImpl::UpdateRank(bool modified) {
568 if (!doomed_) { 551 if (!doomed_) {
569 // Everything is handled by the backend. 552 // Everything is handled by the backend.
570 backend_->UpdateRank(&node_, true); 553 backend_->UpdateRank(&node_, true);
571 return; 554 return;
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
704 } 687 }
705 688
706 if (!MoveToLocalBuffer(index)) 689 if (!MoveToLocalBuffer(index))
707 return false; 690 return false;
708 691
709 // Clear the end of the buffer. 692 // Clear the end of the buffer.
710 ClearInvalidData(user_buffers_[index].get(), 0, offset + buf_len); 693 ClearInvalidData(user_buffers_[index].get(), 0, offset + buf_len);
711 return true; 694 return true;
712 } 695 }
713 696
714
715 // The common scenario is that this is called from the destructor of the entry, 697 // The common scenario is that this is called from the destructor of the entry,
716 // to write to disk what we have buffered. We don't want to hold the destructor 698 // to write to disk what we have buffered. We don't want to hold the destructor
717 // until the actual IO finishes, so we'll send an asynchronous write that will 699 // until the actual IO finishes, so we'll send an asynchronous write that will
718 // free up the memory containing the data. To be consistent, this method always 700 // free up the memory containing the data. To be consistent, this method always
719 // returns with the buffer freed up (on success). 701 // returns with the buffer freed up (on success).
720 bool EntryImpl::Flush(int index, int size, bool async) { 702 bool EntryImpl::Flush(int index, int size, bool async) {
721 Addr address(entry_.Data()->data_addr[index]); 703 Addr address(entry_.Data()->data_addr[index]);
722 DCHECK(user_buffers_[index].get()); 704 DCHECK(user_buffers_[index].get());
723 DCHECK(!address.is_initialized()); 705 DCHECK(!address.is_initialized());
724 706
(...skipping 12 matching lines...) Expand all
737 offset = address.start_block() * address.BlockSize() + kBlockHeaderSize; 719 offset = address.start_block() * address.BlockSize() + kBlockHeaderSize;
738 720
739 // We just told the backend to store len bytes for real. 721 // We just told the backend to store len bytes for real.
740 DCHECK(len == static_cast<size_t>(unreported_size_[index])); 722 DCHECK(len == static_cast<size_t>(unreported_size_[index]));
741 backend_->ModifyStorageSize(0, static_cast<int>(len)); 723 backend_->ModifyStorageSize(0, static_cast<int>(len));
742 unreported_size_[index] = 0; 724 unreported_size_[index] = 0;
743 725
744 if (!file) 726 if (!file)
745 return false; 727 return false;
746 728
729 // TODO(rvargas): figure out if it's worth to re-enable posting operations.
730 // Right now it is only used from GrowUserBuffer, not the destructor, and
731 // it is not accounted for from the point of view of the total number of
732 // pending operations of the cache. It is also racing with the actual write
733 // on the GrowUserBuffer path because there is no code to exclude the range
734 // that is going to be written.
735 async = false;
747 if (async) { 736 if (async) {
748 if (!file->PostWrite(user_buffers_[index].get(), len, offset)) 737 if (!file->PostWrite(user_buffers_[index].get(), len, offset))
749 return false; 738 return false;
750 } else { 739 } else {
751 if (!file->Write(user_buffers_[index].get(), len, offset, NULL, NULL)) 740 if (!file->Write(user_buffers_[index].get(), len, offset, NULL, NULL))
752 return false; 741 return false;
753 user_buffers_[index].reset(NULL); 742 user_buffers_[index].reset(NULL);
754 } 743 }
755 744
756 // The buffer is deleted from the PostWrite operation. 745 // The buffer is deleted from the PostWrite operation.
(...skipping 14 matching lines...) Expand all
771 entry_.address().value(), node_.address().value()); 760 entry_.address().value(), node_.address().value());
772 761
773 Trace(" data: 0x%x 0x%x 0x%x", entry_.Data()->data_addr[0], 762 Trace(" data: 0x%x 0x%x 0x%x", entry_.Data()->data_addr[0],
774 entry_.Data()->data_addr[1], entry_.Data()->long_key); 763 entry_.Data()->data_addr[1], entry_.Data()->long_key);
775 764
776 Trace(" doomed: %d 0x%p 0x%x", doomed_, pointer, dirty); 765 Trace(" doomed: %d 0x%p 0x%x", doomed_, pointer, dirty);
777 } 766 }
778 767
779 } // namespace disk_cache 768 } // namespace disk_cache
780 769
OLDNEW
« no previous file with comments | « net/disk_cache/disk_cache_test_base.cc ('k') | net/disk_cache/file_win.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698