OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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/sparse_control.h" | 5 #include "net/disk_cache/sparse_control.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.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 "base/time.h" | 10 #include "base/time.h" |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
185 // Copy the operation parameters. | 185 // Copy the operation parameters. |
186 operation_ = op; | 186 operation_ = op; |
187 offset_ = offset; | 187 offset_ = offset; |
188 user_buf_ = buf ? new net::ReusedIOBuffer(buf, buf_len) : NULL; | 188 user_buf_ = buf ? new net::ReusedIOBuffer(buf, buf_len) : NULL; |
189 buf_len_ = buf_len; | 189 buf_len_ = buf_len; |
190 user_callback_ = callback; | 190 user_callback_ = callback; |
191 | 191 |
192 result_ = 0; | 192 result_ = 0; |
193 pending_ = false; | 193 pending_ = false; |
194 finished_ = false; | 194 finished_ = false; |
| 195 abort_ = false; |
195 | 196 |
196 DoChildrenIO(); | 197 DoChildrenIO(); |
197 | 198 |
198 if (!pending_) { | 199 if (!pending_) { |
199 // Everything was done synchronously. | 200 // Everything was done synchronously. |
200 operation_ = kNoOperation; | 201 operation_ = kNoOperation; |
201 user_buf_ = NULL; | 202 user_buf_ = NULL; |
202 user_callback_ = NULL; | 203 user_callback_ = NULL; |
203 return result_; | 204 return result_; |
204 } | 205 } |
(...skipping 14 matching lines...) Expand all Loading... |
219 if (range_found_) { | 220 if (range_found_) { |
220 *start = offset_; | 221 *start = offset_; |
221 return result; | 222 return result; |
222 } | 223 } |
223 | 224 |
224 // This is a failure. We want to return a valid start value in any case. | 225 // This is a failure. We want to return a valid start value in any case. |
225 *start = offset; | 226 *start = offset; |
226 return result < 0 ? result : 0; // Don't mask error codes to the caller. | 227 return result < 0 ? result : 0; // Don't mask error codes to the caller. |
227 } | 228 } |
228 | 229 |
| 230 void SparseControl::CancelIO() { |
| 231 if (operation_ == kNoOperation) |
| 232 return; |
| 233 abort_ = true; |
| 234 } |
| 235 |
| 236 int SparseControl::ReadyToUse(net::CompletionCallback* completion_callback) { |
| 237 if (!abort_) |
| 238 return net::OK; |
| 239 |
| 240 // We'll grab another reference to keep this object alive because we just have |
| 241 // one extra reference due to the pending IO operation itself, but we'll |
| 242 // release that one before invoking user_callback_. |
| 243 entry_->AddRef(); // Balanced in DoAbortCallbacks. |
| 244 abort_callbacks_.push_back(completion_callback); |
| 245 return net::ERR_IO_PENDING; |
| 246 } |
| 247 |
229 // Static | 248 // Static |
230 void SparseControl::DeleteChildren(EntryImpl* entry) { | 249 void SparseControl::DeleteChildren(EntryImpl* entry) { |
231 DCHECK(entry->GetEntryFlags() & PARENT_ENTRY); | 250 DCHECK(entry->GetEntryFlags() & PARENT_ENTRY); |
232 int data_len = entry->GetDataSize(kSparseIndex); | 251 int data_len = entry->GetDataSize(kSparseIndex); |
233 if (data_len < static_cast<int>(sizeof(SparseData)) || | 252 if (data_len < static_cast<int>(sizeof(SparseData)) || |
234 entry->GetDataSize(kSparseData)) | 253 entry->GetDataSize(kSparseData)) |
235 return; | 254 return; |
236 | 255 |
237 int map_len = data_len - sizeof(SparseHeader); | 256 int map_len = data_len - sizeof(SparseHeader); |
238 if (map_len > kMaxMapSize || map_len % 4) | 257 if (map_len > kMaxMapSize || map_len % 4) |
(...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
594 NOTREACHED(); | 613 NOTREACHED(); |
595 } | 614 } |
596 | 615 |
597 if (rv == net::ERR_IO_PENDING) { | 616 if (rv == net::ERR_IO_PENDING) { |
598 if (!pending_) { | 617 if (!pending_) { |
599 pending_ = true; | 618 pending_ = true; |
600 // The child will protect himself against closing the entry while IO is in | 619 // The child will protect himself against closing the entry while IO is in |
601 // progress. However, this entry can still be closed, and that would not | 620 // progress. However, this entry can still be closed, and that would not |
602 // be a good thing for us, so we increase the refcount until we're | 621 // be a good thing for us, so we increase the refcount until we're |
603 // finished doing sparse stuff. | 622 // finished doing sparse stuff. |
604 entry_->AddRef(); | 623 entry_->AddRef(); // Balanced in DoUserCallback. |
605 } | 624 } |
606 return false; | 625 return false; |
607 } | 626 } |
608 if (!rv) | 627 if (!rv) |
609 return false; | 628 return false; |
610 | 629 |
611 DoChildIOCompleted(rv); | 630 DoChildIOCompleted(rv); |
612 return true; | 631 return true; |
613 } | 632 } |
614 | 633 |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
674 | 693 |
675 // We'll be reusing the user provided buffer for the next chunk. | 694 // We'll be reusing the user provided buffer for the next chunk. |
676 if (buf_len_ && user_buf_) | 695 if (buf_len_ && user_buf_) |
677 user_buf_->SetOffset(result_); | 696 user_buf_->SetOffset(result_); |
678 } | 697 } |
679 | 698 |
680 void SparseControl::OnChildIOCompleted(int result) { | 699 void SparseControl::OnChildIOCompleted(int result) { |
681 DCHECK_NE(net::ERR_IO_PENDING, result); | 700 DCHECK_NE(net::ERR_IO_PENDING, result); |
682 DoChildIOCompleted(result); | 701 DoChildIOCompleted(result); |
683 | 702 |
| 703 if (abort_) { |
| 704 // We'll return the current result of the operation, which may be less than |
| 705 // the bytes to read or write, but the user cancelled the operation. |
| 706 abort_ = false; |
| 707 DoUserCallback(); |
| 708 return DoAbortCallbacks(); |
| 709 } |
| 710 |
684 // We are running a callback from the message loop. It's time to restart what | 711 // We are running a callback from the message loop. It's time to restart what |
685 // we were doing before. | 712 // we were doing before. |
686 DoChildrenIO(); | 713 DoChildrenIO(); |
687 } | 714 } |
688 | 715 |
689 void SparseControl::DoUserCallback() { | 716 void SparseControl::DoUserCallback() { |
690 DCHECK(user_callback_); | 717 DCHECK(user_callback_); |
691 net::CompletionCallback* c = user_callback_; | 718 net::CompletionCallback* c = user_callback_; |
692 user_callback_ = NULL; | 719 user_callback_ = NULL; |
693 user_buf_ = NULL; | 720 user_buf_ = NULL; |
694 pending_ = false; | 721 pending_ = false; |
695 operation_ = kNoOperation; | 722 operation_ = kNoOperation; |
696 entry_->Release(); // Don't touch object after this line. | 723 entry_->Release(); // Don't touch object after this line. |
697 c->Run(result_); | 724 c->Run(result_); |
698 } | 725 } |
699 | 726 |
| 727 void SparseControl::DoAbortCallbacks() { |
| 728 for (size_t i = 0; i < abort_callbacks_.size(); i++) { |
| 729 // Releasing all references to entry_ may result in the destruction of this |
| 730 // object so we should not be touching it after the last Release(). |
| 731 net::CompletionCallback* c = abort_callbacks_[i]; |
| 732 if (i == abort_callbacks_.size() - 1) |
| 733 abort_callbacks_.clear(); |
| 734 |
| 735 entry_->Release(); // Don't touch object after this line. |
| 736 c->Run(net::OK); |
| 737 } |
| 738 } |
| 739 |
700 } // namespace disk_cache | 740 } // namespace disk_cache |
OLD | NEW |