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

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

Issue 12192005: Add new simple disk cache backend. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix dcheck Created 7 years, 10 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
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
new file mode 100644
index 0000000000000000000000000000000000000000..0639b942f6e17f8d5db7cdeb2a67f8070a959a70
--- /dev/null
+++ b/net/disk_cache/simple/simple_entry_impl.cc
@@ -0,0 +1,364 @@
+// Copyright (c) 2013 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/simple/simple_entry_impl.h"
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/callback.h"
+#include "base/location.h"
+#include "base/message_loop_proxy.h"
+#include "base/threading/worker_pool.h"
+#include "net/base/io_buffer.h"
+#include "net/base/net_errors.h"
+#include "net/disk_cache/simple/simple_synchronous_entry.h"
+
+
+namespace {
+
+typedef disk_cache::Entry::CompletionCallback CompletionCallback;
+typedef disk_cache::SimpleSynchronousEntry::SynchronousEntryCallback
+ SynchronousEntryCallback;
+
+} // namespace
+
+namespace disk_cache {
+
+using base::FilePath;
+using base::MessageLoopProxy;
+using base::Time;
+using base::WeakPtr;
+using base::WorkerPool;
+
+// A PendingCreationOperation represents a pending operation that is creating a
+// new SimpleSynchronousEntry, such as OpenEntry() or CreateEntry(). It ensures
+// that a SimpleEntryImpl is only created after the underlying synchronous
+// operation has succeeded.
+class SimpleEntryImpl::PendingCreationOperation {
felipeg 2013/02/12 13:25:20 As discussed by chat, we don't really need a class
gavinp 2013/02/12 15:45:57 Great suggestion. I was being too ornate.
+ public:
+ static SynchronousEntryCallback Create(
+ const CompletionCallback& completion_callback,
+ Entry** out_entry);
+
+ private:
+ PendingCreationOperation(const CompletionCallback& completion_callback,
+ Entry** out_entry);
+
+ void OnIOComplete(SimpleSynchronousEntry* sync_entry, int result);
+
+ CompletionCallback completion_callback_;
+ Entry** out_entry_;
+};
+
+// A PendingEntryOperation represents an operation on a SynchronousEntry while
+// it is in flight. It informs the owning SimpleEntryImpl of IO completion if
+// necessary, as well as calling the IO completion callback.
+class SimpleEntryImpl::PendingEntryOperation {
felipeg 2013/02/12 13:25:20 ditto.
gavinp 2013/02/12 15:45:57 ditto!
+ public:
+ static SynchronousEntryCallback Create(
+ const WeakPtr<SimpleEntryImpl>& entry,
+ const CompletionCallback& completion_callback);
+
+ private:
+ PendingEntryOperation(const WeakPtr<SimpleEntryImpl>& entry,
+ const CompletionCallback& completion_callback);
+
+ void OnIOComplete(SimpleSynchronousEntry* sync_entry, int result);
+
+ WeakPtr<SimpleEntryImpl> entry_;
+ CompletionCallback completion_callback_;
+};
+
+// static
+SynchronousEntryCallback SimpleEntryImpl::PendingCreationOperation::Create(
+ const CompletionCallback& completion_callback,
+ Entry** out_entry) {
+ PendingCreationOperation* operation =
+ new PendingCreationOperation(completion_callback, out_entry);
+ DCHECK(operation);
+ return base::Bind(&PendingCreationOperation::OnIOComplete,
+ base::Owned(operation));
+}
+
+SimpleEntryImpl::PendingCreationOperation::PendingCreationOperation(
+ const CompletionCallback& completion_callback,
+ Entry** out_entry) : completion_callback_(completion_callback),
+ out_entry_(out_entry) {
+}
+
+void SimpleEntryImpl::PendingCreationOperation::OnIOComplete(
+ SimpleSynchronousEntry* sync_entry,
+ int result) {
+ DCHECK_NE(net::ERR_IO_PENDING, result);
+
+ if (result != net::OK) {
+ DCHECK(!sync_entry) << "sync_entry = " << sync_entry;
+ completion_callback_.Run(result);
+ return;
+ }
+ DCHECK(sync_entry);
+ *out_entry_ = new SimpleEntryImpl(sync_entry);
+ DCHECK(*out_entry_);
+ completion_callback_.Run(net::OK);
+}
+
+// static
+SynchronousEntryCallback SimpleEntryImpl::PendingEntryOperation::Create(
+ const WeakPtr<SimpleEntryImpl>& entry,
+ const CompletionCallback& completion_callback) {
+ PendingEntryOperation* operation = new PendingEntryOperation(entry,
+ completion_callback);
+ DCHECK(operation);
+ return base::Bind(&PendingEntryOperation::OnIOComplete,
+ base::Owned(operation));
+}
+
+SimpleEntryImpl::PendingEntryOperation::PendingEntryOperation(
+ const WeakPtr<SimpleEntryImpl>& entry,
+ const CompletionCallback& completion_callback)
+ : entry_(entry),
+ completion_callback_(completion_callback) {
+}
+
+void SimpleEntryImpl::PendingEntryOperation::OnIOComplete(
+ SimpleSynchronousEntry* sync_entry,
+ int result) {
+ DCHECK(sync_entry);
+ if (entry_)
+ entry_->SetSynchronousEntry(sync_entry);
+ completion_callback_.Run(result);
+}
+
+// static
+int SimpleEntryImpl::OpenEntry(const FilePath& path,
+ const std::string& key,
+ Entry** entry,
+ const CompletionCallback& callback) {
+ SynchronousEntryCallback sync_entry_callback =
+ PendingCreationOperation::Create(callback, entry);
+
+ WorkerPool::PostTask(FROM_HERE,
+ base::Bind(&SimpleSynchronousEntry::OpenEntry, path, key,
+ MessageLoopProxy::current(),
+ sync_entry_callback),
+ true);
+ return net::ERR_IO_PENDING;
+}
+
+// static
+int SimpleEntryImpl::CreateEntry(const FilePath& path,
+ const std::string& key,
+ Entry** entry,
+ const CompletionCallback& callback) {
+ SynchronousEntryCallback sync_entry_callback =
+ PendingCreationOperation::Create(callback, entry);
+ WorkerPool::PostTask(FROM_HERE,
+ base::Bind(&SimpleSynchronousEntry::CreateEntry, path,
+ key, MessageLoopProxy::current(),
+ sync_entry_callback),
+ true);
+ return net::ERR_IO_PENDING;
+}
+
+// static
+int SimpleEntryImpl::DoomEntry(const FilePath& path,
+ const std::string& key,
+ const CompletionCallback& callback) {
+ WorkerPool::PostTask(FROM_HERE,
+ base::Bind(&SimpleSynchronousEntry::DoomEntry, path, key,
+ MessageLoopProxy::current(), callback),
+ true);
+ return net::ERR_IO_PENDING;
+}
+
+void SimpleEntryImpl::Doom() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ if (!synchronous_entry_) {
+ NOTIMPLEMENTED() << ": Overlapping an asynchronous operation.";
+ return;
+ }
+ WorkerPool::PostTask(FROM_HERE,
+ base::Bind(&SimpleSynchronousEntry::DoomAndClose,
+ base::Unretained(ReleaseSynchronousEntry())),
+ true);
+ has_been_doomed_ = true;
+}
+
+void SimpleEntryImpl::Close() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ if (!synchronous_entry_) {
+ NOTIMPLEMENTED() << ": Overlapping an asynchronous operation.";
+ delete this;
+ return;
+ }
+ if (!has_been_doomed_) {
+ WorkerPool::PostTask(FROM_HERE,
+ base::Bind(&SimpleSynchronousEntry::Close,
+ base::Unretained(
+ ReleaseSynchronousEntry())),
+ true);
+ }
+ // Entry::Close() is expected to release this entry. See disk_cache.h for
+ // details.
+ delete this;
+}
+
+std::string SimpleEntryImpl::GetKey() const {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ return key_;
+}
+
+Time SimpleEntryImpl::GetLastUsed() const {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ if (!synchronous_entry_) {
+ NOTIMPLEMENTED() << ": Synchronous operations overlapping an asynchronous "
+ << "operation.";
+ NOTREACHED();
+ }
+ return synchronous_entry_->last_used();
+}
+
+Time SimpleEntryImpl::GetLastModified() const {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ if (!synchronous_entry_) {
+ NOTIMPLEMENTED() << ": Synchronous operations overlapping an asynchronous "
+ << "operation.";
+ NOTREACHED();
+ }
+ return synchronous_entry_->last_modified();
+}
+
+int32 SimpleEntryImpl::GetDataSize(int index) const {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ if (!synchronous_entry_) {
+ NOTIMPLEMENTED() << ": Synchronous operations overlapping an asynchronous "
+ << "operation.";
+ NOTREACHED();
+ }
+ return synchronous_entry_->data_size(index);
+}
+
+int SimpleEntryImpl::ReadData(int index,
+ int offset,
+ net::IOBuffer* buf,
+ int buf_len,
+ const CompletionCallback& callback) {
+ DCHECK(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.
+ if (!synchronous_entry_) {
+ NOTIMPLEMENTED() << ": Overlapping calls to ReadData.";
+ NOTREACHED();
+ }
+ SynchronousEntryCallback sync_entry_callback =
+ PendingEntryOperation::Create(weak_ptr_factory_.GetWeakPtr(), callback);
+ WorkerPool::PostTask(FROM_HERE,
+ base::Bind(&SimpleSynchronousEntry::ReadData,
+ base::Unretained(ReleaseSynchronousEntry()),
+ index, offset, scoped_refptr<IOBuffer>(buf),
+ buf_len, sync_entry_callback),
+ true);
+ return net::ERR_IO_PENDING;
+}
+
+int SimpleEntryImpl::WriteData(int index,
+ int offset,
+ net::IOBuffer* buf,
+ int buf_len,
+ const CompletionCallback& callback,
+ bool truncate) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ if (!synchronous_entry_) {
+ NOTIMPLEMENTED() << ": Overlapping calls to WriteData.";
+ NOTREACHED();
+ }
+ SynchronousEntryCallback sync_entry_callback =
+ PendingEntryOperation::Create(weak_ptr_factory_.GetWeakPtr(), callback);
+ WorkerPool::PostTask(FROM_HERE,
+ base::Bind(&SimpleSynchronousEntry::WriteData,
+ base::Unretained(ReleaseSynchronousEntry()),
+ index, offset, scoped_refptr<IOBuffer>(buf),
+ buf_len, sync_entry_callback, truncate),
+ true);
+ return net::ERR_IO_PENDING;
+}
+
+int SimpleEntryImpl::ReadSparseData(int64 offset,
+ net::IOBuffer* buf,
+ int buf_len,
+ const CompletionCallback& callback) {
+ // TODO(gavinp): Determine if the simple backend should support sparse data.
+ DCHECK(thread_checker_.CalledOnValidThread());
+ NOTIMPLEMENTED();
+ return net::ERR_FAILED;
+}
+
+int SimpleEntryImpl::WriteSparseData(int64 offset,
+ net::IOBuffer* buf,
+ int buf_len,
+ const CompletionCallback& callback) {
+ // TODO(gavinp): Determine if the simple backend should support sparse data.
+ DCHECK(thread_checker_.CalledOnValidThread());
+ NOTIMPLEMENTED();
+ return net::ERR_FAILED;
+}
+
+int SimpleEntryImpl::GetAvailableRange(int64 offset,
+ int len,
+ int64* start,
+ const CompletionCallback& callback) {
+ // TODO(gavinp): Determine if the simple backend should support sparse data.
+ DCHECK(thread_checker_.CalledOnValidThread());
+ NOTIMPLEMENTED();
+ return net::ERR_FAILED;
+}
+
+bool SimpleEntryImpl::CouldBeSparse() const {
+ // TODO(gavinp): Determine if the simple backend should support sparse data.
+ DCHECK(thread_checker_.CalledOnValidThread());
+ return false;
+}
+
+void SimpleEntryImpl::CancelSparseIO() {
+ // TODO(gavinp): Determine if the simple backend should support sparse data.
+ DCHECK(thread_checker_.CalledOnValidThread());
+ NOTIMPLEMENTED();
+}
+
+int SimpleEntryImpl::ReadyForSparseIO(const CompletionCallback& callback) {
+ // TODO(gavinp): Determine if the simple backend should support sparse data.
+ DCHECK(thread_checker_.CalledOnValidThread());
+ NOTIMPLEMENTED();
+ return net::ERR_FAILED;
+}
+
+SimpleEntryImpl::SimpleEntryImpl(
+ SimpleSynchronousEntry* synchronous_entry)
+ : ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)),
+ key_(synchronous_entry->key()),
+ synchronous_entry_(synchronous_entry),
+ has_been_doomed_(false) {
+ DCHECK(synchronous_entry);
+}
+
+SimpleEntryImpl::~SimpleEntryImpl() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(!synchronous_entry_) << "synchronous_entry_ = " << synchronous_entry_;
+}
+
+SimpleSynchronousEntry* SimpleEntryImpl::ReleaseSynchronousEntry() {
+ DCHECK(synchronous_entry_);
+ SimpleSynchronousEntry* retval = synchronous_entry_;
+ synchronous_entry_ = NULL;
+ return retval;
+}
+
+void SimpleEntryImpl::SetSynchronousEntry(
+ SimpleSynchronousEntry* synchronous_entry) {
+ DCHECK(!synchronous_entry_) << "synchronous_entry_ = " << synchronous_entry_;
+ synchronous_entry_ = synchronous_entry;
+}
+
+} // namespace disk_cache

Powered by Google App Engine
This is Rietveld 408576698