summaryrefslogtreecommitdiffstats
path: root/net/disk_cache/sparse_control.cc
diff options
context:
space:
mode:
authorrvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-08 23:07:39 +0000
committerrvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-08 23:07:39 +0000
commit06e62baf611d6fca8698d50765bca81989155845 (patch)
tree5516ccda32e56e7dae301b8b30f5fd24a4c8b83c /net/disk_cache/sparse_control.cc
parent681d3b6b072e17a5de40be8794550f781bf28d87 (diff)
downloadchromium_src-06e62baf611d6fca8698d50765bca81989155845.zip
chromium_src-06e62baf611d6fca8698d50765bca81989155845.tar.gz
chromium_src-06e62baf611d6fca8698d50765bca81989155845.tar.bz2
Disk cache: Add a method to cancel pending sparse operations.
The sparse IO methods require exclusive use of the cache entry and they complain when that requirement is violated. When the user cancels a request and reissues another one to the same entry, we may be waiting for the previous operation to finish when we receive a new IO request, so we fail. This CL add a way for the HTTP cache to cancel IO operations and get a notification when the disk cache is able to operate on that entry again. BUG=23862 TEST=unittests Review URL: http://codereview.chromium.org/256090 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@28475 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/disk_cache/sparse_control.cc')
-rw-r--r--net/disk_cache/sparse_control.cc42
1 files changed, 41 insertions, 1 deletions
diff --git a/net/disk_cache/sparse_control.cc b/net/disk_cache/sparse_control.cc
index 7648f4e..3c1dd8c 100644
--- a/net/disk_cache/sparse_control.cc
+++ b/net/disk_cache/sparse_control.cc
@@ -192,6 +192,7 @@ int SparseControl::StartIO(SparseOperation op, int64 offset, net::IOBuffer* buf,
result_ = 0;
pending_ = false;
finished_ = false;
+ abort_ = false;
DoChildrenIO();
@@ -226,6 +227,24 @@ int SparseControl::GetAvailableRange(int64 offset, int len, int64* start) {
return result < 0 ? result : 0; // Don't mask error codes to the caller.
}
+void SparseControl::CancelIO() {
+ if (operation_ == kNoOperation)
+ return;
+ abort_ = true;
+}
+
+int SparseControl::ReadyToUse(net::CompletionCallback* completion_callback) {
+ if (!abort_)
+ return net::OK;
+
+ // We'll grab another reference to keep this object alive because we just have
+ // one extra reference due to the pending IO operation itself, but we'll
+ // release that one before invoking user_callback_.
+ entry_->AddRef(); // Balanced in DoAbortCallbacks.
+ abort_callbacks_.push_back(completion_callback);
+ return net::ERR_IO_PENDING;
+}
+
// Static
void SparseControl::DeleteChildren(EntryImpl* entry) {
DCHECK(entry->GetEntryFlags() & PARENT_ENTRY);
@@ -601,7 +620,7 @@ bool SparseControl::DoChildIO() {
// progress. However, this entry can still be closed, and that would not
// be a good thing for us, so we increase the refcount until we're
// finished doing sparse stuff.
- entry_->AddRef();
+ entry_->AddRef(); // Balanced in DoUserCallback.
}
return false;
}
@@ -681,6 +700,14 @@ void SparseControl::OnChildIOCompleted(int result) {
DCHECK_NE(net::ERR_IO_PENDING, result);
DoChildIOCompleted(result);
+ if (abort_) {
+ // We'll return the current result of the operation, which may be less than
+ // the bytes to read or write, but the user cancelled the operation.
+ abort_ = false;
+ DoUserCallback();
+ return DoAbortCallbacks();
+ }
+
// We are running a callback from the message loop. It's time to restart what
// we were doing before.
DoChildrenIO();
@@ -697,4 +724,17 @@ void SparseControl::DoUserCallback() {
c->Run(result_);
}
+void SparseControl::DoAbortCallbacks() {
+ for (size_t i = 0; i < abort_callbacks_.size(); i++) {
+ // Releasing all references to entry_ may result in the destruction of this
+ // object so we should not be touching it after the last Release().
+ net::CompletionCallback* c = abort_callbacks_[i];
+ if (i == abort_callbacks_.size() - 1)
+ abort_callbacks_.clear();
+
+ entry_->Release(); // Don't touch object after this line.
+ c->Run(net::OK);
+ }
+}
+
} // namespace disk_cache