diff options
author | jhawkins@chromium.org <jhawkins@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-12-06 19:11:51 +0000 |
---|---|---|
committer | jhawkins@chromium.org <jhawkins@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-12-06 19:11:51 +0000 |
commit | 8ebf9b135df2b2a79cf130d39a48185b8f851338 (patch) | |
tree | b1f393ed627e91bf098bffff4fac3b9f3696e59b /net | |
parent | 0b349ba539020caa0201c6523813a16fa41a3448 (diff) | |
download | chromium_src-8ebf9b135df2b2a79cf130d39a48185b8f851338.zip chromium_src-8ebf9b135df2b2a79cf130d39a48185b8f851338.tar.gz chromium_src-8ebf9b135df2b2a79cf130d39a48185b8f851338.tar.bz2 |
base::Bind: Convert disk_cache_based_ssl_host_info.
BUG=none
TEST=none
R=csilv@chromium.org
Review URL: http://codereview.chromium.org/8794003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@113249 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
23 files changed, 804 insertions, 139 deletions
diff --git a/net/base/test_completion_callback.cc b/net/base/test_completion_callback.cc index 6851a7c..9d1de1a 100644 --- a/net/base/test_completion_callback.cc +++ b/net/base/test_completion_callback.cc @@ -9,50 +9,53 @@ #include "base/message_loop.h" #include "net/base/net_errors.h" -TestOldCompletionCallback::TestOldCompletionCallback() - : result_(0), - have_result_(false), - waiting_for_result_(false) { +void TestCompletionCallbackBase::SetResult(int result) { + result_ = result; + have_result_ = true; + if (waiting_for_result_) + MessageLoop::current()->Quit(); } -TestOldCompletionCallback::~TestOldCompletionCallback() {} - -int TestOldCompletionCallback::WaitForResult() { +int TestCompletionCallbackBase::WaitForResult() { DCHECK(!waiting_for_result_); + while (!have_result_) { + printf("waiting\n"); waiting_for_result_ = true; MessageLoop::current()->Run(); waiting_for_result_ = false; } - have_result_ = false; // auto-reset for next callback + + have_result_ = false; // Auto-reset for next callback. return result_; } -int TestOldCompletionCallback::GetResult(int result) { +int TestCompletionCallbackBase::GetResult(int result) { if (net::ERR_IO_PENDING != result) return result; + return WaitForResult(); } +TestCompletionCallbackBase::TestCompletionCallbackBase() + : result_(0), + have_result_(false), + waiting_for_result_(false) { +} + void TestOldCompletionCallback::RunWithParams(const Tuple1<int>& params) { - result_ = params.a; - have_result_ = true; - if (waiting_for_result_) - MessageLoop::current()->Quit(); + SetResult(params.a); } namespace net { TestCompletionCallback::TestCompletionCallback() : ALLOW_THIS_IN_INITIALIZER_LIST(callback_( - base::Bind(&TestCompletionCallback::OnComplete, + base::Bind(&TestCompletionCallback::SetResult, base::Unretained(this)))) { } TestCompletionCallback::~TestCompletionCallback() {} -void TestCompletionCallback::OnComplete(int result) { - old_callback_impl_.RunWithParams(Tuple1<int>(result)); -} } // namespace net diff --git a/net/base/test_completion_callback.h b/net/base/test_completion_callback.h index a192194..888c610 100644 --- a/net/base/test_completion_callback.h +++ b/net/base/test_completion_callback.h @@ -22,45 +22,51 @@ // there could be other side-effects resulting from WaitForResult. For this // reason, this class is probably not ideal for a general application. // -class TestOldCompletionCallback : public CallbackRunner< Tuple1<int> > { - public: - TestOldCompletionCallback(); - virtual ~TestOldCompletionCallback(); +// Base class overridden by custom implementations of TestCompletionCallback. +class TestCompletionCallbackBase { + public: + void SetResult(int result); int WaitForResult(); - int GetResult(int result); - bool have_result() const { return have_result_; } - virtual void RunWithParams(const Tuple1<int>& params) OVERRIDE; + protected: + TestCompletionCallbackBase(); - private: int result_; bool have_result_; bool waiting_for_result_; + + private: + DISALLOW_COPY_AND_ASSIGN(TestCompletionCallbackBase); +}; + +class TestOldCompletionCallback : public TestCompletionCallbackBase, + public CallbackRunner< Tuple1<int> > { + public: + TestOldCompletionCallback() {}; + virtual ~TestOldCompletionCallback() {} + + virtual void RunWithParams(const Tuple1<int>& params) OVERRIDE; + + private: + DISALLOW_COPY_AND_ASSIGN(TestOldCompletionCallback); }; namespace net { -class TestCompletionCallback { +class TestCompletionCallback : public TestCompletionCallbackBase { public: TestCompletionCallback(); ~TestCompletionCallback(); - int WaitForResult() { return old_callback_impl_.WaitForResult(); } - - int GetResult(int result) { return old_callback_impl_.GetResult(result); } - - bool have_result() const { return old_callback_impl_.have_result(); } - const CompletionCallback& callback() const { return callback_; } private: - void OnComplete(int result); - const CompletionCallback callback_; - TestOldCompletionCallback old_callback_impl_; + + DISALLOW_COPY_AND_ASSIGN(TestCompletionCallback); }; } // namespace net diff --git a/net/disk_cache/backend_impl.cc b/net/disk_cache/backend_impl.cc index 14a2722..1c6c92a 100644 --- a/net/disk_cache/backend_impl.cc +++ b/net/disk_cache/backend_impl.cc @@ -1381,6 +1381,13 @@ int BackendImpl::OpenEntry(const std::string& key, Entry** entry, return net::ERR_IO_PENDING; } +int BackendImpl::OpenEntry(const std::string& key, Entry** entry, + const net::CompletionCallback& callback) { + DCHECK(!callback.is_null()); + background_queue_.OpenEntry(key, entry, callback); + return net::ERR_IO_PENDING; +} + int BackendImpl::CreateEntry(const std::string& key, Entry** entry, OldCompletionCallback* callback) { DCHECK(callback); @@ -1388,6 +1395,13 @@ int BackendImpl::CreateEntry(const std::string& key, Entry** entry, return net::ERR_IO_PENDING; } +int BackendImpl::CreateEntry(const std::string& key, Entry** entry, + const net::CompletionCallback& callback) { + DCHECK(!callback.is_null()); + background_queue_.CreateEntry(key, entry, callback); + return net::ERR_IO_PENDING; +} + int BackendImpl::DoomEntry(const std::string& key, OldCompletionCallback* callback) { DCHECK(callback); diff --git a/net/disk_cache/backend_impl.h b/net/disk_cache/backend_impl.h index 1e38678..0cf1fac 100644 --- a/net/disk_cache/backend_impl.h +++ b/net/disk_cache/backend_impl.h @@ -65,7 +65,7 @@ class NET_EXPORT_PRIVATE BackendImpl : public Backend { int SyncInit(); void CleanupCache(); - // Same bahavior as OpenNextEntry but walks the list from back to front. + // Same behavior as OpenNextEntry but walks the list from back to front. int OpenPrevEntry(void** iter, Entry** prev_entry, OldCompletionCallback* callback); @@ -260,8 +260,12 @@ class NET_EXPORT_PRIVATE BackendImpl : public Backend { virtual int32 GetEntryCount() const OVERRIDE; virtual int OpenEntry(const std::string& key, Entry** entry, OldCompletionCallback* callback) OVERRIDE; + virtual int OpenEntry(const std::string& key, Entry** entry, + const net::CompletionCallback& callback) OVERRIDE; virtual int CreateEntry(const std::string& key, Entry** entry, OldCompletionCallback* callback) OVERRIDE; + virtual int CreateEntry(const std::string& key, Entry** entry, + const net::CompletionCallback& callback) OVERRIDE; virtual int DoomEntry(const std::string& key, OldCompletionCallback* callback) OVERRIDE; virtual int DoomAllEntries(OldCompletionCallback* callback) OVERRIDE; diff --git a/net/disk_cache/disk_cache.h b/net/disk_cache/disk_cache.h index 3e0efa6..8fc74b7 100644 --- a/net/disk_cache/disk_cache.h +++ b/net/disk_cache/disk_cache.h @@ -78,6 +78,8 @@ class NET_EXPORT Backend { // |entry| must remain valid until the operation completes. virtual int OpenEntry(const std::string& key, Entry** entry, OldCompletionCallback* callback) = 0; + virtual int OpenEntry(const std::string& key, Entry** entry, + const net::CompletionCallback& callback) = 0; // Creates a new entry. Upon success, the out param holds a pointer to an // Entry object representing the newly created disk cache entry. When the @@ -87,6 +89,8 @@ class NET_EXPORT Backend { // receive the |entry| must remain valid until the operation completes. virtual int CreateEntry(const std::string& key, Entry** entry, OldCompletionCallback* callback) = 0; + virtual int CreateEntry(const std::string& key, Entry** entry, + const net::CompletionCallback& callback) = 0; // Marks the entry, specified by the given key, for deletion. The return value // is a net error code. If this method returns ERR_IO_PENDING, the |callback| @@ -179,6 +183,8 @@ class NET_EXPORT Entry { // performed from the callback code. virtual int ReadData(int index, int offset, net::IOBuffer* buf, int buf_len, OldCompletionCallback* completion_callback) = 0; + virtual int ReadData(int index, int offset, net::IOBuffer* buf, int buf_len, + const net::CompletionCallback& completion_callback) = 0; // Copies cache data from the given buffer of length |buf_len|. If // completion_callback is null, then this call blocks until the write @@ -196,6 +202,9 @@ class NET_EXPORT Entry { virtual int WriteData(int index, int offset, net::IOBuffer* buf, int buf_len, OldCompletionCallback* completion_callback, bool truncate) = 0; + virtual int WriteData(int index, int offset, net::IOBuffer* buf, int buf_len, + const net::CompletionCallback& completion_callback, + bool truncate) = 0; // Sparse entries support: // diff --git a/net/disk_cache/entry_impl.cc b/net/disk_cache/entry_impl.cc index 7e13029..7ba6e94 100644 --- a/net/disk_cache/entry_impl.cc +++ b/net/disk_cache/entry_impl.cc @@ -35,6 +35,14 @@ class SyncCallback: public disk_cache::FileIOCallback { SyncCallback(disk_cache::EntryImpl* entry, net::IOBuffer* buffer, net::OldCompletionCallback* callback, net::NetLog::EventType end_event_type) + : entry_(entry), old_callback_(callback), buf_(buffer), + start_(TimeTicks::Now()), end_event_type_(end_event_type) { + entry->AddRef(); + entry->IncrementIoCount(); + } + SyncCallback(disk_cache::EntryImpl* entry, net::IOBuffer* buffer, + const net::CompletionCallback& callback, + net::NetLog::EventType end_event_type) : entry_(entry), callback_(callback), buf_(buffer), start_(TimeTicks::Now()), end_event_type_(end_event_type) { entry->AddRef(); @@ -47,7 +55,8 @@ class SyncCallback: public disk_cache::FileIOCallback { private: disk_cache::EntryImpl* entry_; - net::OldCompletionCallback* callback_; + net::OldCompletionCallback* old_callback_; + net::CompletionCallback callback_; scoped_refptr<net::IOBuffer> buf_; TimeTicks start_; const net::NetLog::EventType end_event_type_; @@ -57,7 +66,7 @@ class SyncCallback: public disk_cache::FileIOCallback { void SyncCallback::OnFileIOComplete(int bytes_copied) { entry_->DecrementIoCount(); - if (callback_) { + if (old_callback_ || !callback_.is_null()) { if (entry_->net_log().IsLoggingAllEvents()) { entry_->net_log().EndEvent( end_event_type_, @@ -65,14 +74,19 @@ void SyncCallback::OnFileIOComplete(int bytes_copied) { new disk_cache::ReadWriteCompleteParameters(bytes_copied))); } entry_->ReportIOTime(disk_cache::EntryImpl::kAsyncIO, start_); - callback_->Run(bytes_copied); + + if (old_callback_) + old_callback_->Run(bytes_copied); + else + callback_.Run(bytes_copied); } entry_->Release(); delete this; } void SyncCallback::Discard() { - callback_ = NULL; + old_callback_ = NULL; + callback_.Reset(); buf_ = NULL; OnFileIOComplete(0); } @@ -327,6 +341,26 @@ int EntryImpl::ReadDataImpl(int index, int offset, net::IOBuffer* buf, return result; } +int EntryImpl::ReadDataImpl( + int index, int offset, net::IOBuffer* buf, int buf_len, + const net::CompletionCallback& callback) { + if (net_log_.IsLoggingAllEvents()) { + net_log_.BeginEvent( + net::NetLog::TYPE_ENTRY_READ_DATA, + make_scoped_refptr( + new ReadWriteDataParameters(index, offset, buf_len, false))); + } + + int result = InternalReadData(index, offset, buf, buf_len, callback); + + if (result != net::ERR_IO_PENDING && net_log_.IsLoggingAllEvents()) { + net_log_.EndEvent( + net::NetLog::TYPE_ENTRY_READ_DATA, + make_scoped_refptr(new ReadWriteCompleteParameters(result))); + } + return result; +} + int EntryImpl::WriteDataImpl(int index, int offset, net::IOBuffer* buf, int buf_len, OldCompletionCallback* callback, bool truncate) { @@ -348,6 +382,27 @@ int EntryImpl::WriteDataImpl(int index, int offset, net::IOBuffer* buf, return result; } +int EntryImpl::WriteDataImpl( + int index, int offset, net::IOBuffer* buf, int buf_len, + const net::CompletionCallback& callback, bool truncate) { + if (net_log_.IsLoggingAllEvents()) { + net_log_.BeginEvent( + net::NetLog::TYPE_ENTRY_WRITE_DATA, + make_scoped_refptr( + new ReadWriteDataParameters(index, offset, buf_len, truncate))); + } + + int result = InternalWriteData(index, offset, buf, buf_len, callback, + truncate); + + if (result != net::ERR_IO_PENDING && net_log_.IsLoggingAllEvents()) { + net_log_.EndEvent( + net::NetLog::TYPE_ENTRY_WRITE_DATA, + make_scoped_refptr(new ReadWriteCompleteParameters(result))); + } + return result; +} + int EntryImpl::ReadSparseDataImpl(int64 offset, net::IOBuffer* buf, int buf_len, OldCompletionCallback* callback) { DCHECK(node_.Data()->dirty || read_only_); @@ -818,6 +873,27 @@ int EntryImpl::ReadData(int index, int offset, net::IOBuffer* buf, int buf_len, return net::ERR_IO_PENDING; } +int EntryImpl::ReadData(int index, int offset, net::IOBuffer* buf, int buf_len, + const net::CompletionCallback& callback) { + if (callback.is_null()) + return ReadDataImpl(index, offset, buf, buf_len, callback); + + DCHECK(node_.Data()->dirty || read_only_); + if (index < 0 || index >= kNumStreams) + return net::ERR_INVALID_ARGUMENT; + + int entry_size = entry_.Data()->data_size[index]; + if (offset >= entry_size || offset < 0 || !buf_len) + return 0; + + if (buf_len < 0) + return net::ERR_INVALID_ARGUMENT; + + backend_->background_queue()->ReadData(this, index, offset, buf, buf_len, + callback); + return net::ERR_IO_PENDING; +} + int EntryImpl::WriteData(int index, int offset, net::IOBuffer* buf, int buf_len, OldCompletionCallback* callback, bool truncate) { if (!callback) @@ -835,6 +911,24 @@ int EntryImpl::WriteData(int index, int offset, net::IOBuffer* buf, int buf_len, return net::ERR_IO_PENDING; } +int EntryImpl::WriteData( + int index, int offset, net::IOBuffer* buf, int buf_len, + const net::CompletionCallback& callback, bool truncate) { + if (callback.is_null()) + return WriteDataImpl(index, offset, buf, buf_len, callback, truncate); + + DCHECK(node_.Data()->dirty || read_only_); + if (index < 0 || index >= kNumStreams) + return net::ERR_INVALID_ARGUMENT; + + if (offset < 0 || buf_len < 0) + return net::ERR_INVALID_ARGUMENT; + + backend_->background_queue()->WriteData(this, index, offset, buf, buf_len, + truncate, callback); + return net::ERR_IO_PENDING; +} + int EntryImpl::ReadSparseData(int64 offset, net::IOBuffer* buf, int buf_len, net::OldCompletionCallback* callback) { if (!callback) @@ -1013,6 +1107,82 @@ int EntryImpl::InternalReadData(int index, int offset, net::IOBuffer* buf, return (completed || !callback) ? buf_len : net::ERR_IO_PENDING; } +int EntryImpl::InternalReadData( + int index, int offset, net::IOBuffer* buf, int buf_len, + const net::CompletionCallback& callback) { + DCHECK(node_.Data()->dirty || read_only_); + DVLOG(2) << "Read from " << index << " at " << offset << " : " << buf_len; + if (index < 0 || index >= kNumStreams) + return net::ERR_INVALID_ARGUMENT; + + int entry_size = entry_.Data()->data_size[index]; + if (offset >= entry_size || offset < 0 || !buf_len) + return 0; + + if (buf_len < 0) + return net::ERR_INVALID_ARGUMENT; + + TimeTicks start = TimeTicks::Now(); + + if (offset + buf_len > entry_size) + buf_len = entry_size - offset; + + UpdateRank(false); + + backend_->OnEvent(Stats::READ_DATA); + backend_->OnRead(buf_len); + + Addr address(entry_.Data()->data_addr[index]); + int eof = address.is_initialized() ? entry_size : 0; + if (user_buffers_[index].get() && + user_buffers_[index]->PreRead(eof, offset, &buf_len)) { + // Complete the operation locally. + buf_len = user_buffers_[index]->Read(offset, buf, buf_len); + ReportIOTime(kRead, start); + return buf_len; + } + + address.set_value(entry_.Data()->data_addr[index]); + DCHECK(address.is_initialized()); + if (!address.is_initialized()) + return net::ERR_FAILED; + + File* file = GetBackingFile(address, index); + if (!file) + return net::ERR_FAILED; + + size_t file_offset = offset; + if (address.is_block_file()) { + DCHECK_LE(offset + buf_len, kMaxBlockSize); + file_offset += address.start_block() * address.BlockSize() + + kBlockHeaderSize; + } + + SyncCallback* io_callback = NULL; + if (!callback.is_null()) { + io_callback = new SyncCallback(this, buf, callback, + net::NetLog::TYPE_ENTRY_READ_DATA); + } + + TimeTicks start_async = TimeTicks::Now(); + + bool completed; + if (!file->Read(buf->data(), buf_len, file_offset, io_callback, &completed)) { + if (io_callback) + io_callback->Discard(); + return net::ERR_FAILED; + } + + if (io_callback && completed) + io_callback->Discard(); + + if (io_callback) + ReportIOTime(kReadAsync1, start_async); + + ReportIOTime(kRead, start); + return (completed || callback.is_null()) ? buf_len : net::ERR_IO_PENDING; +} + int EntryImpl::InternalWriteData(int index, int offset, net::IOBuffer* buf, int buf_len, OldCompletionCallback* callback, bool truncate) { @@ -1113,6 +1283,106 @@ int EntryImpl::InternalWriteData(int index, int offset, net::IOBuffer* buf, return (completed || !callback) ? buf_len : net::ERR_IO_PENDING; } +int EntryImpl::InternalWriteData( + int index, int offset, net::IOBuffer* buf, int buf_len, + const net::CompletionCallback& callback, bool truncate) { + DCHECK(node_.Data()->dirty || read_only_); + DVLOG(2) << "Write to " << index << " at " << offset << " : " << buf_len; + if (index < 0 || index >= kNumStreams) + return net::ERR_INVALID_ARGUMENT; + + if (offset < 0 || buf_len < 0) + return net::ERR_INVALID_ARGUMENT; + + int max_file_size = backend_->MaxFileSize(); + + // offset or buf_len could be negative numbers. + if (offset > max_file_size || buf_len > max_file_size || + offset + buf_len > max_file_size) { + int size = offset + buf_len; + if (size <= max_file_size) + size = kint32max; + backend_->TooMuchStorageRequested(size); + return net::ERR_FAILED; + } + + TimeTicks start = TimeTicks::Now(); + + // Read the size at this point (it may change inside prepare). + int entry_size = entry_.Data()->data_size[index]; + bool extending = entry_size < offset + buf_len; + truncate = truncate && entry_size > offset + buf_len; + Trace("To PrepareTarget 0x%x", entry_.address().value()); + if (!PrepareTarget(index, offset, buf_len, truncate)) + return net::ERR_FAILED; + + Trace("From PrepareTarget 0x%x", entry_.address().value()); + if (extending || truncate) + UpdateSize(index, entry_size, offset + buf_len); + + UpdateRank(true); + + backend_->OnEvent(Stats::WRITE_DATA); + backend_->OnWrite(buf_len); + + if (user_buffers_[index].get()) { + // Complete the operation locally. + user_buffers_[index]->Write(offset, buf, buf_len); + ReportIOTime(kWrite, start); + return buf_len; + } + + Addr address(entry_.Data()->data_addr[index]); + if (offset + buf_len == 0) { + if (truncate) { + DCHECK(!address.is_initialized()); + } + return 0; + } + + File* file = GetBackingFile(address, index); + if (!file) + return net::ERR_FAILED; + + size_t file_offset = offset; + if (address.is_block_file()) { + DCHECK_LE(offset + buf_len, kMaxBlockSize); + file_offset += address.start_block() * address.BlockSize() + + kBlockHeaderSize; + } else if (truncate || (extending && !buf_len)) { + if (!file->SetLength(offset + buf_len)) + return net::ERR_FAILED; + } + + if (!buf_len) + return 0; + + SyncCallback* io_callback = NULL; + if (!callback.is_null()) { + io_callback = new SyncCallback(this, buf, callback, + net::NetLog::TYPE_ENTRY_WRITE_DATA); + } + + TimeTicks start_async = TimeTicks::Now(); + + bool completed; + if (!file->Write(buf->data(), buf_len, file_offset, io_callback, + &completed)) { + if (io_callback) + io_callback->Discard(); + return net::ERR_FAILED; + } + + if (io_callback && completed) + io_callback->Discard(); + + if (io_callback) + ReportIOTime(kWriteAsync1, start_async); + + ReportIOTime(kWrite, start); + return (completed || callback.is_null()) ? buf_len : net::ERR_IO_PENDING; +} + // ------------------------------------------------------------------------ bool EntryImpl::CreateDataBlock(int index, int size) { diff --git a/net/disk_cache/entry_impl.h b/net/disk_cache/entry_impl.h index 62ec9d7..6ff7152 100644 --- a/net/disk_cache/entry_impl.h +++ b/net/disk_cache/entry_impl.h @@ -41,8 +41,12 @@ class NET_EXPORT_PRIVATE EntryImpl void DoomImpl(); int ReadDataImpl(int index, int offset, net::IOBuffer* buf, int buf_len, OldCompletionCallback* callback); + int ReadDataImpl(int index, int offset, net::IOBuffer* buf, int buf_len, + const net::CompletionCallback& callback); int WriteDataImpl(int index, int offset, net::IOBuffer* buf, int buf_len, OldCompletionCallback* callback, bool truncate); + int WriteDataImpl(int index, int offset, net::IOBuffer* buf, int buf_len, + const net::CompletionCallback& callback, bool truncate); int ReadSparseDataImpl(int64 offset, net::IOBuffer* buf, int buf_len, OldCompletionCallback* callback); int WriteSparseDataImpl(int64 offset, net::IOBuffer* buf, int buf_len, @@ -149,9 +153,15 @@ class NET_EXPORT_PRIVATE EntryImpl virtual int ReadData( int index, int offset, net::IOBuffer* buf, int buf_len, net::OldCompletionCallback* completion_callback) OVERRIDE; + virtual int ReadData( + int index, int offset, net::IOBuffer* buf, int buf_len, + const net::CompletionCallback& completion_callback) OVERRIDE; virtual int WriteData(int index, int offset, net::IOBuffer* buf, int buf_len, net::OldCompletionCallback* completion_callback, bool truncate) OVERRIDE; + virtual int WriteData(int index, int offset, net::IOBuffer* buf, int buf_len, + const net::CompletionCallback& completion_callback, + bool truncate) OVERRIDE; virtual int ReadSparseData( int64 offset, net::IOBuffer* buf, int buf_len, net::OldCompletionCallback* completion_callback) OVERRIDE; @@ -177,8 +187,12 @@ class NET_EXPORT_PRIVATE EntryImpl // separate functions to make logging of results simpler. int InternalReadData(int index, int offset, net::IOBuffer* buf, int buf_len, OldCompletionCallback* callback); + int InternalReadData(int index, int offset, net::IOBuffer* buf, + int buf_len, const net::CompletionCallback& callback); int InternalWriteData(int index, int offset, net::IOBuffer* buf, int buf_len, OldCompletionCallback* callback, bool truncate); + int InternalWriteData(int index, int offset, net::IOBuffer* buf, int buf_len, + const net::CompletionCallback& callback, bool truncate); // Initializes the storage for an internal or external data block. bool CreateDataBlock(int index, int size); diff --git a/net/disk_cache/in_flight_backend_io.cc b/net/disk_cache/in_flight_backend_io.cc index b99d627..d4e208a 100644 --- a/net/disk_cache/in_flight_backend_io.cc +++ b/net/disk_cache/in_flight_backend_io.cc @@ -16,7 +16,21 @@ namespace disk_cache { BackendIO::BackendIO(InFlightIO* controller, BackendImpl* backend, net::OldCompletionCallback* callback) - : BackgroundIO(controller), backend_(backend), callback_(callback), + : BackgroundIO(controller), + backend_(backend), + old_callback_(callback), + operation_(OP_NONE), + ALLOW_THIS_IN_INITIALIZER_LIST( + my_callback_(this, &BackendIO::OnIOComplete)) { + start_time_ = base::TimeTicks::Now(); +} + +BackendIO::BackendIO(InFlightIO* controller, BackendImpl* backend, + const net::CompletionCallback& callback) + : BackgroundIO(controller), + backend_(backend), + old_callback_(NULL), + callback_(callback), operation_(OP_NONE), ALLOW_THIS_IN_INITIALIZER_LIST( my_callback_(this, &BackendIO::OnIOComplete)) { @@ -313,6 +327,13 @@ void InFlightBackendIO::OpenEntry(const std::string& key, Entry** entry, PostOperation(operation); } +void InFlightBackendIO::OpenEntry(const std::string& key, Entry** entry, + const net::CompletionCallback& callback) { + scoped_refptr<BackendIO> operation(new BackendIO(this, backend_, callback)); + operation->OpenEntry(key, entry); + PostOperation(operation); +} + void InFlightBackendIO::CreateEntry(const std::string& key, Entry** entry, OldCompletionCallback* callback) { scoped_refptr<BackendIO> operation(new BackendIO(this, backend_, callback)); @@ -320,6 +341,13 @@ void InFlightBackendIO::CreateEntry(const std::string& key, Entry** entry, PostOperation(operation); } +void InFlightBackendIO::CreateEntry(const std::string& key, Entry** entry, + const net::CompletionCallback& callback) { + scoped_refptr<BackendIO> operation(new BackendIO(this, backend_, callback)); + operation->CreateEntry(key, entry); + PostOperation(operation); +} + void InFlightBackendIO::DoomEntry(const std::string& key, OldCompletionCallback* callback) { scoped_refptr<BackendIO> operation(new BackendIO(this, backend_, callback)); @@ -406,6 +434,14 @@ void InFlightBackendIO::ReadData(EntryImpl* entry, int index, int offset, PostOperation(operation); } +void InFlightBackendIO::ReadData(EntryImpl* entry, int index, int offset, + net::IOBuffer* buf, int buf_len, + const net::CompletionCallback& callback) { + scoped_refptr<BackendIO> operation(new BackendIO(this, backend_, callback)); + operation->ReadData(entry, index, offset, buf, buf_len); + PostOperation(operation); +} + void InFlightBackendIO::WriteData(EntryImpl* entry, int index, int offset, net::IOBuffer* buf, int buf_len, bool truncate, @@ -415,6 +451,15 @@ void InFlightBackendIO::WriteData(EntryImpl* entry, int index, int offset, PostOperation(operation); } +void InFlightBackendIO::WriteData(EntryImpl* entry, int index, int offset, + net::IOBuffer* buf, int buf_len, + bool truncate, + const net::CompletionCallback& callback) { + scoped_refptr<BackendIO> operation(new BackendIO(this, backend_, callback)); + operation->WriteData(entry, index, offset, buf, buf_len, truncate); + PostOperation(operation); +} + void InFlightBackendIO::ReadSparseData(EntryImpl* entry, int64 offset, net::IOBuffer* buf, int buf_len, OldCompletionCallback* callback) { @@ -464,8 +509,10 @@ void InFlightBackendIO::OnOperationComplete(BackgroundIO* operation, CACHE_UMA(TIMES, "TotalIOTime", 0, op->ElapsedTime()); } - if (op->callback() && (!cancel || op->IsEntryOperation())) - op->callback()->Run(op->result()); + if (op->old_callback() && (!cancel || op->IsEntryOperation())) + op->old_callback()->Run(op->result()); + else if (!op->callback().is_null() && (!cancel || op->IsEntryOperation())) + op->callback().Run(op->result()); } void InFlightBackendIO::PostOperation(BackendIO* operation) { diff --git a/net/disk_cache/in_flight_backend_io.h b/net/disk_cache/in_flight_backend_io.h index 17efb1a..96dc3e4 100644 --- a/net/disk_cache/in_flight_backend_io.h +++ b/net/disk_cache/in_flight_backend_io.h @@ -27,6 +27,8 @@ class BackendIO : public BackgroundIO { public: BackendIO(InFlightIO* controller, BackendImpl* backend, net::OldCompletionCallback* callback); + BackendIO(InFlightIO* controller, BackendImpl* backend, + const net::CompletionCallback& callback); // Runs the actual operation on the background thread. void ExecuteOperation(); @@ -37,7 +39,8 @@ class BackendIO : public BackgroundIO { // Returns true if this operation is directed to an entry (vs. the backend). bool IsEntryOperation(); - net::OldCompletionCallback* callback() { return callback_; } + net::OldCompletionCallback* old_callback() const { return old_callback_; } + net::CompletionCallback callback() const { return callback_; } // Grabs an extra reference of entry_. void ReferenceEntry(); @@ -113,7 +116,8 @@ class BackendIO : public BackgroundIO { void ExecuteEntryOperation(); BackendImpl* backend_; - net::OldCompletionCallback* callback_; + net::OldCompletionCallback* old_callback_; + net::CompletionCallback callback_; Operation operation_; net::OldCompletionCallbackImpl<BackendIO> my_callback_; @@ -149,8 +153,12 @@ class InFlightBackendIO : public InFlightIO { void Init(net::OldCompletionCallback* callback); void OpenEntry(const std::string& key, Entry** entry, net::OldCompletionCallback* callback); + void OpenEntry(const std::string& key, Entry** entry, + const net::CompletionCallback& callback); void CreateEntry(const std::string& key, Entry** entry, net::OldCompletionCallback* callback); + void CreateEntry(const std::string& key, Entry** entry, + const net::CompletionCallback& callback); void DoomEntry(const std::string& key, net::OldCompletionCallback* callback); void DoomAllEntries(net::OldCompletionCallback* callback); void DoomEntriesBetween(const base::Time initial_time, @@ -170,8 +178,14 @@ class InFlightBackendIO : public InFlightIO { void RunTask(Task* task, net::OldCompletionCallback* callback); void ReadData(EntryImpl* entry, int index, int offset, net::IOBuffer* buf, int buf_len, net::OldCompletionCallback* callback); - void WriteData(EntryImpl* entry, int index, int offset, net::IOBuffer* buf, - int buf_len, bool truncate, net::OldCompletionCallback* callback); + void ReadData(EntryImpl* entry, int index, int offset, net::IOBuffer* buf, + int buf_len, const net::CompletionCallback& callback); + void WriteData(EntryImpl* entry, int index, int offset, + net::IOBuffer* buf, int buf_len, bool truncate, + net::OldCompletionCallback* callback); + void WriteData(EntryImpl* entry, int index, int offset, + net::IOBuffer* buf, int buf_len, bool truncate, + const net::CompletionCallback& callback); void ReadSparseData(EntryImpl* entry, int64 offset, net::IOBuffer* buf, int buf_len, net::OldCompletionCallback* callback); void WriteSparseData(EntryImpl* entry, int64 offset, net::IOBuffer* buf, diff --git a/net/disk_cache/mem_backend_impl.cc b/net/disk_cache/mem_backend_impl.cc index f08b316..2c54049 100644 --- a/net/disk_cache/mem_backend_impl.cc +++ b/net/disk_cache/mem_backend_impl.cc @@ -136,6 +136,14 @@ int MemBackendImpl::OpenEntry(const std::string& key, Entry** entry, return net::ERR_FAILED; } +int MemBackendImpl::OpenEntry(const std::string& key, Entry** entry, + const net::CompletionCallback& callback) { + if (OpenEntry(key, entry)) + return net::OK; + + return net::ERR_FAILED; +} + int MemBackendImpl::CreateEntry(const std::string& key, Entry** entry, OldCompletionCallback* callback) { if (CreateEntry(key, entry)) @@ -144,6 +152,14 @@ int MemBackendImpl::CreateEntry(const std::string& key, Entry** entry, return net::ERR_FAILED; } +int MemBackendImpl::CreateEntry(const std::string& key, Entry** entry, + const net::CompletionCallback& callback) { + if (CreateEntry(key, entry)) + return net::OK; + + return net::ERR_FAILED; +} + int MemBackendImpl::DoomEntry(const std::string& key, OldCompletionCallback* callback) { if (DoomEntry(key)) diff --git a/net/disk_cache/mem_backend_impl.h b/net/disk_cache/mem_backend_impl.h index abf1443..022b918 100644 --- a/net/disk_cache/mem_backend_impl.h +++ b/net/disk_cache/mem_backend_impl.h @@ -66,8 +66,12 @@ class NET_EXPORT_PRIVATE MemBackendImpl : public Backend { virtual int32 GetEntryCount() const OVERRIDE; virtual int OpenEntry(const std::string& key, Entry** entry, OldCompletionCallback* callback) OVERRIDE; + virtual int OpenEntry(const std::string& key, Entry** entry, + const net::CompletionCallback& callback) OVERRIDE; virtual int CreateEntry(const std::string& key, Entry** entry, OldCompletionCallback* callback) OVERRIDE; + virtual int CreateEntry(const std::string& key, Entry** entry, + const net::CompletionCallback& callback) OVERRIDE; virtual int DoomEntry(const std::string& key, OldCompletionCallback* callback) OVERRIDE; virtual int DoomAllEntries(OldCompletionCallback* callback) OVERRIDE; diff --git a/net/disk_cache/mem_entry_impl.cc b/net/disk_cache/mem_entry_impl.cc index 677cd6a..4874761 100644 --- a/net/disk_cache/mem_entry_impl.cc +++ b/net/disk_cache/mem_entry_impl.cc @@ -185,6 +185,26 @@ int MemEntryImpl::ReadData(int index, int offset, net::IOBuffer* buf, return result; } +int MemEntryImpl::ReadData( + int index, int offset, net::IOBuffer* buf, int buf_len, + const net::CompletionCallback& completion_callback) { + if (net_log_.IsLoggingAllEvents()) { + net_log_.BeginEvent( + net::NetLog::TYPE_ENTRY_READ_DATA, + make_scoped_refptr( + new ReadWriteDataParameters(index, offset, buf_len, false))); + } + + int result = InternalReadData(index, offset, buf, buf_len); + + if (net_log_.IsLoggingAllEvents()) { + net_log_.EndEvent( + net::NetLog::TYPE_ENTRY_READ_DATA, + make_scoped_refptr(new ReadWriteCompleteParameters(result))); + } + return result; +} + int MemEntryImpl::WriteData(int index, int offset, net::IOBuffer* buf, int buf_len, net::OldCompletionCallback* completion_callback, bool truncate) { if (net_log_.IsLoggingAllEvents()) { @@ -204,6 +224,26 @@ int MemEntryImpl::WriteData(int index, int offset, net::IOBuffer* buf, return result; } +int MemEntryImpl::WriteData( + int index, int offset, net::IOBuffer* buf, int buf_len, + const net::CompletionCallback& completion_callback, bool truncate) { + if (net_log_.IsLoggingAllEvents()) { + net_log_.BeginEvent( + net::NetLog::TYPE_ENTRY_WRITE_DATA, + make_scoped_refptr( + new ReadWriteDataParameters(index, offset, buf_len, truncate))); + } + + int result = InternalWriteData(index, offset, buf, buf_len, truncate); + + if (net_log_.IsLoggingAllEvents()) { + net_log_.EndEvent( + net::NetLog::TYPE_ENTRY_WRITE_DATA, + make_scoped_refptr(new ReadWriteCompleteParameters(result))); + } + return result; +} + int MemEntryImpl::ReadSparseData(int64 offset, net::IOBuffer* buf, int buf_len, net::OldCompletionCallback* completion_callback) { if (net_log_.IsLoggingAllEvents()) { diff --git a/net/disk_cache/mem_entry_impl.h b/net/disk_cache/mem_entry_impl.h index b1d4703..2967154 100644 --- a/net/disk_cache/mem_entry_impl.h +++ b/net/disk_cache/mem_entry_impl.h @@ -101,9 +101,15 @@ class MemEntryImpl : public Entry { virtual int ReadData( int index, int offset, net::IOBuffer* buf, int buf_len, net::OldCompletionCallback* completion_callback) OVERRIDE; + virtual int ReadData( + int index, int offset, net::IOBuffer* buf, int buf_len, + const net::CompletionCallback& completion_callback) OVERRIDE; virtual int WriteData(int index, int offset, net::IOBuffer* buf, int buf_len, net::OldCompletionCallback* completion_callback, bool truncate) OVERRIDE; + virtual int WriteData(int index, int offset, net::IOBuffer* buf, int buf_len, + const net::CompletionCallback& completion_callback, + bool truncate) OVERRIDE; virtual int ReadSparseData( int64 offset, net::IOBuffer* buf, int buf_len, net::OldCompletionCallback* completion_callback) OVERRIDE; diff --git a/net/http/disk_cache_based_ssl_host_info.cc b/net/http/disk_cache_based_ssl_host_info.cc index 003618e..985a261 100644 --- a/net/http/disk_cache_based_ssl_host_info.cc +++ b/net/http/disk_cache_based_ssl_host_info.cc @@ -40,8 +40,8 @@ DiskCacheBasedSSLHostInfo::DiskCacheBasedSSLHostInfo( HttpCache* http_cache) : SSLHostInfo(hostname, ssl_config, cert_verifier), weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), - callback_(new CallbackImpl(weak_ptr_factory_.GetWeakPtr(), - &DiskCacheBasedSSLHostInfo::OnIOComplete)), + callback_(base::Bind(&DiskCacheBasedSSLHostInfo::OnIOComplete, + weak_ptr_factory_.GetWeakPtr())), state_(GET_BACKEND), ready_(false), found_entry_(false), @@ -93,8 +93,6 @@ DiskCacheBasedSSLHostInfo::~DiskCacheBasedSSLHostInfo() { DCHECK(user_callback_.is_null()); if (entry_) entry_->Close(); - if (!IsCallbackPending()) - delete callback_; } std::string DiskCacheBasedSSLHostInfo::key() const { @@ -160,7 +158,6 @@ int DiskCacheBasedSSLHostInfo::DoLoop(int rv) { int DiskCacheBasedSSLHostInfo::DoGetBackendComplete(int rv) { if (rv == OK) { - backend_ = callback_->backend(); state_ = OPEN; } else { state_ = WAIT_FOR_DATA_READY_DONE; @@ -170,7 +167,6 @@ int DiskCacheBasedSSLHostInfo::DoGetBackendComplete(int rv) { int DiskCacheBasedSSLHostInfo::DoOpenComplete(int rv) { if (rv == OK) { - entry_ = callback_->entry(); state_ = READ; found_entry_ = true; } else { @@ -194,23 +190,22 @@ int DiskCacheBasedSSLHostInfo::DoWriteComplete(int rv) { } int DiskCacheBasedSSLHostInfo::DoCreateOrOpenComplete(int rv) { - if (rv != OK) { + if (rv != OK) state_ = SET_DONE; - } else { - entry_ = callback_->entry(); + else state_ = WRITE; - } + return OK; } int DiskCacheBasedSSLHostInfo::DoGetBackend() { state_ = GET_BACKEND_COMPLETE; - return http_cache_->GetBackend(callback_->backend_pointer(), callback_); + return http_cache_->GetBackend(&backend_, callback_); } int DiskCacheBasedSSLHostInfo::DoOpen() { state_ = OPEN_COMPLETE; - return backend_->OpenEntry(key(), callback_->entry_pointer(), callback_); + return backend_->OpenEntry(key(), &entry_, callback_); } int DiskCacheBasedSSLHostInfo::DoRead() { @@ -232,16 +227,17 @@ int DiskCacheBasedSSLHostInfo::DoWrite() { state_ = WRITE_COMPLETE; return entry_->WriteData(0 /* index */, 0 /* offset */, write_buffer_, - new_data_.size(), callback_, true /* truncate */); + new_data_.size(), callback_, + true /* truncate */); } int DiskCacheBasedSSLHostInfo::DoCreateOrOpen() { DCHECK(entry_ == NULL); state_ = CREATE_OR_OPEN_COMPLETE; if (found_entry_) - return backend_->OpenEntry(key(), callback_->entry_pointer(), callback_); + return backend_->OpenEntry(key(), &entry_, callback_); - return backend_->CreateEntry(key(), callback_->entry_pointer(), callback_); + return backend_->CreateEntry(key(), &entry_, callback_); } int DiskCacheBasedSSLHostInfo::DoWaitForDataReadyDone() { diff --git a/net/http/disk_cache_based_ssl_host_info.h b/net/http/disk_cache_based_ssl_host_info.h index 2339ae9..48651ed 100644 --- a/net/http/disk_cache_based_ssl_host_info.h +++ b/net/http/disk_cache_based_ssl_host_info.h @@ -106,7 +106,7 @@ class NET_EXPORT_PRIVATE DiskCacheBasedSSLHostInfo bool IsCallbackPending() const; base::WeakPtrFactory<DiskCacheBasedSSLHostInfo> weak_ptr_factory_; - CallbackImpl* callback_; + CompletionCallback callback_; State state_; bool ready_; bool found_entry_; // Controls the behavior of DoCreateOrOpen. diff --git a/net/http/http_cache.cc b/net/http/http_cache.cc index 58fa5cb..e968526 100644 --- a/net/http/http_cache.cc +++ b/net/http/http_cache.cc @@ -23,6 +23,7 @@ #include "base/string_number_conversions.h" #include "base/string_util.h" #include "base/stringprintf.h" +#include "net/base/completion_callback.h" #include "net/base/io_buffer.h" #include "net/base/load_flags.h" #include "net/base/net_errors.h" @@ -143,11 +144,16 @@ enum WorkItemOperation { class HttpCache::WorkItem { public: WorkItem(WorkItemOperation operation, Transaction* trans, ActiveEntry** entry) - : operation_(operation), trans_(trans), entry_(entry), callback_(NULL), + : operation_(operation), + trans_(trans), + entry_(entry), backend_(NULL) {} WorkItem(WorkItemOperation operation, Transaction* trans, - OldCompletionCallback* cb, disk_cache::Backend** backend) - : operation_(operation), trans_(trans), entry_(NULL), callback_(cb), + const CompletionCallback& cb, disk_cache::Backend** backend) + : operation_(operation), + trans_(trans), + entry_(NULL), + callback_(cb), backend_(backend) {} ~WorkItem() {} @@ -165,25 +171,31 @@ class HttpCache::WorkItem { bool DoCallback(int result, disk_cache::Backend* backend) { if (backend_) *backend_ = backend; - if (callback_) { - callback_->Run(result); + if (!callback_.is_null()) { + callback_.Run(result); return true; } return false; } + void ClearCallback() { + callback_.Reset(); + } + + bool IsValid() const { + return trans_ || entry_ || !callback_.is_null(); + } + WorkItemOperation operation() { return operation_; } void ClearTransaction() { trans_ = NULL; } void ClearEntry() { entry_ = NULL; } - void ClearCallback() { callback_ = NULL; } bool Matches(Transaction* trans) const { return trans == trans_; } - bool IsValid() const { return trans_ || entry_ || callback_; } private: WorkItemOperation operation_; Transaction* trans_; ActiveEntry** entry_; - OldCompletionCallback* callback_; // User callback. + CompletionCallback callback_; disk_cache::Backend** backend_; }; @@ -422,8 +434,8 @@ HttpCache::~HttpCache() { } int HttpCache::GetBackend(disk_cache::Backend** backend, - OldCompletionCallback* callback) { - DCHECK(callback != NULL); + const CompletionCallback& callback) { + DCHECK(!callback.is_null()); if (disk_cache_.get()) { *backend = disk_cache_.get(); @@ -452,8 +464,10 @@ void HttpCache::WriteMetadata(const GURL& url, return; // Do lazy initialization of disk cache if needed. - if (!disk_cache_.get()) - CreateBackend(NULL, NULL); // We don't care about the result. + if (!disk_cache_.get()) { + // We don't care about the result. + CreateBackend(NULL, CompletionCallback()); + } HttpCache::Transaction* trans = new HttpCache::Transaction(this); MetadataWriter* writer = new MetadataWriter(trans); @@ -492,8 +506,10 @@ void HttpCache::OnExternalCacheHit(const GURL& url, int HttpCache::CreateTransaction(scoped_ptr<HttpTransaction>* trans) { // Do lazy initialization of disk cache if needed. - if (!disk_cache_.get()) - CreateBackend(NULL, NULL); // We don't care about the result. + if (!disk_cache_.get()) { + // We don't care about the result. + CreateBackend(NULL, CompletionCallback()); + } trans->reset(new HttpCache::Transaction(this)); return OK; @@ -512,7 +528,7 @@ HttpNetworkSession* HttpCache::GetSession() { //----------------------------------------------------------------------------- int HttpCache::CreateBackend(disk_cache::Backend** backend, - OldCompletionCallback* callback) { + const CompletionCallback& callback) { if (!backend_factory_.get()) return ERR_FAILED; @@ -525,7 +541,7 @@ int HttpCache::CreateBackend(disk_cache::Backend** backend, // entry, so we use an empty key for it. PendingOp* pending_op = GetPendingOp(""); if (pending_op->writer) { - if (callback) + if (!callback.is_null()) pending_op->pending_queue.push_back(item.release()); return ERR_IO_PENDING; } @@ -553,7 +569,8 @@ int HttpCache::GetBackendForTransaction(Transaction* trans) { if (!building_backend_) return ERR_FAILED; - WorkItem* item = new WorkItem(WI_CREATE_BACKEND, trans, NULL, NULL); + WorkItem* item = new WorkItem(WI_CREATE_BACKEND, trans, + CompletionCallback(), NULL); PendingOp* pending_op = GetPendingOp(""); DCHECK(pending_op->writer); pending_op->pending_queue.push_back(item); diff --git a/net/http/http_cache.h b/net/http/http_cache.h index 526da58..176d9ff 100644 --- a/net/http/http_cache.h +++ b/net/http/http_cache.h @@ -157,7 +157,8 @@ class NET_EXPORT HttpCache : public HttpTransactionFactory, // a network error code, and it could be ERR_IO_PENDING, in which case the // |callback| will be notified when the operation completes. The pointer that // receives the |backend| must remain valid until the operation completes. - int GetBackend(disk_cache::Backend** backend, OldCompletionCallback* callback); + int GetBackend(disk_cache::Backend** backend, + const CompletionCallback& callback); // Returns the current backend (can be NULL). disk_cache::Backend* GetCurrentBackend() const; @@ -190,7 +191,7 @@ class NET_EXPORT HttpCache : public HttpTransactionFactory, // referred to by |url| and |http_method|. void OnExternalCacheHit(const GURL& url, const std::string& http_method); - // HttpTransactionFactory implementation: + // HttpTransactionFactory implementation. virtual int CreateTransaction(scoped_ptr<HttpTransaction>* trans) OVERRIDE; virtual HttpCache* GetCache() OVERRIDE; virtual HttpNetworkSession* GetSession() OVERRIDE; @@ -243,7 +244,7 @@ class NET_EXPORT HttpCache : public HttpTransactionFactory, // Creates the |backend| object and notifies the |callback| when the operation // completes. Returns an error code. int CreateBackend(disk_cache::Backend** backend, - OldCompletionCallback* callback); + const CompletionCallback& callback); // Makes sure that the backend creation is complete before allowing the // provided transaction to use the object. Returns an error code. |trans| diff --git a/net/http/http_cache_unittest.cc b/net/http/http_cache_unittest.cc index 0c0ff6f..93f7476 100644 --- a/net/http/http_cache_unittest.cc +++ b/net/http/http_cache_unittest.cc @@ -11,6 +11,7 @@ #include "base/stringprintf.h" #include "net/base/cache_type.h" #include "net/base/cert_status_flags.h" +#include "net/base/completion_callback.h" #include "net/base/host_port_pair.h" #include "net/base/load_flags.h" #include "net/base/net_errors.h" @@ -32,18 +33,27 @@ using base::Time; namespace { -class DeleteCacheOldCompletionCallback : public TestOldCompletionCallback { +class DeleteCacheCompletionCallback : public TestCompletionCallbackBase { public: - explicit DeleteCacheOldCompletionCallback(MockHttpCache* cache) - : cache_(cache) {} + explicit DeleteCacheCompletionCallback(MockHttpCache* cache) + : cache_(cache), + ALLOW_THIS_IN_INITIALIZER_LIST(callback_( + base::Bind(&DeleteCacheCompletionCallback::OnComplete, + base::Unretained(this)))) { + } + + const net::CompletionCallback& callback() const { return callback_; } - virtual void RunWithParams(const Tuple1<int>& params) { + private: + void OnComplete(int result) { delete cache_; - TestOldCompletionCallback::RunWithParams(params); + SetResult(result); } - private: MockHttpCache* cache_; + const net::CompletionCallback callback_; + + DISALLOW_COPY_AND_ASSIGN(DeleteCacheCompletionCallback); }; //----------------------------------------------------------------------------- @@ -395,9 +405,9 @@ TEST(HttpCache, GetBackend) { MockHttpCache cache(net::HttpCache::DefaultBackend::InMemory(0)); disk_cache::Backend* backend; - TestOldCompletionCallback cb; + net::TestCompletionCallback cb; // This will lazily initialize the backend. - int rv = cache.http_cache()->GetBackend(&backend, &cb); + int rv = cache.http_cache()->GetBackend(&backend, cb.callback()); EXPECT_EQ(net::OK, cb.GetResult(rv)); } @@ -1465,9 +1475,9 @@ TEST(HttpCache, DeleteCacheWaitingForBackend2) { MockBlockingBackendFactory* factory = new MockBlockingBackendFactory(); MockHttpCache* cache = new MockHttpCache(factory); - DeleteCacheOldCompletionCallback cb(cache); + DeleteCacheCompletionCallback cb(cache); disk_cache::Backend* backend; - int rv = cache->http_cache()->GetBackend(&backend, &cb); + int rv = cache->http_cache()->GetBackend(&backend, cb.callback()); EXPECT_EQ(net::ERR_IO_PENDING, rv); // Now let's queue a regular transaction @@ -1480,8 +1490,8 @@ TEST(HttpCache, DeleteCacheWaitingForBackend2) { c->trans->Start(&request, &c->callback, net::BoundNetLog()); // And another direct backend request. - TestOldCompletionCallback cb2; - rv = cache->http_cache()->GetBackend(&backend, &cb2); + net::TestCompletionCallback cb2; + rv = cache->http_cache()->GetBackend(&backend, cb2.callback()); EXPECT_EQ(net::ERR_IO_PENDING, rv); // Just to make sure that everything is still pending. diff --git a/net/http/mock_http_cache.cc b/net/http/mock_http_cache.cc index 98efd70..597c729 100644 --- a/net/http/mock_http_cache.cc +++ b/net/http/mock_http_cache.cc @@ -11,6 +11,26 @@ namespace { +class OldCallbackRunner : public Task { + public: + OldCallbackRunner(net::OldCompletionCallback* callback, int result) + : callback_(callback), result_(result) {} + virtual void Run() { + callback_->Run(result_); + } + + private: + net::OldCompletionCallback* callback_; + int result_; + + DISALLOW_COPY_AND_ASSIGN(OldCallbackRunner); +}; + +void CompletionCallbackRunner( + const net::CompletionCallback& callback, int result) { + callback.Run(result); +} + int GetTestModeForEntry(const std::string& key) { // 'key' is prefixed with an identifier if it corresponds to a cached POST. // Skip past that to locate the actual URL. @@ -41,7 +61,8 @@ int g_test_mode = 0; struct MockDiskEntry::CallbackInfo { scoped_refptr<MockDiskEntry> entry; - net::OldCompletionCallback* callback; + net::OldCompletionCallback* old_callback; + net::CompletionCallback callback; int result; }; @@ -106,6 +127,30 @@ int MockDiskEntry::ReadData(int index, int offset, net::IOBuffer* buf, return net::ERR_IO_PENDING; } +int MockDiskEntry::ReadData( + int index, int offset, net::IOBuffer* buf, int buf_len, + const net::CompletionCallback& callback) { + DCHECK(index >= 0 && index < kNumCacheEntryDataIndices); + DCHECK(!callback.is_null()); + + if (fail_requests_) + return net::ERR_CACHE_READ_FAILURE; + + if (offset < 0 || offset > static_cast<int>(data_[index].size())) + return net::ERR_FAILED; + if (static_cast<size_t>(offset) == data_[index].size()) + return 0; + + int num = std::min(buf_len, static_cast<int>(data_[index].size()) - offset); + memcpy(buf->data(), &data_[index][offset], num); + + if (MockHttpCache::GetTestMode(test_mode_) & TEST_MODE_SYNC_CACHE_READ) + return num; + + CallbackLater(callback, num); + return net::ERR_IO_PENDING; +} + int MockDiskEntry::WriteData(int index, int offset, net::IOBuffer* buf, int buf_len, net::OldCompletionCallback* callback, bool truncate) { @@ -132,6 +177,32 @@ int MockDiskEntry::WriteData(int index, int offset, net::IOBuffer* buf, return net::ERR_IO_PENDING; } +int MockDiskEntry::WriteData( + int index, int offset, net::IOBuffer* buf, int buf_len, + const net::CompletionCallback& callback, bool truncate) { + DCHECK(index >= 0 && index < kNumCacheEntryDataIndices); + DCHECK(truncate); + DCHECK(!callback.is_null()); + + if (fail_requests_) { + CallbackLater(callback, net::ERR_CACHE_READ_FAILURE); + return net::ERR_IO_PENDING; + } + + if (offset < 0 || offset > static_cast<int>(data_[index].size())) + return net::ERR_FAILED; + + data_[index].resize(offset + buf_len); + if (buf_len) + memcpy(&data_[index][offset], buf->data(), buf_len); + + if (MockHttpCache::GetTestMode(test_mode_) & TEST_MODE_SYNC_CACHE_WRITE) + return buf_len; + + CallbackLater(callback, buf_len); + return net::ERR_IO_PENDING; +} + int MockDiskEntry::ReadSparseData(int64 offset, net::IOBuffer* buf, int buf_len, net::OldCompletionCallback* callback) { DCHECK(callback); @@ -264,7 +335,7 @@ void MockDiskEntry::IgnoreCallbacks(bool value) { return; ignore_callbacks_ = value; if (!value) - StoreAndDeliverCallbacks(false, NULL, NULL, 0); + StoreAndDeliverCallbacks(false, NULL, NULL, net::CompletionCallback(), 0); } MockDiskEntry::~MockDiskEntry() { @@ -275,13 +346,29 @@ MockDiskEntry::~MockDiskEntry() { // leveraging the fact that this class is reference counted. void MockDiskEntry::CallbackLater(net::OldCompletionCallback* callback, int result) { - if (ignore_callbacks_) - return StoreAndDeliverCallbacks(true, this, callback, result); + if (ignore_callbacks_) { + StoreAndDeliverCallbacks(true, this, callback, + net::CompletionCallback(), result); + return; + } + + MessageLoop::current()->PostTask(FROM_HERE, base::Bind( + &MockDiskEntry::RunOldCallback, this, callback, result)); +} + +void MockDiskEntry::CallbackLater(const net::CompletionCallback& callback, + int result) { + if (ignore_callbacks_) { + StoreAndDeliverCallbacks(true, this, NULL, callback, result); + return; + } + MessageLoop::current()->PostTask(FROM_HERE, base::Bind( &MockDiskEntry::RunCallback, this, callback, result)); } -void MockDiskEntry::RunCallback(net::OldCompletionCallback* callback, int result) { +void MockDiskEntry::RunOldCallback( + net::OldCompletionCallback* callback, int result) { if (busy_) { // This is kind of hacky, but controlling the behavior of just this entry // from a test is sort of complicated. What we really want to do is @@ -290,7 +377,7 @@ void MockDiskEntry::RunCallback(net::OldCompletionCallback* callback, int result // this operation (already posted to the message loop)... and without // just delaying for n mS (which may cause trouble with slow bots). So // we re-post this operation (all async sparse IO operations will take two - // trips trhough the message loop instead of one). + // trips through the message loop instead of one). if (!delayed_) { delayed_ = true; return CallbackLater(callback, result); @@ -300,20 +387,44 @@ void MockDiskEntry::RunCallback(net::OldCompletionCallback* callback, int result callback->Run(result); } +void MockDiskEntry::RunCallback( + const net::CompletionCallback& callback, int result) { + if (busy_) { + // This is kind of hacky, but controlling the behavior of just this entry + // from a test is sort of complicated. What we really want to do is + // delay the delivery of a sparse IO operation a little more so that the + // request start operation (async) will finish without seeing the end of + // this operation (already posted to the message loop)... and without + // just delaying for n mS (which may cause trouble with slow bots). So + // we re-post this operation (all async sparse IO operations will take two + // trips through the message loop instead of one). + if (!delayed_) { + delayed_ = true; + return CallbackLater(callback, result); + } + } + busy_ = false; + callback.Run(result); +} + // When |store| is true, stores the callback to be delivered later; otherwise // delivers any callback previously stored. // Static. -void MockDiskEntry::StoreAndDeliverCallbacks(bool store, MockDiskEntry* entry, - net::OldCompletionCallback* callback, - int result) { +void MockDiskEntry::StoreAndDeliverCallbacks( + bool store, MockDiskEntry* entry, + net::OldCompletionCallback* old_callback, + const net::CompletionCallback& callback, int result) { static std::vector<CallbackInfo> callback_list; if (store) { - CallbackInfo c = {entry, callback, result}; + CallbackInfo c = {entry, old_callback, callback, result}; callback_list.push_back(c); } else { - for (size_t i = 0; i < callback_list.size(); i++) { + for (size_t i = 0; i < callback_list.size(); ++i) { CallbackInfo& c = callback_list[i]; - c.entry->CallbackLater(c.callback, c.result); + if (c.old_callback) + c.entry->CallbackLater(c.old_callback, c.result); + else + c.entry->CallbackLater(c.callback, c.result); } callback_list.clear(); } @@ -325,20 +436,6 @@ bool MockDiskEntry::ignore_callbacks_ = false; //----------------------------------------------------------------------------- -class MockDiskCache::CallbackRunner : public Task { - public: - CallbackRunner(net::OldCompletionCallback* callback, int result) - : callback_(callback), result_(result) {} - virtual void Run() { - callback_->Run(result_); - } - - private: - net::OldCompletionCallback* callback_; - int result_; - DISALLOW_COPY_AND_ASSIGN(CallbackRunner); -}; - MockDiskCache::MockDiskCache() : open_count_(0), create_count_(0), fail_requests_(false), soft_failures_(false), double_create_check_(true) { @@ -383,6 +480,38 @@ int MockDiskCache::OpenEntry(const std::string& key, disk_cache::Entry** entry, return net::ERR_IO_PENDING; } +int MockDiskCache::OpenEntry(const std::string& key, disk_cache::Entry** entry, + const net::CompletionCallback& callback) { + DCHECK(!callback.is_null()); + + if (fail_requests_) + return net::ERR_CACHE_OPEN_FAILURE; + + EntryMap::iterator it = entries_.find(key); + if (it == entries_.end()) + return net::ERR_CACHE_OPEN_FAILURE; + + if (it->second->is_doomed()) { + it->second->Release(); + entries_.erase(it); + return net::ERR_CACHE_OPEN_FAILURE; + } + + open_count_++; + + it->second->AddRef(); + *entry = it->second; + + if (soft_failures_) + it->second->set_fail_requests(); + + if (GetTestModeForEntry(key) & TEST_MODE_SYNC_CACHE_START) + return net::OK; + + CallbackLater(callback, net::OK); + return net::ERR_IO_PENDING; +} + int MockDiskCache::CreateEntry(const std::string& key, disk_cache::Entry** entry, net::OldCompletionCallback* callback) { @@ -422,6 +551,46 @@ int MockDiskCache::CreateEntry(const std::string& key, return net::ERR_IO_PENDING; } +int MockDiskCache::CreateEntry(const std::string& key, + disk_cache::Entry** entry, + const net::CompletionCallback& callback) { + DCHECK(!callback.is_null()); + + if (fail_requests_) + return net::ERR_CACHE_CREATE_FAILURE; + + EntryMap::iterator it = entries_.find(key); + if (it != entries_.end()) { + if (!it->second->is_doomed()) { + if (double_create_check_) + NOTREACHED(); + else + return net::ERR_CACHE_CREATE_FAILURE; + } + it->second->Release(); + entries_.erase(it); + } + + create_count_++; + + MockDiskEntry* new_entry = new MockDiskEntry(key); + + new_entry->AddRef(); + entries_[key] = new_entry; + + new_entry->AddRef(); + *entry = new_entry; + + if (soft_failures_) + new_entry->set_fail_requests(); + + if (GetTestModeForEntry(key) & TEST_MODE_SYNC_CACHE_START) + return net::OK; + + CallbackLater(callback, net::OK); + return net::ERR_IO_PENDING; +} + int MockDiskCache::DoomEntry(const std::string& key, net::OldCompletionCallback* callback) { DCHECK(callback); @@ -478,7 +647,13 @@ void MockDiskCache::ReleaseAll() { void MockDiskCache::CallbackLater(net::OldCompletionCallback* callback, int result) { MessageLoop::current()->PostTask(FROM_HERE, - new CallbackRunner(callback, result)); + new OldCallbackRunner(callback, result)); +} + +void MockDiskCache::CallbackLater(const net::CompletionCallback& callback, + int result) { + MessageLoop::current()->PostTask( + FROM_HERE, base::Bind(&CompletionCallbackRunner, callback, result)); } //----------------------------------------------------------------------------- @@ -501,9 +676,9 @@ MockHttpCache::MockHttpCache(net::HttpCache::BackendFactory* disk_cache_factory) } MockDiskCache* MockHttpCache::disk_cache() { - TestOldCompletionCallback cb; + net::TestCompletionCallback cb; disk_cache::Backend* backend; - int rv = http_cache_.GetBackend(&backend, &cb); + int rv = http_cache_.GetBackend(&backend, cb.callback()); rv = cb.GetResult(rv); return (rv == net::OK) ? static_cast<MockDiskCache*>(backend) : NULL; } diff --git a/net/http/mock_http_cache.h b/net/http/mock_http_cache.h index 975058f..00b5cae 100644 --- a/net/http/mock_http_cache.h +++ b/net/http/mock_http_cache.h @@ -35,9 +35,14 @@ class MockDiskEntry : public disk_cache::Entry, virtual int32 GetDataSize(int index) const OVERRIDE; virtual int ReadData(int index, int offset, net::IOBuffer* buf, int buf_len, net::OldCompletionCallback* callback) OVERRIDE; + virtual int ReadData(int index, int offset, net::IOBuffer* buf, int buf_len, + const net::CompletionCallback& callback) OVERRIDE; virtual int WriteData(int index, int offset, net::IOBuffer* buf, int buf_len, net::OldCompletionCallback* callback, bool truncate) OVERRIDE; + virtual int WriteData(int index, int offset, net::IOBuffer* buf, int buf_len, + const net::CompletionCallback& callback, + bool truncate) OVERRIDE; virtual int ReadSparseData(int64 offset, net::IOBuffer* buf, int buf_len, net::OldCompletionCallback* callback) OVERRIDE; virtual int WriteSparseData(int64 offset, net::IOBuffer* buf, int buf_len, @@ -67,13 +72,16 @@ class MockDiskEntry : public disk_cache::Entry, // if the consumer called Close on the MockDiskEntry. We achieve that by // leveraging the fact that this class is reference counted. void CallbackLater(net::OldCompletionCallback* callback, int result); + void CallbackLater(const net::CompletionCallback& callback, int result); - void RunCallback(net::OldCompletionCallback* callback, int result); + void RunOldCallback(net::OldCompletionCallback* callback, int result); + void RunCallback(const net::CompletionCallback& callback, int result); // When |store| is true, stores the callback to be delivered later; otherwise // delivers any callback previously stored. static void StoreAndDeliverCallbacks(bool store, MockDiskEntry* entry, - net::OldCompletionCallback* callback, + net::OldCompletionCallback* old_callback, + const net::CompletionCallback& callback, int result); static const int kNumCacheEntryDataIndices = 3; @@ -98,8 +106,12 @@ class MockDiskCache : public disk_cache::Backend { virtual int32 GetEntryCount() const OVERRIDE; virtual int OpenEntry(const std::string& key, disk_cache::Entry** entry, net::OldCompletionCallback* callback) OVERRIDE; + virtual int OpenEntry(const std::string& key, disk_cache::Entry** entry, + const net::CompletionCallback& callback) OVERRIDE; virtual int CreateEntry(const std::string& key, disk_cache::Entry** entry, net::OldCompletionCallback* callback) OVERRIDE; + virtual int CreateEntry(const std::string& key, disk_cache::Entry** entry, + const net::CompletionCallback& callback) OVERRIDE; virtual int DoomEntry(const std::string& key, net::OldCompletionCallback* callback) OVERRIDE; virtual int DoomAllEntries(net::OldCompletionCallback* callback) OVERRIDE; @@ -134,9 +146,9 @@ class MockDiskCache : public disk_cache::Backend { private: typedef base::hash_map<std::string, MockDiskEntry*> EntryMap; - class CallbackRunner; void CallbackLater(net::OldCompletionCallback* callback, int result); + void CallbackLater(const net::CompletionCallback& callback, int result); EntryMap entries_; int open_count_; diff --git a/net/url_request/view_cache_helper.cc b/net/url_request/view_cache_helper.cc index e0f6456..6810245 100644 --- a/net/url_request/view_cache_helper.cc +++ b/net/url_request/view_cache_helper.cc @@ -4,6 +4,8 @@ #include "net/url_request/view_cache_helper.h" +#include "base/bind.h" +#include "base/bind_helpers.h" #include "base/stringprintf.h" #include "net/base/escape.h" #include "net/base/io_buffer.h" @@ -46,8 +48,10 @@ ViewCacheHelper::ViewCacheHelper() index_(0), data_(NULL), next_state_(STATE_NONE), + ALLOW_THIS_IN_INITIALIZER_LIST(cache_callback_( + base::Bind(&ViewCacheHelper::OnIOComplete, base::Unretained(this)))), ALLOW_THIS_IN_INITIALIZER_LIST( - cache_callback_(this, &ViewCacheHelper::OnIOComplete)), + old_cache_callback_(this, &ViewCacheHelper::OnIOComplete)), ALLOW_THIS_IN_INITIALIZER_LIST( entry_callback_(new CancelableOldCompletionCallback<ViewCacheHelper>( this, &ViewCacheHelper::OnIOComplete))) { @@ -219,7 +223,7 @@ int ViewCacheHelper::DoGetBackend() { if (!http_cache) return ERR_FAILED; - return http_cache->GetBackend(&disk_cache_, &cache_callback_); + return http_cache->GetBackend(&disk_cache_, cache_callback_); } int ViewCacheHelper::DoGetBackendComplete(int result) { @@ -242,7 +246,7 @@ int ViewCacheHelper::DoGetBackendComplete(int result) { int ViewCacheHelper::DoOpenNextEntry() { next_state_ = STATE_OPEN_NEXT_ENTRY_COMPLETE; - return disk_cache_->OpenNextEntry(&iter_, &entry_, &cache_callback_); + return disk_cache_->OpenNextEntry(&iter_, &entry_, &old_cache_callback_); } int ViewCacheHelper::DoOpenNextEntryComplete(int result) { @@ -262,7 +266,7 @@ int ViewCacheHelper::DoOpenNextEntryComplete(int result) { int ViewCacheHelper::DoOpenEntry() { next_state_ = STATE_OPEN_ENTRY_COMPLETE; - return disk_cache_->OpenEntry(key_, &entry_, &cache_callback_); + return disk_cache_->OpenEntry(key_, &entry_, &old_cache_callback_); } int ViewCacheHelper::DoOpenEntryComplete(int result) { diff --git a/net/url_request/view_cache_helper.h b/net/url_request/view_cache_helper.h index f6f7cc4..c31d0fc 100644 --- a/net/url_request/view_cache_helper.h +++ b/net/url_request/view_cache_helper.h @@ -114,7 +114,8 @@ class NET_EXPORT ViewCacheHelper { State next_state_; - OldCompletionCallbackImpl<ViewCacheHelper> cache_callback_; + CompletionCallback cache_callback_; + OldCompletionCallbackImpl<ViewCacheHelper> old_cache_callback_; scoped_refptr<CancelableOldCompletionCallback<ViewCacheHelper> > entry_callback_; DISALLOW_COPY_AND_ASSIGN(ViewCacheHelper); diff --git a/net/url_request/view_cache_helper_unittest.cc b/net/url_request/view_cache_helper_unittest.cc index 17bad61..e911fcc 100644 --- a/net/url_request/view_cache_helper_unittest.cc +++ b/net/url_request/view_cache_helper_unittest.cc @@ -5,6 +5,7 @@ #include "net/url_request/view_cache_helper.h" #include "base/pickle.h" +#include "net/base/completion_callback.h" #include "net/base/net_errors.h" #include "net/base/test_completion_callback.h" #include "net/disk_cache/disk_cache.h" @@ -85,10 +86,10 @@ void WriteToEntry(disk_cache::Backend* cache, const std::string key, } void FillCache(URLRequestContext* context) { - TestOldCompletionCallback cb; + TestCompletionCallback cb; disk_cache::Backend* cache; - int rv = - context->http_transaction_factory()->GetCache()->GetBackend(&cache, &cb); + int rv = context->http_transaction_factory()->GetCache()->GetBackend( + &cache, cb.callback()); ASSERT_EQ(OK, cb.GetResult(rv)); std::string empty; @@ -180,15 +181,16 @@ TEST(ViewCacheHelper, TruncatedFlag) { scoped_refptr<TestURLRequestContext> context(new TestURLRequestContext()); ViewCacheHelper helper; - TestOldCompletionCallback cb; + TestCompletionCallback cb; disk_cache::Backend* cache; - int rv = - context->http_transaction_factory()->GetCache()->GetBackend(&cache, &cb); + int rv = context->http_transaction_factory()->GetCache()->GetBackend( + &cache, cb.callback()); ASSERT_EQ(OK, cb.GetResult(rv)); std::string key("the key"); disk_cache::Entry* entry; - rv = cache->CreateEntry(key, &entry, &cb); + TestOldCompletionCallback cb2; + rv = cache->CreateEntry(key, &entry, &cb2); ASSERT_EQ(OK, cb.GetResult(rv)); // RESPONSE_INFO_TRUNCATED defined on response_info.cc |