| 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 |