Index: net/disk_cache/in_flight_backend_io.cc |
=================================================================== |
--- net/disk_cache/in_flight_backend_io.cc (revision 0) |
+++ net/disk_cache/in_flight_backend_io.cc (revision 0) |
@@ -0,0 +1,448 @@ |
+// Copyright (c) 2010 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "net/disk_cache/in_flight_backend_io.h" |
+ |
+#include "base/compiler_specific.h" |
+#include "base/logging.h" |
+#include "net/base/net_errors.h" |
+#include "net/disk_cache/backend_impl.h" |
+#include "net/disk_cache/entry_impl.h" |
+ |
+namespace disk_cache { |
+ |
+BackendIO::BackendIO(InFlightIO* controller, BackendImpl* backend, |
+ net::CompletionCallback* callback) |
+ : BackgroundIO(controller), backend_(backend), callback_(callback), |
+ operation_(OP_NONE), |
+ ALLOW_THIS_IN_INITIALIZER_LIST( |
+ my_callback_(this, &BackendIO::OnIOComplete)) { |
+} |
+ |
+// Runs on the background thread. |
+void BackendIO::ExecuteOperation() { |
+ if (IsEntryOperation()) |
+ return ExecuteEntryOperation(); |
+ |
+ ExecuteBackendOperation(); |
+} |
+ |
+// Runs on the background thread. |
+void BackendIO::OnIOComplete(int result) { |
+ DCHECK(IsEntryOperation()); |
+ DCHECK_NE(result, net::ERR_IO_PENDING); |
+ result_ = result; |
+ controller_->OnIOComplete(this); |
+} |
+ |
+bool BackendIO::IsEntryOperation() { |
+ return operation_ > OP_MAX_BACKEND; |
+} |
+ |
+void BackendIO::ReleaseEntry() { |
+ entry_ = NULL; |
+} |
+ |
+void BackendIO::Init() { |
+ operation_ = OP_INIT; |
+} |
+ |
+void BackendIO::OpenEntry(const std::string& key, Entry** entry) { |
+ operation_ = OP_OPEN; |
+ key_ = key; |
+ entry_ptr_ = entry; |
+} |
+ |
+void BackendIO::CreateEntry(const std::string& key, Entry** entry) { |
+ operation_ = OP_CREATE; |
+ key_ = key; |
+ entry_ptr_ = entry; |
+} |
+ |
+void BackendIO::DoomEntry(const std::string& key) { |
+ operation_ = OP_DOOM; |
+ key_ = key; |
+} |
+ |
+void BackendIO::DoomAllEntries() { |
+ operation_ = OP_DOOM_ALL; |
+} |
+ |
+void BackendIO::DoomEntriesBetween(const base::Time initial_time, |
+ const base::Time end_time) { |
+ operation_ = OP_DOOM_BETWEEN; |
+ initial_time_ = initial_time; |
+ end_time_ = end_time; |
+} |
+ |
+void BackendIO::DoomEntriesSince(const base::Time initial_time) { |
+ operation_ = OP_DOOM_SINCE; |
+ initial_time_ = initial_time; |
+} |
+ |
+void BackendIO::OpenNextEntry(void** iter, Entry** next_entry) { |
+ operation_ = OP_OPEN_NEXT; |
+ iter_ptr_ = iter; |
+ entry_ptr_ = next_entry; |
+} |
+ |
+void BackendIO::OpenPrevEntry(void** iter, Entry** prev_entry) { |
+ operation_ = OP_OPEN_PREV; |
+ iter_ptr_ = iter; |
+ entry_ptr_ = prev_entry; |
+} |
+ |
+void BackendIO::EndEnumeration(void* iterator) { |
+ operation_ = OP_END_ENUMERATION; |
+ iter_ = iterator; |
+} |
+ |
+void BackendIO::CloseEntryImpl(EntryImpl* entry) { |
+ operation_ = OP_CLOSE_ENTRY; |
+ entry_ = entry; |
+} |
+ |
+void BackendIO::DoomEntryImpl(EntryImpl* entry) { |
+ operation_ = OP_DOOM_ENTRY; |
+ entry_ = entry; |
+} |
+ |
+void BackendIO::FlushQueue() { |
+ operation_ = OP_FLUSH_QUEUE; |
+} |
+ |
+void BackendIO::ReadData(EntryImpl* entry, int index, int offset, |
+ net::IOBuffer* buf, int buf_len) { |
+ operation_ = OP_READ; |
+ entry_ = entry; |
+ index_ = index; |
+ offset_ = offset; |
+ buf_ = buf; |
+ buf_len_ = buf_len; |
+} |
+ |
+void BackendIO::WriteData(EntryImpl* entry, int index, int offset, |
+ net::IOBuffer* buf, int buf_len, bool truncate) { |
+ operation_ = OP_WRITE; |
+ entry_ = entry; |
+ index_ = index; |
+ offset_ = offset; |
+ buf_ = buf; |
+ buf_len_ = buf_len; |
+ truncate_ = truncate; |
+} |
+ |
+void BackendIO::ReadSparseData(EntryImpl* entry, int64 offset, |
+ net::IOBuffer* buf, int buf_len) { |
+ operation_ = OP_READ_SPARSE; |
+ entry_ = entry; |
+ offset64_ = offset; |
+ buf_ = buf; |
+ buf_len_ = buf_len; |
+} |
+ |
+void BackendIO::WriteSparseData(EntryImpl* entry, int64 offset, |
+ net::IOBuffer* buf, int buf_len) { |
+ operation_ = OP_WRITE_SPARSE; |
+ entry_ = entry; |
+ offset64_ = offset; |
+ buf_ = buf; |
+ buf_len_ = buf_len; |
+} |
+ |
+void BackendIO::GetAvailableRange(EntryImpl* entry, int64 offset, int len, |
+ int64* start) { |
+ operation_ = OP_GET_RANGE; |
+ entry_ = entry; |
+ offset64_ = offset; |
+ buf_len_ = len; |
+ start_ = start; |
+} |
+ |
+void BackendIO::CancelSparseIO(EntryImpl* entry) { |
+ operation_ = OP_CANCEL_IO; |
+ entry_ = entry; |
+} |
+ |
+void BackendIO::ReadyForSparseIO(EntryImpl* entry) { |
+ operation_ = OP_IS_READY; |
+ entry_ = entry; |
+} |
+ |
+// Runs on the background thread. |
+void BackendIO::ExecuteBackendOperation() { |
+ switch (operation_) { |
+ case OP_INIT: |
+ result_ = backend_->SyncInit(); |
+ break; |
+ case OP_OPEN: |
+ result_ = backend_->SyncOpenEntry(key_, entry_ptr_); |
+ break; |
+ case OP_CREATE: |
+ result_ = backend_->SyncCreateEntry(key_, entry_ptr_); |
+ break; |
+ case OP_DOOM: |
+ result_ = backend_->SyncDoomEntry(key_); |
+ break; |
+ case OP_DOOM_ALL: |
+ result_ = backend_->SyncDoomAllEntries(); |
+ break; |
+ case OP_DOOM_BETWEEN: |
+ result_ = backend_->SyncDoomEntriesBetween(initial_time_, end_time_); |
+ break; |
+ case OP_DOOM_SINCE: |
+ result_ = backend_->SyncDoomEntriesSince(initial_time_); |
+ break; |
+ case OP_OPEN_NEXT: |
+ result_ = backend_->SyncOpenNextEntry(iter_ptr_, entry_ptr_); |
+ break; |
+ case OP_OPEN_PREV: |
+ result_ = backend_->SyncOpenPrevEntry(iter_ptr_, entry_ptr_); |
+ break; |
+ case OP_END_ENUMERATION: |
+ backend_->SyncEndEnumeration(iter_); |
+ result_ = net::OK; |
+ break; |
+ case OP_CLOSE_ENTRY: |
+ entry_->Release(); |
+ result_ = net::OK; |
+ break; |
+ case OP_DOOM_ENTRY: |
+ entry_->DoomImpl(); |
+ result_ = net::OK; |
+ break; |
+ case OP_FLUSH_QUEUE: |
+ result_ = net::OK; |
+ break; |
+ default: |
+ NOTREACHED() << "Invalid Operation"; |
+ result_ = net::ERR_UNEXPECTED; |
+ } |
+ DCHECK_NE(net::ERR_IO_PENDING, result_); |
+ controller_->OnIOComplete(this); |
+} |
+ |
+// Runs on the background thread. |
+void BackendIO::ExecuteEntryOperation() { |
+ switch (operation_) { |
+ case OP_READ: |
+ result_ = entry_->ReadDataImpl(index_, offset_, buf_, buf_len_, |
+ &my_callback_); |
+ break; |
+ case OP_WRITE: |
+ result_ = entry_->WriteDataImpl(index_, offset_, buf_, buf_len_, |
+ &my_callback_, truncate_); |
+ break; |
+ case OP_READ_SPARSE: |
+ result_ = entry_->ReadSparseDataImpl(offset64_, buf_, buf_len_, |
+ &my_callback_); |
+ break; |
+ case OP_WRITE_SPARSE: |
+ result_ = entry_->WriteSparseDataImpl(offset64_, buf_, buf_len_, |
+ &my_callback_); |
+ break; |
+ case OP_GET_RANGE: |
+ result_ = entry_->GetAvailableRangeImpl(offset64_, buf_len_, start_); |
+ break; |
+ case OP_CANCEL_IO: |
+ entry_->CancelSparseIOImpl(); |
+ result_ = net::OK; |
+ break; |
+ case OP_IS_READY: |
+ result_ = entry_->ReadyForSparseIOImpl(&my_callback_); |
+ break; |
+ default: |
+ NOTREACHED() << "Invalid Operation"; |
+ result_ = net::ERR_UNEXPECTED; |
+ } |
+ if (result_ != net::ERR_IO_PENDING) |
+ controller_->OnIOComplete(this); |
+} |
+ |
+// --------------------------------------------------------------------------- |
+ |
+void InFlightBackendIO::Init(CompletionCallback* callback) { |
+ scoped_refptr<BackendIO> operation = new BackendIO(this, backend_, callback); |
+ operation->Init(); |
+ QueueOperation(operation); |
+} |
+ |
+void InFlightBackendIO::OpenEntry(const std::string& key, Entry** entry, |
+ CompletionCallback* callback) { |
+ scoped_refptr<BackendIO> operation = new BackendIO(this, backend_, callback); |
+ operation->OpenEntry(key, entry); |
+ QueueOperation(operation); |
+} |
+ |
+void InFlightBackendIO::CreateEntry(const std::string& key, Entry** entry, |
+ CompletionCallback* callback) { |
+ scoped_refptr<BackendIO> operation = new BackendIO(this, backend_, callback); |
+ operation->CreateEntry(key, entry); |
+ QueueOperation(operation); |
+} |
+ |
+void InFlightBackendIO::DoomEntry(const std::string& key, |
+ CompletionCallback* callback) { |
+ scoped_refptr<BackendIO> operation = new BackendIO(this, backend_, callback); |
+ operation->DoomEntry(key); |
+ QueueOperation(operation); |
+} |
+ |
+void InFlightBackendIO::DoomAllEntries(CompletionCallback* callback) { |
+ scoped_refptr<BackendIO> operation = new BackendIO(this, backend_, callback); |
+ operation->DoomAllEntries(); |
+ QueueOperation(operation); |
+} |
+ |
+void InFlightBackendIO::DoomEntriesBetween(const base::Time initial_time, |
+ const base::Time end_time, |
+ CompletionCallback* callback) { |
+ scoped_refptr<BackendIO> operation = new BackendIO(this, backend_, callback); |
+ operation->DoomEntriesBetween(initial_time, end_time); |
+ QueueOperation(operation); |
+} |
+ |
+void InFlightBackendIO::DoomEntriesSince(const base::Time initial_time, |
+ CompletionCallback* callback) { |
+ scoped_refptr<BackendIO> operation = new BackendIO(this, backend_, callback); |
+ operation->DoomEntriesSince(initial_time); |
+ QueueOperation(operation); |
+} |
+ |
+void InFlightBackendIO::OpenNextEntry(void** iter, Entry** next_entry, |
+ CompletionCallback* callback) { |
+ scoped_refptr<BackendIO> operation = new BackendIO(this, backend_, callback); |
+ operation->OpenNextEntry(iter, next_entry); |
+ QueueOperation(operation); |
+} |
+ |
+void InFlightBackendIO::OpenPrevEntry(void** iter, Entry** prev_entry, |
+ CompletionCallback* callback) { |
+ scoped_refptr<BackendIO> operation = new BackendIO(this, backend_, callback); |
+ operation->OpenPrevEntry(iter, prev_entry); |
+ QueueOperation(operation); |
+} |
+ |
+void InFlightBackendIO::EndEnumeration(void* iterator) { |
+ scoped_refptr<BackendIO> operation = new BackendIO(this, backend_, NULL); |
+ operation->EndEnumeration(iterator); |
+ QueueOperation(operation); |
+} |
+ |
+void InFlightBackendIO::CloseEntryImpl(EntryImpl* entry) { |
+ scoped_refptr<BackendIO> operation = new BackendIO(this, backend_, NULL); |
+ operation->CloseEntryImpl(entry); |
+ QueueOperation(operation); |
+} |
+ |
+void InFlightBackendIO::DoomEntryImpl(EntryImpl* entry) { |
+ scoped_refptr<BackendIO> operation = new BackendIO(this, backend_, NULL); |
+ operation->DoomEntryImpl(entry); |
+ QueueOperation(operation); |
+} |
+ |
+void InFlightBackendIO::FlushQueue(net::CompletionCallback* callback) { |
+ scoped_refptr<BackendIO> operation = new BackendIO(this, backend_, callback); |
+ operation->FlushQueue(); |
+ QueueOperation(operation); |
+} |
+ |
+void InFlightBackendIO::ReadData(EntryImpl* entry, int index, int offset, |
+ net::IOBuffer* buf, int buf_len, |
+ CompletionCallback* callback) { |
+ scoped_refptr<BackendIO> operation = new BackendIO(this, backend_, callback); |
+ operation->ReadData(entry, index, offset, buf, buf_len); |
+ QueueOperation(operation); |
+} |
+ |
+void InFlightBackendIO::WriteData(EntryImpl* entry, int index, int offset, |
+ net::IOBuffer* buf, int buf_len, |
+ bool truncate, |
+ CompletionCallback* callback) { |
+ scoped_refptr<BackendIO> operation = new BackendIO(this, backend_, callback); |
+ operation->WriteData(entry, index, offset, buf, buf_len, truncate); |
+ QueueOperation(operation); |
+} |
+ |
+void InFlightBackendIO::ReadSparseData(EntryImpl* entry, int64 offset, |
+ net::IOBuffer* buf, int buf_len, |
+ CompletionCallback* callback) { |
+ scoped_refptr<BackendIO> operation = new BackendIO(this, backend_, callback); |
+ operation->ReadSparseData(entry, offset, buf, buf_len); |
+ QueueOperation(operation); |
+} |
+ |
+void InFlightBackendIO::WriteSparseData(EntryImpl* entry, int64 offset, |
+ net::IOBuffer* buf, int buf_len, |
+ CompletionCallback* callback) { |
+ scoped_refptr<BackendIO> operation = new BackendIO(this, backend_, callback); |
+ operation->WriteSparseData(entry, offset, buf, buf_len); |
+ QueueOperation(operation); |
+} |
+ |
+void InFlightBackendIO::GetAvailableRange(EntryImpl* entry, int64 offset, |
+ int len, int64* start, |
+ CompletionCallback* callback) { |
+ scoped_refptr<BackendIO> operation = new BackendIO(this, backend_, callback); |
+ operation->GetAvailableRange(entry, offset, len, start); |
+ QueueOperation(operation); |
+} |
+ |
+void InFlightBackendIO::CancelSparseIO(EntryImpl* entry) { |
+ scoped_refptr<BackendIO> operation = new BackendIO(this, backend_, NULL); |
+ operation->ReadyForSparseIO(entry); |
+ QueueOperation(operation); |
+} |
+ |
+void InFlightBackendIO::ReadyForSparseIO(EntryImpl* entry, |
+ CompletionCallback* callback) { |
+ scoped_refptr<BackendIO> operation = new BackendIO(this, backend_, callback); |
+ operation->ReadyForSparseIO(entry); |
+ QueueOperation(operation); |
+} |
+ |
+void InFlightBackendIO::WaitForPendingIO() { |
+ // We clear the list first so that we don't post more operations after this |
+ // point. |
+ pending_ops_.clear(); |
+ InFlightIO::WaitForPendingIO(); |
+} |
+ |
+void InFlightBackendIO::OnOperationComplete(BackgroundIO* operation, |
+ bool cancel) { |
+ BackendIO* op = static_cast<BackendIO*>(operation); |
+ |
+ if (!op->IsEntryOperation() && !pending_ops_.empty()) { |
+ // Process the next request. Note that invoking the callback may result |
+ // in the backend destruction (and with it this object), so we should deal |
+ // with the next operation before invoking the callback. |
+ scoped_refptr<BackendIO> next_op = pending_ops_.front(); |
+ pending_ops_.pop_front(); |
+ PostOperation(next_op); |
+ } |
+ |
+ if (op->callback() && (!cancel || op->IsEntryOperation())) |
+ op->callback()->Run(op->result()); |
+ |
+ if (cancel) |
+ op->ReleaseEntry(); |
+} |
+ |
+void InFlightBackendIO::QueueOperation(BackendIO* operation) { |
+ if (operation->IsEntryOperation()) |
+ return PostOperation(operation); |
+ |
+ if (pending_ops_.empty()) |
+ return PostOperation(operation); |
+ |
+ pending_ops_.push_back(operation); |
+} |
+ |
+void InFlightBackendIO::PostOperation(BackendIO* operation) { |
+ background_thread_->PostTask(FROM_HERE, |
+ NewRunnableMethod(operation, &BackendIO::ExecuteOperation)); |
+ OnOperationPosted(operation); |
+} |
+ |
+} // namespace |
Property changes on: net\disk_cache\in_flight_backend_io.cc |
___________________________________________________________________ |
Added: svn:eol-style |
+ LF |