| Index: net/disk_cache/v3/sparse_control_v3.cc
|
| ===================================================================
|
| --- net/disk_cache/v3/sparse_control_v3.cc (revision 0)
|
| +++ net/disk_cache/v3/sparse_control_v3.cc (working copy)
|
| @@ -104,7 +104,7 @@
|
|
|
| void ChildrenDeleter::ReadData(disk_cache::Addr address, int len) {
|
| DCHECK(address.is_block_file());
|
| - if (!backend_.get())
|
| + if (!backend_)
|
| return Release();
|
|
|
| disk_cache::File* file(backend_->File(address));
|
| @@ -127,7 +127,7 @@
|
|
|
| void ChildrenDeleter::DeleteChildren() {
|
| int child_id = 0;
|
| - if (!children_map_.FindNextSetBit(&child_id) || !backend_.get()) {
|
| + if (!children_map_.FindNextSetBit(&child_id) || !backend_) {
|
| // We are done. Just delete this object.
|
| return Release();
|
| }
|
| @@ -140,6 +140,8 @@
|
| FROM_HERE, base::Bind(&ChildrenDeleter::DeleteChildren, this));
|
| }
|
|
|
| +// -----------------------------------------------------------------------
|
| +
|
| // Returns the NetLog event type corresponding to a SparseOperation.
|
| net::NetLog::EventType GetSparseEventType(
|
| disk_cache::SparseControl::SparseOperation operation) {
|
| @@ -210,27 +212,6 @@
|
| WriteSparseData();
|
| }
|
|
|
| -int SparseControl::Init() {
|
| - DCHECK(!init_);
|
| -
|
| - // We should not have sparse data for the exposed entry.
|
| - if (entry_->GetDataSize(kSparseData))
|
| - return net::ERR_CACHE_OPERATION_NOT_SUPPORTED;
|
| -
|
| - // Now see if there is something where we store our data.
|
| - int rv = net::OK;
|
| - int data_len = entry_->GetDataSize(kSparseIndex);
|
| - if (!data_len) {
|
| - rv = CreateSparseEntry();
|
| - } else {
|
| - rv = OpenSparseEntry(data_len);
|
| - }
|
| -
|
| - if (rv == net::OK)
|
| - init_ = true;
|
| - return rv;
|
| -}
|
| -
|
| bool SparseControl::CouldBeSparse() const {
|
| DCHECK(!init_);
|
|
|
| @@ -255,7 +236,7 @@
|
| if (offset + buf_len >= 0x1000000000LL || offset + buf_len < 0)
|
| return net::ERR_CACHE_OPERATION_NOT_SUPPORTED;
|
|
|
| - DCHECK(!user_buf_.get());
|
| + DCHECK(!user_buf_);
|
| DCHECK(user_callback_.is_null());
|
|
|
| if (!buf && (op == kReadOperation || op == kWriteOperation))
|
| @@ -350,9 +331,9 @@
|
|
|
| entry->net_log().AddEvent(net::NetLog::TYPE_SPARSE_DELETE_CHILDREN);
|
|
|
| - DCHECK(entry->backend_.get());
|
| - ChildrenDeleter* deleter =
|
| - new ChildrenDeleter(entry->backend_.get(), entry->GetKey());
|
| + DCHECK(entry->backend_);
|
| + ChildrenDeleter* deleter = new ChildrenDeleter(entry->backend_.get(),
|
| + entry->GetKey());
|
| // The object will self destruct when finished.
|
| deleter->AddRef();
|
|
|
| @@ -367,6 +348,29 @@
|
| }
|
| }
|
|
|
| +// -----------------------------------------------------------------------
|
| +
|
| +int SparseControl::Init() {
|
| + DCHECK(!init_);
|
| +
|
| + // We should not have sparse data for the exposed entry.
|
| + if (entry_->GetDataSize(kSparseData))
|
| + return net::ERR_CACHE_OPERATION_NOT_SUPPORTED;
|
| +
|
| + // Now see if there is something where we store our data.
|
| + int rv = net::OK;
|
| + int data_len = entry_->GetDataSize(kSparseIndex);
|
| + if (!data_len) {
|
| + rv = CreateSparseEntry();
|
| + } else {
|
| + rv = OpenSparseEntry(data_len);
|
| + }
|
| +
|
| + if (rv == net::OK)
|
| + init_ = true;
|
| + return rv;
|
| +}
|
| +
|
| // We are going to start using this entry to store sparse data, so we have to
|
| // initialize our control info.
|
| int SparseControl::CreateSparseEntry() {
|
| @@ -383,12 +387,8 @@
|
| scoped_refptr<net::IOBuffer> buf(
|
| new net::WrappedIOBuffer(reinterpret_cast<char*>(&sparse_header_)));
|
|
|
| - int rv = entry_->WriteData(kSparseIndex,
|
| - 0,
|
| - buf.get(),
|
| - sizeof(sparse_header_),
|
| - CompletionCallback(),
|
| - false);
|
| + int rv = entry_->WriteData(kSparseIndex, 0, buf.get(), sizeof(sparse_header_),
|
| + CompletionCallback(), false);
|
| if (rv != sizeof(sparse_header_)) {
|
| DLOG(ERROR) << "Unable to save sparse_header_";
|
| return net::ERR_CACHE_OPERATION_NOT_SUPPORTED;
|
| @@ -418,8 +418,8 @@
|
| new net::WrappedIOBuffer(reinterpret_cast<char*>(&sparse_header_)));
|
|
|
| // Read header.
|
| - int rv = entry_->ReadData(
|
| - kSparseIndex, 0, buf.get(), sizeof(sparse_header_), CompletionCallback());
|
| + int rv = entry_->ReadData(kSparseIndex, 0, buf.get(), sizeof(sparse_header_),
|
| + CompletionCallback());
|
| if (rv != static_cast<int>(sizeof(sparse_header_)))
|
| return net::ERR_CACHE_READ_FAILURE;
|
|
|
| @@ -432,11 +432,8 @@
|
|
|
| // Read the actual bitmap.
|
| buf = new net::IOBuffer(map_len);
|
| - rv = entry_->ReadData(kSparseIndex,
|
| - sizeof(sparse_header_),
|
| - buf.get(),
|
| - map_len,
|
| - CompletionCallback());
|
| + rv = entry_->ReadData(kSparseIndex, sizeof(sparse_header_), buf.get(),
|
| + map_len, CompletionCallback());
|
| if (rv != map_len)
|
| return net::ERR_CACHE_READ_FAILURE;
|
|
|
| @@ -461,7 +458,7 @@
|
| if (!ChildPresent())
|
| return ContinueWithoutChild(key);
|
|
|
| - if (!entry_->backend_.get())
|
| + if (!entry_->backend_)
|
| return false;
|
|
|
| child_ = entry_->backend_->OpenEntryImpl(key);
|
| @@ -478,8 +475,8 @@
|
| new net::WrappedIOBuffer(reinterpret_cast<char*>(&child_data_)));
|
|
|
| // Read signature.
|
| - int rv = child_->ReadData(
|
| - kSparseIndex, 0, buf.get(), sizeof(child_data_), CompletionCallback());
|
| + int rv = child_->ReadData(kSparseIndex, 0, buf.get(), sizeof(child_data_),
|
| + CompletionCallback());
|
| if (rv != sizeof(child_data_))
|
| return KillChildAndContinue(key, true); // This is a fatal failure.
|
|
|
| @@ -502,36 +499,15 @@
|
| new net::WrappedIOBuffer(reinterpret_cast<char*>(&child_data_)));
|
|
|
| // Save the allocation bitmap before closing the child entry.
|
| - int rv = child_->WriteData(kSparseIndex,
|
| - 0,
|
| - buf.get(),
|
| - sizeof(child_data_),
|
| + int rv = child_->WriteData(kSparseIndex, 0, buf.get(), sizeof(child_data_),
|
| CompletionCallback(),
|
| - false);
|
| + false);
|
| if (rv != sizeof(child_data_))
|
| DLOG(ERROR) << "Failed to save child data";
|
| child_->Release();
|
| child_ = NULL;
|
| }
|
|
|
| -std::string SparseControl::GenerateChildKey() {
|
| - return GenerateChildName(entry_->GetKey(), sparse_header_.signature,
|
| - offset_ >> 20);
|
| -}
|
| -
|
| -// We are deleting the child because something went wrong.
|
| -bool SparseControl::KillChildAndContinue(const std::string& key, bool fatal) {
|
| - SetChildBit(false);
|
| - child_->DoomImpl();
|
| - child_->Release();
|
| - child_ = NULL;
|
| - if (fatal) {
|
| - result_ = net::ERR_CACHE_READ_FAILURE;
|
| - return false;
|
| - }
|
| - return ContinueWithoutChild(key);
|
| -}
|
| -
|
| // We were not able to open this child; see what we can do.
|
| bool SparseControl::ContinueWithoutChild(const std::string& key) {
|
| if (kReadOperation == operation_)
|
| @@ -539,7 +515,7 @@
|
| if (kGetRangeOperation == operation_)
|
| return true;
|
|
|
| - if (!entry_->backend_.get())
|
| + if (!entry_->backend_)
|
| return false;
|
|
|
| child_ = entry_->backend_->CreateEntryImpl(key);
|
| @@ -553,6 +529,121 @@
|
| return true;
|
| }
|
|
|
| +void SparseControl::WriteSparseData() {
|
| + scoped_refptr<net::IOBuffer> buf(new net::WrappedIOBuffer(
|
| + reinterpret_cast<const char*>(children_map_.GetMap())));
|
| +
|
| + int len = children_map_.ArraySize() * 4;
|
| + int rv = entry_->WriteData(kSparseIndex, sizeof(sparse_header_), buf.get(),
|
| + len, CompletionCallback(), false);
|
| + if (rv != len) {
|
| + DLOG(ERROR) << "Unable to save sparse map";
|
| + }
|
| +}
|
| +
|
| +bool SparseControl::DoChildIO() {
|
| + finished_ = true;
|
| + if (!buf_len_ || result_ < 0)
|
| + return false;
|
| +
|
| + if (!OpenChild())
|
| + return false;
|
| +
|
| + if (!VerifyRange())
|
| + return false;
|
| +
|
| + // We have more work to do. Let's not trigger a callback to the caller.
|
| + finished_ = false;
|
| + CompletionCallback callback;
|
| + if (!user_callback_.is_null()) {
|
| + callback =
|
| + base::Bind(&SparseControl::OnChildIOCompleted, base::Unretained(this));
|
| + }
|
| +
|
| + int rv = 0;
|
| + switch (operation_) {
|
| + case kReadOperation:
|
| + if (entry_->net_log().IsLoggingAllEvents()) {
|
| + entry_->net_log().BeginEvent(
|
| + net::NetLog::TYPE_SPARSE_READ_CHILD_DATA,
|
| + CreateNetLogSparseReadWriteCallback(child_->net_log().source(),
|
| + child_len_));
|
| + }
|
| + rv = child_->ReadDataImpl(kSparseData, child_offset_, user_buf_.get(),
|
| + child_len_, callback);
|
| + break;
|
| + case kWriteOperation:
|
| + if (entry_->net_log().IsLoggingAllEvents()) {
|
| + entry_->net_log().BeginEvent(
|
| + net::NetLog::TYPE_SPARSE_WRITE_CHILD_DATA,
|
| + CreateNetLogSparseReadWriteCallback(child_->net_log().source(),
|
| + child_len_));
|
| + }
|
| + rv = child_->WriteDataImpl(kSparseData, child_offset_, user_buf_.get(),
|
| + child_len_, callback, false);
|
| + break;
|
| + case kGetRangeOperation:
|
| + rv = DoGetAvailableRange();
|
| + break;
|
| + default:
|
| + NOTREACHED();
|
| + }
|
| +
|
| + if (rv == net::ERR_IO_PENDING) {
|
| + if (!pending_) {
|
| + pending_ = true;
|
| + // The child will protect himself against closing the entry while IO is in
|
| + // 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(); // Balanced in DoUserCallback.
|
| + }
|
| + return false;
|
| + }
|
| + if (!rv)
|
| + return false;
|
| +
|
| + DoChildIOCompleted(rv);
|
| + return true;
|
| +}
|
| +
|
| +void SparseControl::DoChildIOCompleted(int result) {
|
| + LogChildOperationEnd(entry_->net_log(), operation_, result);
|
| + if (result < 0) {
|
| + // We fail the whole operation if we encounter an error.
|
| + result_ = result;
|
| + return;
|
| + }
|
| +
|
| + UpdateRange(result);
|
| +
|
| + result_ += result;
|
| + offset_ += result;
|
| + buf_len_ -= result;
|
| +
|
| + // We'll be reusing the user provided buffer for the next chunk.
|
| + if (buf_len_ && user_buf_)
|
| + user_buf_->DidConsume(result);
|
| +}
|
| +
|
| +std::string SparseControl::GenerateChildKey() {
|
| + return GenerateChildName(entry_->GetKey(), sparse_header_.signature,
|
| + offset_ >> 20);
|
| +}
|
| +
|
| +// We are deleting the child because something went wrong.
|
| +bool SparseControl::KillChildAndContinue(const std::string& key, bool fatal) {
|
| + SetChildBit(false);
|
| + child_->DoomImpl();
|
| + child_->Release();
|
| + child_ = NULL;
|
| + if (fatal) {
|
| + result_ = net::ERR_CACHE_READ_FAILURE;
|
| + return false;
|
| + }
|
| + return ContinueWithoutChild(key);
|
| +}
|
| +
|
| bool SparseControl::ChildPresent() {
|
| int child_bit = static_cast<int>(offset_ >> 20);
|
| if (children_map_.Size() <= child_bit)
|
| @@ -571,22 +662,6 @@
|
| children_map_.Set(child_bit, value);
|
| }
|
|
|
| -void SparseControl::WriteSparseData() {
|
| - scoped_refptr<net::IOBuffer> buf(new net::WrappedIOBuffer(
|
| - reinterpret_cast<const char*>(children_map_.GetMap())));
|
| -
|
| - int len = children_map_.ArraySize() * 4;
|
| - int rv = entry_->WriteData(kSparseIndex,
|
| - sizeof(sparse_header_),
|
| - buf.get(),
|
| - len,
|
| - CompletionCallback(),
|
| - false);
|
| - if (rv != len) {
|
| - DLOG(ERROR) << "Unable to save sparse map";
|
| - }
|
| -}
|
| -
|
| bool SparseControl::VerifyRange() {
|
| DCHECK_GE(result_, 0);
|
|
|
| @@ -684,108 +759,13 @@
|
| scoped_refptr<net::WrappedIOBuffer> buf(
|
| new net::WrappedIOBuffer(reinterpret_cast<char*>(&child_data_)));
|
|
|
| - int rv = child_->WriteData(kSparseIndex,
|
| - 0,
|
| - buf.get(),
|
| - sizeof(child_data_),
|
| - CompletionCallback(),
|
| - false);
|
| + int rv = child_->WriteData(kSparseIndex, 0, buf.get(), sizeof(child_data_),
|
| + CompletionCallback(), false);
|
| if (rv != sizeof(child_data_))
|
| DLOG(ERROR) << "Failed to save child data";
|
| SetChildBit(true);
|
| }
|
|
|
| -void SparseControl::DoChildrenIO() {
|
| - while (DoChildIO()) continue;
|
| -
|
| - // Range operations are finished synchronously, often without setting
|
| - // |finished_| to true.
|
| - if (kGetRangeOperation == operation_ &&
|
| - entry_->net_log().IsLoggingAllEvents()) {
|
| - entry_->net_log().EndEvent(
|
| - net::NetLog::TYPE_SPARSE_GET_RANGE,
|
| - CreateNetLogGetAvailableRangeResultCallback(offset_, result_));
|
| - }
|
| - if (finished_) {
|
| - if (kGetRangeOperation != operation_ &&
|
| - entry_->net_log().IsLoggingAllEvents()) {
|
| - entry_->net_log().EndEvent(GetSparseEventType(operation_));
|
| - }
|
| - if (pending_)
|
| - DoUserCallback(); // Don't touch this object after this point.
|
| - }
|
| -}
|
| -
|
| -bool SparseControl::DoChildIO() {
|
| - finished_ = true;
|
| - if (!buf_len_ || result_ < 0)
|
| - return false;
|
| -
|
| - if (!OpenChild())
|
| - return false;
|
| -
|
| - if (!VerifyRange())
|
| - return false;
|
| -
|
| - // We have more work to do. Let's not trigger a callback to the caller.
|
| - finished_ = false;
|
| - CompletionCallback callback;
|
| - if (!user_callback_.is_null()) {
|
| - callback =
|
| - base::Bind(&SparseControl::OnChildIOCompleted, base::Unretained(this));
|
| - }
|
| -
|
| - int rv = 0;
|
| - switch (operation_) {
|
| - case kReadOperation:
|
| - if (entry_->net_log().IsLoggingAllEvents()) {
|
| - entry_->net_log().BeginEvent(
|
| - net::NetLog::TYPE_SPARSE_READ_CHILD_DATA,
|
| - CreateNetLogSparseReadWriteCallback(child_->net_log().source(),
|
| - child_len_));
|
| - }
|
| - rv = child_->ReadDataImpl(
|
| - kSparseData, child_offset_, user_buf_.get(), child_len_, callback);
|
| - break;
|
| - case kWriteOperation:
|
| - if (entry_->net_log().IsLoggingAllEvents()) {
|
| - entry_->net_log().BeginEvent(
|
| - net::NetLog::TYPE_SPARSE_WRITE_CHILD_DATA,
|
| - CreateNetLogSparseReadWriteCallback(child_->net_log().source(),
|
| - child_len_));
|
| - }
|
| - rv = child_->WriteDataImpl(kSparseData,
|
| - child_offset_,
|
| - user_buf_.get(),
|
| - child_len_,
|
| - callback,
|
| - false);
|
| - break;
|
| - case kGetRangeOperation:
|
| - rv = DoGetAvailableRange();
|
| - break;
|
| - default:
|
| - NOTREACHED();
|
| - }
|
| -
|
| - if (rv == net::ERR_IO_PENDING) {
|
| - if (!pending_) {
|
| - pending_ = true;
|
| - // The child will protect himself against closing the entry while IO is in
|
| - // 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(); // Balanced in DoUserCallback.
|
| - }
|
| - return false;
|
| - }
|
| - if (!rv)
|
| - return false;
|
| -
|
| - DoChildIOCompleted(rv);
|
| - return true;
|
| -}
|
| -
|
| int SparseControl::DoGetAvailableRange() {
|
| if (!child_)
|
| return child_len_; // Move on to the next child.
|
| @@ -833,23 +813,29 @@
|
| return 0;
|
| }
|
|
|
| -void SparseControl::DoChildIOCompleted(int result) {
|
| - LogChildOperationEnd(entry_->net_log(), operation_, result);
|
| - if (result < 0) {
|
| - // We fail the whole operation if we encounter an error.
|
| - result_ = result;
|
| - return;
|
| - }
|
| +void SparseControl::DoUserCallback() {
|
| + DCHECK(!user_callback_.is_null());
|
| + CompletionCallback cb = user_callback_;
|
| + user_callback_.Reset();
|
| + user_buf_ = NULL;
|
| + pending_ = false;
|
| + operation_ = kNoOperation;
|
| + int rv = result_;
|
| + entry_->Release(); // Don't touch object after this line.
|
| + cb.Run(rv);
|
| +}
|
|
|
| - UpdateRange(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().
|
| + CompletionCallback cb = abort_callbacks_[i];
|
| + if (i == abort_callbacks_.size() - 1)
|
| + abort_callbacks_.clear();
|
|
|
| - result_ += result;
|
| - offset_ += result;
|
| - buf_len_ -= result;
|
| -
|
| - // We'll be reusing the user provided buffer for the next chunk.
|
| - if (buf_len_ && user_buf_.get())
|
| - user_buf_->DidConsume(result);
|
| + entry_->Release(); // Don't touch object after this line.
|
| + cb.Run(net::OK);
|
| + }
|
| }
|
|
|
| void SparseControl::OnChildIOCompleted(int result) {
|
| @@ -879,29 +865,4 @@
|
| DoChildrenIO();
|
| }
|
|
|
| -void SparseControl::DoUserCallback() {
|
| - DCHECK(!user_callback_.is_null());
|
| - CompletionCallback cb = user_callback_;
|
| - user_callback_.Reset();
|
| - user_buf_ = NULL;
|
| - pending_ = false;
|
| - operation_ = kNoOperation;
|
| - int rv = result_;
|
| - entry_->Release(); // Don't touch object after this line.
|
| - cb.Run(rv);
|
| -}
|
| -
|
| -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().
|
| - CompletionCallback cb = abort_callbacks_[i];
|
| - if (i == abort_callbacks_.size() - 1)
|
| - abort_callbacks_.clear();
|
| -
|
| - entry_->Release(); // Don't touch object after this line.
|
| - cb.Run(net::OK);
|
| - }
|
| -}
|
| -
|
| } // namespace disk_cache
|
|
|