Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(206)

Unified Diff: net/disk_cache/simple/simple_entry_impl.cc

Issue 2807433002: SimpleCache: synchronously reply on reads from idle if data is in memory.
Patch Set: Use the proper limit for the barrier. Created 3 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/disk_cache/simple/simple_entry_impl.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/disk_cache/simple/simple_entry_impl.cc
diff --git a/net/disk_cache/simple/simple_entry_impl.cc b/net/disk_cache/simple/simple_entry_impl.cc
index 0e860d70664132df34f7b3b5405f3532168c52b7..c9edd8e1c235a492b877e7700aef43aebf5e3cdb 100644
--- a/net/disk_cache/simple/simple_entry_impl.cc
+++ b/net/disk_cache/simple/simple_entry_impl.cc
@@ -133,6 +133,20 @@ void InvokeCallbackIfBackendIsAlive(
completion_callback.Run(result);
}
+// If |sync_possible| is false, and callback is available, posts rv to it and
+// return net::ERR_IO_PENDING; otherwise just passes through rv.
+int PostToCallbackIfNeeded(bool sync_possible,
+ const net::CompletionCallback& callback,
+ int rv) {
+ if (!sync_possible && !callback.is_null()) {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
+ base::Bind(callback, rv));
+ return net::ERR_IO_PENDING;
+ } else {
+ return rv;
+ }
+}
+
} // namespace
using base::Closure;
@@ -370,23 +384,17 @@ int SimpleEntryImpl::ReadData(int stream_index,
RecordReadResult(cache_type_, READ_RESULT_INVALID_ARGUMENT);
return net::ERR_INVALID_ARGUMENT;
}
- if (pending_operations_.empty() && (offset >= GetDataSize(stream_index) ||
- offset < 0 || !buf_len)) {
- if (net_log_.IsCapturing()) {
- net_log_.AddEvent(net::NetLogEventType::SIMPLE_CACHE_ENTRY_READ_END,
- CreateNetLogReadWriteCompleteCallback(0));
- }
-
- RecordReadResult(cache_type_, READ_RESULT_NONBLOCK_EMPTY_RETURN);
- return 0;
- }
-
- // TODO(clamy): return immediatly when reading from stream 0.
// TODO(felipeg): Optimization: Add support for truly parallel read
// operations.
bool alone_in_queue =
pending_operations_.size() == 0 && state_ == STATE_READY;
+
+ if (alone_in_queue) {
+ return ReadDataInternal(/*sync_possible = */ true, stream_index, offset,
+ buf, buf_len, callback);
+ }
+
pending_operations_.push(SimpleEntryOperation::ReadOperation(
this, stream_index, offset, buf_len, buf, callback, alone_in_queue));
RunNextOperationIfNeeded();
@@ -634,11 +642,9 @@ void SimpleEntryImpl::RunNextOperationIfNeeded() {
break;
case SimpleEntryOperation::TYPE_READ:
RecordReadIsParallelizable(*operation);
- ReadDataInternal(operation->index(),
- operation->offset(),
- operation->buf(),
- operation->length(),
- operation->callback());
+ ReadDataInternal(/* sync_possible= */ false, operation->index(),
+ operation->offset(), operation->buf(),
+ operation->length(), operation->callback());
break;
case SimpleEntryOperation::TYPE_WRITE:
RecordWriteDependencyType(*operation);
@@ -809,11 +815,12 @@ void SimpleEntryImpl::CloseInternal() {
}
}
-void SimpleEntryImpl::ReadDataInternal(int stream_index,
- int offset,
- net::IOBuffer* buf,
- int buf_len,
- const CompletionCallback& callback) {
+int SimpleEntryImpl::ReadDataInternal(bool sync_possible,
+ int stream_index,
+ int offset,
+ net::IOBuffer* buf,
+ int buf_len,
+ const CompletionCallback& callback) {
DCHECK(io_thread_checker_.CalledOnValidThread());
ScopedOperationRunner operation_runner(this);
@@ -824,38 +831,33 @@ void SimpleEntryImpl::ReadDataInternal(int stream_index,
}
if (state_ == STATE_FAILURE || state_ == STATE_UNINITIALIZED) {
- if (!callback.is_null()) {
- RecordReadResult(cache_type_, READ_RESULT_BAD_STATE);
- // Note that the API states that client-provided callbacks for entry-level
- // (i.e. non-backend) operations (e.g. read, write) are invoked even if
- // the backend was already destroyed.
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::Bind(callback, net::ERR_FAILED));
- }
+ RecordReadResult(cache_type_, READ_RESULT_BAD_STATE);
if (net_log_.IsCapturing()) {
net_log_.AddEvent(net::NetLogEventType::SIMPLE_CACHE_ENTRY_READ_END,
CreateNetLogReadWriteCompleteCallback(net::ERR_FAILED));
}
- return;
+ // Note that the API states that client-provided callbacks for entry-level
+ // (i.e. non-backend) operations (e.g. read, write) are invoked even if
+ // the backend was already destroyed.
+ return PostToCallbackIfNeeded(sync_possible, callback, net::ERR_FAILED);
}
DCHECK_EQ(STATE_READY, state_);
if (offset >= GetDataSize(stream_index) || offset < 0 || !buf_len) {
- RecordReadResult(cache_type_, READ_RESULT_FAST_EMPTY_RETURN);
+ RecordReadResult(cache_type_, sync_possible
+ ? READ_RESULT_NONBLOCK_EMPTY_RETURN
+ : READ_RESULT_FAST_EMPTY_RETURN);
// If there is nothing to read, we bail out before setting state_ to
- // STATE_IO_PENDING.
- if (!callback.is_null())
- base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
- base::Bind(callback, 0));
- return;
+ // STATE_IO_PENDING (so ScopedOperationRunner might start us on next op
+ // here).
+ return PostToCallbackIfNeeded(sync_possible, callback, 0);
}
buf_len = std::min(buf_len, GetDataSize(stream_index) - offset);
// Since stream 0 data is kept in memory, it is read immediately.
if (stream_index == 0) {
- ReadFromBufferAndPostReply(stream_0_data_.get(), offset, buf_len, buf,
- callback);
- return;
+ int rv = ReadFromBuffer(stream_0_data_.get(), offset, buf_len, buf);
+ return PostToCallbackIfNeeded(sync_possible, callback, rv);
}
// Sometimes we can read in-ram prefetched stream 1 data immediately, too.
@@ -867,9 +869,9 @@ void SimpleEntryImpl::ReadDataInternal(int stream_index,
is_initial_stream1_read_ = false;
if (stream_1_prefetch_data_) {
- ReadFromBufferAndPostReply(stream_1_prefetch_data_.get(), offset, buf_len,
- buf, callback);
- return;
+ int rv =
+ ReadFromBuffer(stream_1_prefetch_data_.get(), offset, buf_len, buf);
+ return PostToCallbackIfNeeded(sync_possible, callback, rv);
}
}
@@ -905,6 +907,7 @@ void SimpleEntryImpl::ReadDataInternal(int stream_index,
offset, callback, base::Passed(&crc_request),
base::Passed(&entry_stat), base::Passed(&result));
worker_pool_->PostTaskAndReply(FROM_HERE, task, reply);
+ return net::ERR_IO_PENDING;
}
void SimpleEntryImpl::WriteDataInternal(int stream_index,
@@ -1478,27 +1481,17 @@ void SimpleEntryImpl::RecordWriteDependencyType(
type, WRITE_DEPENDENCY_TYPE_MAX);
}
-void SimpleEntryImpl::ReadFromBufferAndPostReply(
- net::GrowableIOBuffer* in_buf,
- int offset,
- int buf_len,
- net::IOBuffer* out_buf,
- const CompletionCallback& callback) {
- int rv;
- if (buf_len < 0) {
- RecordReadResult(cache_type_, READ_RESULT_SYNC_READ_FAILURE);
- rv = 0;
- } else {
- memcpy(out_buf->data(), in_buf->data() + offset, buf_len);
- UpdateDataFromEntryStat(SimpleEntryStat(base::Time::Now(), last_modified_,
- data_size_, sparse_data_size_));
- RecordReadResult(cache_type_, READ_RESULT_SUCCESS);
- rv = buf_len;
- }
- if (!callback.is_null()) {
- base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
- base::Bind(callback, rv));
- }
+int SimpleEntryImpl::ReadFromBuffer(net::GrowableIOBuffer* in_buf,
+ int offset,
+ int buf_len,
+ net::IOBuffer* out_buf) {
+ DCHECK_GE(buf_len, 0);
+
+ memcpy(out_buf->data(), in_buf->data() + offset, buf_len);
+ UpdateDataFromEntryStat(SimpleEntryStat(base::Time::Now(), last_modified_,
+ data_size_, sparse_data_size_));
+ RecordReadResult(cache_type_, READ_RESULT_SUCCESS);
+ return buf_len;
}
int SimpleEntryImpl::SetStream0Data(net::IOBuffer* buf,
« no previous file with comments | « net/disk_cache/simple/simple_entry_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698