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

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

Issue 14130015: Support overlapping operations on the SimpleEntryImpl. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 8 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 1917a88715091ac1a37be9dae3b8fd104b6f4edf..580caf5d4c9a2c35a815c4e51de59f7b8481915b 100644
--- a/net/disk_cache/simple/simple_entry_impl.cc
+++ b/net/disk_cache/simple/simple_entry_impl.cc
@@ -88,6 +88,7 @@ int SimpleEntryImpl::DoomEntry(WeakPtr<SimpleIndex> index,
void SimpleEntryImpl::Doom() {
DCHECK(io_thread_checker_.CalledOnValidThread());
+ DCHECK(!operation_running_);
#if defined(OS_POSIX)
// This call to static SimpleEntryImpl::DoomEntry() will just erase the
// underlying files. On POSIX, this is fine; the files are still open on the
@@ -101,12 +102,22 @@ void SimpleEntryImpl::Doom() {
void SimpleEntryImpl::Close() {
DCHECK(io_thread_checker_.CalledOnValidThread());
- if (!synchronous_entry_in_use_by_worker_) {
- WorkerPool::PostTask(FROM_HERE,
- base::Bind(&SimpleSynchronousEntry::Close,
- base::Unretained(synchronous_entry_)),
- true);
+ if (operation_running_) {
+ // Postpone close operation.
+ // Push the close operation to the end of the line. This way we run all
+ // operations before we are able close.
+ pending_operations_.push(
+ base::Bind(&SimpleEntryImpl::Close,
+ weak_ptr_factory_.GetWeakPtr()));
+ return;
pasko-google - do not use 2013/04/17 15:14:46 since it is not a trivial if->return case, would b
felipeg 2013/04/17 15:53:57 Done.
}
+ DCHECK(pending_operations_.size() == 0);
+ DCHECK(!operation_running_);
+
+ WorkerPool::PostTask(FROM_HERE,
+ base::Bind(&SimpleSynchronousEntry::Close,
+ base::Unretained(synchronous_entry_)),
+ true);
// Entry::Close() is expected to release this entry. See disk_cache.h for
// details.
delete this;
@@ -138,27 +149,21 @@ int SimpleEntryImpl::ReadData(int index,
int buf_len,
const CompletionCallback& callback) {
DCHECK(io_thread_checker_.CalledOnValidThread());
- // TODO(gavinp): Add support for overlapping reads. The net::HttpCache does
- // make overlapping read requests when multiple transactions access the same
- // entry as read only. This might make calling SimpleSynchronousEntry::Close()
- // correctly more tricky (see SimpleEntryImpl::EntryOperationComplete).
- if (synchronous_entry_in_use_by_worker_) {
- NOTIMPLEMENTED();
- CHECK(false);
- }
- synchronous_entry_in_use_by_worker_ = true;
- if (index_)
- index_->UseIfExists(key_);
- SynchronousOperationCallback sync_operation_callback =
- base::Bind(&SimpleEntryImpl::EntryOperationComplete,
- index_, callback, weak_ptr_factory_.GetWeakPtr(),
- synchronous_entry_);
- WorkerPool::PostTask(FROM_HERE,
- base::Bind(&SimpleSynchronousEntry::ReadData,
- base::Unretained(synchronous_entry_),
- index, offset, make_scoped_refptr(buf),
- buf_len, sync_operation_callback),
- true);
+ if (index < 0 || index >= kSimpleEntryFileCount || buf_len < 0)
pasko-google - do not use 2013/04/17 15:14:46 was this requested by tests? Otherwise seems like
felipeg 2013/04/17 15:53:57 Done.
+ return net::ERR_INVALID_ARGUMENT;
+ if (offset >= data_size_[index] || offset < 0 || !buf_len)
+ return 0;
+ // TODO(felipeg): Optimization: Add support for truly parallel read
+ // operations.
+ pending_operations_.push(
+ base::Bind(&SimpleEntryImpl::ReadDataInternal,
+ weak_ptr_factory_.GetWeakPtr(),
+ index,
+ offset,
+ make_scoped_refptr(buf),
+ buf_len,
+ callback));
+ RunNextOperationIfNeeded();
return net::ERR_IO_PENDING;
}
@@ -169,23 +174,22 @@ int SimpleEntryImpl::WriteData(int index,
const CompletionCallback& callback,
bool truncate) {
DCHECK(io_thread_checker_.CalledOnValidThread());
- if (synchronous_entry_in_use_by_worker_) {
- NOTIMPLEMENTED();
- CHECK(false);
- }
- synchronous_entry_in_use_by_worker_ = true;
- if (index_)
- index_->UseIfExists(key_);
- SynchronousOperationCallback sync_operation_callback =
- base::Bind(&SimpleEntryImpl::EntryOperationComplete,
- index_, callback, weak_ptr_factory_.GetWeakPtr(),
- synchronous_entry_);
- WorkerPool::PostTask(FROM_HERE,
- base::Bind(&SimpleSynchronousEntry::WriteData,
- base::Unretained(synchronous_entry_),
- index, offset, make_scoped_refptr(buf),
- buf_len, sync_operation_callback, truncate),
- true);
+ if (index < 0 || index >= kSimpleEntryFileCount || offset < 0 || buf_len < 0)
+ return net::ERR_INVALID_ARGUMENT;
+
+ pending_operations_.push(
+ base::Bind(&SimpleEntryImpl::WriteDataInternal,
+ weak_ptr_factory_.GetWeakPtr(),
+ index,
+ offset,
+ make_scoped_refptr(buf),
+ buf_len,
+ callback,
+ truncate));
+ RunNextOperationIfNeeded();
+
+ // TODO(felipeg): Optimization: Add support for optimistic writes, quickly
+ // returning net::OK here.
return net::ERR_IO_PENDING;
}
@@ -245,7 +249,7 @@ SimpleEntryImpl::SimpleEntryImpl(
path_(synchronous_entry->path()),
key_(synchronous_entry->key()),
synchronous_entry_(synchronous_entry),
- synchronous_entry_in_use_by_worker_(false),
+ operation_running_(false),
index_(index) {
DCHECK(synchronous_entry);
SetSynchronousData();
@@ -255,6 +259,66 @@ SimpleEntryImpl::~SimpleEntryImpl() {
DCHECK(io_thread_checker_.CalledOnValidThread());
}
+bool SimpleEntryImpl::RunNextOperationIfNeeded() {
+ DCHECK(io_thread_checker_.CalledOnValidThread());
+ if (pending_operations_.size() <= 0 || operation_running_)
+ return false;
+ base::Closure operation = pending_operations_.front();
+ pending_operations_.pop();
+ operation.Run();
+ return true;
+}
+
+void SimpleEntryImpl::ReadDataInternal(int index,
+ int offset,
+ scoped_refptr<net::IOBuffer> buf,
+ int buf_len,
+ const CompletionCallback& callback) {
+ DCHECK(io_thread_checker_.CalledOnValidThread());
+ DCHECK(!operation_running_);
+ operation_running_ = true;
+ if (index_)
+ index_->UseIfExists(key_);
+ SynchronousOperationCallback sync_operation_callback =
+ base::Bind(&SimpleEntryImpl::EntryOperationComplete,
+ index_, callback, weak_ptr_factory_.GetWeakPtr(),
+ synchronous_entry_);
+ WorkerPool::PostTask(FROM_HERE,
+ base::Bind(&SimpleSynchronousEntry::ReadData,
+ base::Unretained(synchronous_entry_),
+ index, offset, buf,
+ buf_len, sync_operation_callback),
+ true);
+}
+
+void SimpleEntryImpl::WriteDataInternal(int index,
+ int offset,
+ scoped_refptr<net::IOBuffer> buf,
+ int buf_len,
+ const CompletionCallback& callback,
+ bool truncate) {
+ DCHECK(io_thread_checker_.CalledOnValidThread());
+ DCHECK(!operation_running_);
+ operation_running_ = true;
+ if (index_)
+ index_->UseIfExists(key_);
+
+ last_used_ = base::Time::Now();
+ last_modified_ = base::Time::Now();
+ data_size_[index] = buf_len;
+
+ SynchronousOperationCallback sync_operation_callback =
+ base::Bind(&SimpleEntryImpl::EntryOperationComplete,
+ index_, callback, weak_ptr_factory_.GetWeakPtr(),
+ synchronous_entry_);
+ WorkerPool::PostTask(FROM_HERE,
+ base::Bind(&SimpleSynchronousEntry::WriteData,
+ base::Unretained(synchronous_entry_),
+ index, offset, buf,
+ buf_len, sync_operation_callback, truncate),
+ true);
+}
+
// static
void SimpleEntryImpl::CreationOperationComplete(
WeakPtr<SimpleIndex> index,
@@ -291,9 +355,10 @@ void SimpleEntryImpl::EntryOperationComplete(
}
if (entry) {
- DCHECK(entry->synchronous_entry_in_use_by_worker_);
- entry->synchronous_entry_in_use_by_worker_ = false;
+ DCHECK(entry->operation_running_);
+ entry->operation_running_ = false;
entry->SetSynchronousData();
+ entry->RunNextOperationIfNeeded();
} else {
// |entry| must have had Close() called while this operation was in flight.
// Since the simple cache now only supports one pending entry operation in
@@ -308,7 +373,7 @@ void SimpleEntryImpl::EntryOperationComplete(
void SimpleEntryImpl::SetSynchronousData() {
DCHECK(io_thread_checker_.CalledOnValidThread());
- DCHECK(!synchronous_entry_in_use_by_worker_);
+ DCHECK(!operation_running_);
// TODO(felipeg): These copies to avoid data races are not optimal. While
// adding an IO thread index (for fast misses etc...), we can store this data
// in that structure. This also solves problems with last_used() on ext4
« 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