diff options
author | rvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-07-01 01:12:00 +0000 |
---|---|---|
committer | rvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-07-01 01:12:00 +0000 |
commit | 05bebf1bc8d96ca3262cd3015af5c8178d3e7f84 (patch) | |
tree | 147efbc0cd0087e277aed96ed01ba6b85a254faf /net | |
parent | 6ebf2fc952b8170971e37971e9d1362c64424e89 (diff) | |
download | chromium_src-05bebf1bc8d96ca3262cd3015af5c8178d3e7f84.zip chromium_src-05bebf1bc8d96ca3262cd3015af5c8178d3e7f84.tar.gz chromium_src-05bebf1bc8d96ca3262cd3015af5c8178d3e7f84.tar.bz2 |
Revert 51312 - Disk cache: Switch the disk cache to use the cache_thread.
(tsan errors on the unit tests)
Add an InFlightBackendIO class that handles posting of
cacheoperations back and forth between the IO thread and
the cachethread.
BUG=26730
TEST=unit tests
Review URL: http://codereview.chromium.org/2829008
TBR=nsylvain@chromium.org
Review URL: http://codereview.chromium.org/2819032
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@51325 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rw-r--r-- | net/disk_cache/backend_impl.cc | 315 | ||||
-rw-r--r-- | net/disk_cache/backend_impl.h | 49 | ||||
-rw-r--r-- | net/disk_cache/backend_unittest.cc | 80 | ||||
-rw-r--r-- | net/disk_cache/disk_cache_test_base.cc | 33 | ||||
-rw-r--r-- | net/disk_cache/disk_cache_test_base.h | 8 | ||||
-rw-r--r-- | net/disk_cache/entry_impl.cc | 157 | ||||
-rw-r--r-- | net/disk_cache/entry_impl.h | 17 | ||||
-rw-r--r-- | net/disk_cache/entry_unittest.cc | 58 | ||||
-rw-r--r-- | net/disk_cache/eviction.cc | 6 | ||||
-rw-r--r-- | net/disk_cache/file_posix.cc | 13 | ||||
-rw-r--r-- | net/disk_cache/in_flight_backend_io.cc | 448 | ||||
-rw-r--r-- | net/disk_cache/in_flight_backend_io.h | 200 | ||||
-rw-r--r-- | net/disk_cache/in_flight_io.cc | 64 | ||||
-rw-r--r-- | net/disk_cache/in_flight_io.h | 128 | ||||
-rw-r--r-- | net/disk_cache/sparse_control.cc | 10 | ||||
-rw-r--r-- | net/disk_cache/stress_cache.cc | 1 | ||||
-rw-r--r-- | net/net.gyp | 4 | ||||
-rw-r--r-- | net/tools/crash_cache/crash_cache.cc | 30 | ||||
-rw-r--r-- | net/tools/dump_cache/upgrade.cc | 45 |
19 files changed, 213 insertions, 1453 deletions
diff --git a/net/disk_cache/backend_impl.cc b/net/disk_cache/backend_impl.cc index 889cbff..5e761e1 100644 --- a/net/disk_cache/backend_impl.cc +++ b/net/disk_cache/backend_impl.cc @@ -162,105 +162,6 @@ void SetFieldTrialInfo(int size_group) { trial1->AppendGroup(group1, FieldTrial::kAllRemainingProbability); } -// ------------------------------------------------------------------------ - -// This class takes care of building an instance of the backend. -class CacheCreator { - public: - CacheCreator(const FilePath& path, bool force, int max_bytes, - net::CacheType type, uint32 flags, - base::MessageLoopProxy* thread, disk_cache::Backend** backend, - net::CompletionCallback* callback) - : path_(path), force_(force), retry_(false), max_bytes_(max_bytes), - type_(type), flags_(flags), thread_(thread), backend_(backend), - callback_(callback), cache_(NULL), - ALLOW_THIS_IN_INITIALIZER_LIST( - my_callback_(this, &CacheCreator::OnIOComplete)) { - } - ~CacheCreator() {} - - // Creates the backend. - int Run(); - - // Callback implementation. - void OnIOComplete(int result); - - private: - void DoCallback(int result); - - const FilePath& path_; - bool force_; - bool retry_; - int max_bytes_; - net::CacheType type_; - uint32 flags_; - scoped_refptr<base::MessageLoopProxy> thread_; - disk_cache::Backend** backend_; - net::CompletionCallback* callback_; - disk_cache::BackendImpl* cache_; - net::CompletionCallbackImpl<CacheCreator> my_callback_; - - DISALLOW_COPY_AND_ASSIGN(CacheCreator); -}; - -int CacheCreator::Run() { - cache_ = new disk_cache::BackendImpl(path_, thread_); - cache_->SetMaxSize(max_bytes_); - cache_->SetType(type_); - cache_->SetFlags(flags_); - int rv = cache_->Init(&my_callback_); - DCHECK_EQ(net::ERR_IO_PENDING, rv); - return rv; -} - -void CacheCreator::OnIOComplete(int result) { - if (result == net::OK || !force_ || retry_) - return DoCallback(result); - - // This is a failure and we are supposed to try again, so delete the object, - // delete all the files, and try again. - retry_ = true; - delete cache_; - if (!DelayedCacheCleanup(path_)) - return DoCallback(result); - - // The worker thread will start deleting files soon, but the original folder - // is not there anymore... let's create a new set of files. - int rv = Run(); - DCHECK_EQ(net::ERR_IO_PENDING, rv); -} - -void CacheCreator::DoCallback(int result) { - DCHECK_NE(net::ERR_IO_PENDING, result); - if (result == net::OK) { - *backend_ = cache_; - } else { - LOG(ERROR) << "Unable to create cache"; - *backend_ = NULL; - delete cache_; - } - callback_->Run(result); - delete this; -} - -// ------------------------------------------------------------------------ - -// A task to perform final cleanup on the background thread. -class FinalCleanup : public Task { - public: - explicit FinalCleanup(disk_cache::BackendImpl* backend) : backend_(backend) {} - ~FinalCleanup() {} - - virtual void Run(); - private: - disk_cache::BackendImpl* backend_; - DISALLOW_EVIL_CONSTRUCTORS(FinalCleanup); -}; - -void FinalCleanup::Run() { - backend_->CleanupCache(); -} - } // namespace // ------------------------------------------------------------------------ @@ -327,16 +228,36 @@ int BackendImpl::CreateBackend(const FilePath& full_path, bool force, uint32 flags, base::MessageLoopProxy* thread, Backend** backend, CompletionCallback* callback) { - CacheCreator* creator = new CacheCreator(full_path, force, max_bytes, type, - flags, thread, backend, callback); - // This object will self-destroy when finished. - return creator->Run(); -} + BackendImpl* cache = new BackendImpl(full_path, thread); + cache->SetMaxSize(max_bytes); + cache->SetType(type); + cache->SetFlags(flags); + if (cache->Init()) { + *backend = cache; + return net::OK; + } + + *backend = NULL; + delete cache; + if (!force) + return net::ERR_FAILED; -int BackendImpl::SyncInit() { - if (Init()) + if (!DelayedCacheCleanup(full_path)) + return net::ERR_FAILED; + + // The worker thread will start deleting files soon, but the original folder + // is not there anymore... let's create a new set of files. + cache = new BackendImpl(full_path, thread); + cache->SetMaxSize(max_bytes); + cache->SetType(type); + cache->SetFlags(flags); + if (cache->Init()) { + *backend = cache; return net::OK; + } + delete cache; + LOG(ERROR) << "Unable to create cache"; return net::ERR_FAILED; } @@ -383,7 +304,7 @@ bool BackendImpl::Init() { // We don't care if the value overflows. The only thing we care about is that // the id cannot be zero, because that value is used as "not dirty". - // Increasing the value once per second gives us many years before we start + // Increasing the value once per second gives us many years before a we start // having collisions. data_->header.this_id++; if (!data_->header.this_id) @@ -414,11 +335,6 @@ bool BackendImpl::Init() { return !disabled_; } -int BackendImpl::Init(CompletionCallback* callback) { - background_queue_.Init(callback); - return net::ERR_IO_PENDING; -} - BackendImpl::~BackendImpl() { Trace("Backend destructor"); if (!init_) @@ -427,24 +343,10 @@ BackendImpl::~BackendImpl() { if (data_) data_->header.crash = 0; - background_queue_.WaitForPendingIO(); - - if (background_queue_.BackgroundIsCurrentThread()) { - // Unit tests may use the same thread for everything. - CleanupCache(); - } else { - background_queue_.background_thread()->PostTask(FROM_HERE, - new FinalCleanup(this)); - done_.Wait(); - } -} - -void BackendImpl::CleanupCache() { timer_.Stop(); + File::WaitForPendingIO(&num_pending_io_); DCHECK(!num_refs_); - factory_.RevokeAll(); - done_.Signal(); } // ------------------------------------------------------------------------ @@ -491,17 +393,18 @@ EntryImpl* BackendImpl::OpenEntryImpl(const std::string& key) { return cache_entry; } -int BackendImpl::SyncOpenEntry(const std::string& key, Entry** entry) { +bool BackendImpl::OpenEntry(const std::string& key, Entry** entry) { DCHECK(entry); *entry = OpenEntryImpl(key); - return (*entry) ? net::OK : net::ERR_FAILED; + return (*entry) ? true : false; } int BackendImpl::OpenEntry(const std::string& key, Entry** entry, CompletionCallback* callback) { - DCHECK(callback); - background_queue_.OpenEntry(key, entry, callback); - return net::ERR_IO_PENDING; + if (OpenEntry(key, entry)) + return net::OK; + + return net::ERR_FAILED; } EntryImpl* BackendImpl::CreateEntryImpl(const std::string& key) { @@ -581,21 +484,15 @@ EntryImpl* BackendImpl::CreateEntryImpl(const std::string& key) { return cache_entry.release(); } -int BackendImpl::SyncCreateEntry(const std::string& key, Entry** entry) { +bool BackendImpl::CreateEntry(const std::string& key, Entry** entry) { DCHECK(entry); *entry = CreateEntryImpl(key); - return (*entry) ? net::OK : net::ERR_FAILED; + return (*entry) ? true : false; } int BackendImpl::CreateEntry(const std::string& key, Entry** entry, CompletionCallback* callback) { - DCHECK(callback); - background_queue_.CreateEntry(key, entry, callback); - return net::ERR_IO_PENDING; -} - -int BackendImpl::SyncDoomEntry(const std::string& key) { - if (DoomEntry(key)) + if (CreateEntry(key, entry)) return net::OK; return net::ERR_FAILED; @@ -605,24 +502,21 @@ bool BackendImpl::DoomEntry(const std::string& key) { if (disabled_) return false; - EntryImpl* entry = OpenEntryImpl(key); - if (!entry) + Entry* entry; + if (!OpenEntry(key, &entry)) return false; - entry->DoomImpl(); - entry->Release(); + // Note that you'd think you could just pass &entry_impl to OpenEntry, + // but that triggers strict aliasing problems with gcc. + EntryImpl* entry_impl = reinterpret_cast<EntryImpl*>(entry); + entry_impl->Doom(); + entry_impl->Release(); return true; } int BackendImpl::DoomEntry(const std::string& key, CompletionCallback* callback) { - DCHECK(callback); - background_queue_.DoomEntry(key, callback); - return net::ERR_IO_PENDING; -} - -int BackendImpl::SyncDoomAllEntries() { - if (DoomAllEntries()) + if (DoomEntry(key)) return net::OK; return net::ERR_FAILED; @@ -644,14 +538,7 @@ bool BackendImpl::DoomAllEntries() { } int BackendImpl::DoomAllEntries(CompletionCallback* callback) { - DCHECK(callback); - background_queue_.DoomAllEntries(callback); - return net::ERR_IO_PENDING; -} - -int BackendImpl::SyncDoomEntriesBetween(const base::Time initial_time, - const base::Time end_time) { - if (DoomEntriesBetween(initial_time, end_time)) + if (DoomAllEntries()) return net::OK; return net::ERR_FAILED; @@ -667,27 +554,27 @@ bool BackendImpl::DoomEntriesBetween(const Time initial_time, if (disabled_) return false; - EntryImpl* node; + Entry* node, *next; void* iter = NULL; - EntryImpl* next = OpenNextEntryImpl(&iter); - if (!next) + if (!OpenNextEntry(&iter, &next)) return true; while (next) { node = next; - next = OpenNextEntryImpl(&iter); + if (!OpenNextEntry(&iter, &next)) + next = NULL; if (node->GetLastUsed() >= initial_time && node->GetLastUsed() < end_time) { - node->DoomImpl(); + node->Doom(); } else if (node->GetLastUsed() < initial_time) { if (next) - next->Release(); + next->Close(); next = NULL; - SyncEndEnumeration(iter); + EndEnumeration(&iter); } - node->Release(); + node->Close(); } return true; @@ -696,72 +583,59 @@ bool BackendImpl::DoomEntriesBetween(const Time initial_time, int BackendImpl::DoomEntriesBetween(const base::Time initial_time, const base::Time end_time, CompletionCallback* callback) { - DCHECK(callback); - background_queue_.DoomEntriesBetween(initial_time, end_time, callback); - return net::ERR_IO_PENDING; -} - -int BackendImpl::SyncDoomEntriesSince(const base::Time initial_time) { - if (DoomEntriesSince(initial_time)) + if (DoomEntriesBetween(initial_time, end_time)) return net::OK; return net::ERR_FAILED; } -// We use OpenNextEntryImpl to retrieve elements from the cache, until we get +// We use OpenNextEntry to retrieve elements from the cache, until we get // entries that are too old. bool BackendImpl::DoomEntriesSince(const Time initial_time) { if (disabled_) return false; for (;;) { + Entry* entry; void* iter = NULL; - EntryImpl* entry = OpenNextEntryImpl(&iter); - if (!entry) + if (!OpenNextEntry(&iter, &entry)) return true; if (initial_time > entry->GetLastUsed()) { - entry->Release(); - SyncEndEnumeration(iter); + entry->Close(); + EndEnumeration(&iter); return true; } - entry->DoomImpl(); - entry->Release(); - SyncEndEnumeration(iter); // Dooming the entry invalidates the iterator. + entry->Doom(); + entry->Close(); + EndEnumeration(&iter); // Dooming the entry invalidates the iterator. } } int BackendImpl::DoomEntriesSince(const base::Time initial_time, CompletionCallback* callback) { - DCHECK(callback); - background_queue_.DoomEntriesSince(initial_time, callback); - return net::ERR_IO_PENDING; -} + if (DoomEntriesSince(initial_time)) + return net::OK; -int BackendImpl::SyncOpenNextEntry(void** iter, Entry** next_entry) { - *next_entry = OpenNextEntryImpl(iter); - return (*next_entry) ? net::OK : net::ERR_FAILED; + return net::ERR_FAILED; } -EntryImpl* BackendImpl::OpenNextEntryImpl(void** iter) { - return OpenFollowingEntry(true, iter); +bool BackendImpl::OpenNextEntry(void** iter, Entry** next_entry) { + return OpenFollowingEntry(true, iter, next_entry); } int BackendImpl::OpenNextEntry(void** iter, Entry** next_entry, CompletionCallback* callback) { - DCHECK(callback); - background_queue_.OpenNextEntry(iter, next_entry, callback); - return net::ERR_IO_PENDING; -} + if (OpenNextEntry(iter, next_entry)) + return net::OK; -void BackendImpl::SyncEndEnumeration(void* iter) { - scoped_ptr<Rankings::Iterator> iterator( - reinterpret_cast<Rankings::Iterator*>(iter)); + return net::ERR_FAILED; } void BackendImpl::EndEnumeration(void** iter) { - background_queue_.EndEnumeration(*iter); + scoped_ptr<Rankings::Iterator> iterator( + reinterpret_cast<Rankings::Iterator*>(*iter)); *iter = NULL; } @@ -1142,11 +1016,6 @@ void BackendImpl::ClearRefCountForTest() { num_refs_ = 0; } -int BackendImpl::FlushQueueForTest(CompletionCallback* callback) { - background_queue_.FlushQueue(callback); - return net::ERR_IO_PENDING; -} - int BackendImpl::SelfCheck() { if (!init_) { LOG(ERROR) << "Init failed"; @@ -1167,20 +1036,8 @@ int BackendImpl::SelfCheck() { return CheckAllEntries(); } -int BackendImpl::SyncOpenPrevEntry(void** iter, Entry** prev_entry) { - *prev_entry = OpenPrevEntryImpl(iter); - return (*prev_entry) ? net::OK : net::ERR_FAILED; -} - -int BackendImpl::OpenPrevEntry(void** iter, Entry** prev_entry, - CompletionCallback* callback) { - DCHECK(callback); - background_queue_.OpenPrevEntry(iter, prev_entry, callback); - return net::ERR_IO_PENDING; -} - -EntryImpl* BackendImpl::OpenPrevEntryImpl(void** iter) { - return OpenFollowingEntry(false, iter); +bool BackendImpl::OpenPrevEntry(void** iter, Entry** prev_entry) { + return OpenFollowingEntry(false, iter, prev_entry); } // ------------------------------------------------------------------------ @@ -1294,7 +1151,7 @@ void BackendImpl::RestartCache() { // trying to re-enable the cache. if (unit_test_) init_ = true; // Let the destructor do proper cleanup. - else if (SyncInit()) + else if (Init()) stats_.SetCounter(Stats::FATAL_ERROR, errors + 1); } @@ -1444,11 +1301,14 @@ EntryImpl* BackendImpl::MatchEntry(const std::string& key, uint32 hash, } // This is the actual implementation for OpenNextEntry and OpenPrevEntry. -EntryImpl* BackendImpl::OpenFollowingEntry(bool forward, void** iter) { +bool BackendImpl::OpenFollowingEntry(bool forward, void** iter, + Entry** next_entry) { if (disabled_) - return NULL; + return false; DCHECK(iter); + DCHECK(next_entry); + *next_entry = NULL; const int kListsToSearch = 3; scoped_refptr<EntryImpl> entries[kListsToSearch]; @@ -1468,7 +1328,7 @@ EntryImpl* BackendImpl::OpenFollowingEntry(bool forward, void** iter) { entries[i].swap(&temp); // The entry was already addref'd. } if (!ret) - return NULL; + return false; } else { // Get the next entry from the last list, and the actual entries for the // elements on the other lists. @@ -1504,19 +1364,18 @@ EntryImpl* BackendImpl::OpenFollowingEntry(bool forward, void** iter) { } if (newest < 0 || oldest < 0) - return NULL; + return false; - EntryImpl* next_entry; if (forward) { - next_entry = entries[newest].release(); + entries[newest].swap(reinterpret_cast<EntryImpl**>(next_entry)); iterator->list = static_cast<Rankings::List>(newest); } else { - next_entry = entries[oldest].release(); + entries[oldest].swap(reinterpret_cast<EntryImpl**>(next_entry)); iterator->list = static_cast<Rankings::List>(oldest); } *iter = iterator.release(); - return next_entry; + return true; } bool BackendImpl::OpenFollowingEntryFromList(bool forward, Rankings::List list, diff --git a/net/disk_cache/backend_impl.h b/net/disk_cache/backend_impl.h index 6dc2d2e..706a0cb 100644 --- a/net/disk_cache/backend_impl.h +++ b/net/disk_cache/backend_impl.h @@ -13,7 +13,6 @@ #include "net/disk_cache/block_files.h" #include "net/disk_cache/disk_cache.h" #include "net/disk_cache/eviction.h" -#include "net/disk_cache/in_flight_backend_io.h" #include "net/disk_cache/rankings.h" #include "net/disk_cache/stats.h" #include "net/disk_cache/trace.h" @@ -37,20 +36,18 @@ class BackendImpl : public Backend { friend class Eviction; public: BackendImpl(const FilePath& path, base::MessageLoopProxy* cache_thread) - : ALLOW_THIS_IN_INITIALIZER_LIST(background_queue_(this, cache_thread)), - path_(path), block_files_(path), mask_(0), max_size_(0), + : path_(path), block_files_(path), mask_(0), max_size_(0), cache_type_(net::DISK_CACHE), uma_report_(0), user_flags_(0), init_(false), restarted_(false), unit_test_(false), read_only_(false), - new_eviction_(false), first_timer_(true), done_(true, false), + new_eviction_(false), first_timer_(true), ALLOW_THIS_IN_INITIALIZER_LIST(factory_(this)) {} // mask can be used to limit the usable size of the hash table, for testing. BackendImpl(const FilePath& path, uint32 mask, base::MessageLoopProxy* cache_thread) - : ALLOW_THIS_IN_INITIALIZER_LIST(background_queue_(this, cache_thread)), - path_(path), block_files_(path), mask_(mask), max_size_(0), + : path_(path), block_files_(path), mask_(mask), max_size_(0), cache_type_(net::DISK_CACHE), uma_report_(0), user_flags_(kMask), init_(false), restarted_(false), unit_test_(false), read_only_(false), - new_eviction_(false), first_timer_(true), done_(true, false), + new_eviction_(false), first_timer_(true), ALLOW_THIS_IN_INITIALIZER_LIST(factory_(this)) {} ~BackendImpl(); @@ -62,12 +59,7 @@ class BackendImpl : public Backend { Backend** backend, CompletionCallback* callback); // Performs general initialization for this current instance of the cache. - bool Init(); // Deprecated. - int Init(CompletionCallback* callback); - int SyncInit(); - - // Performs final cleanup on destruction. - void CleanupCache(); + bool Init(); // Backend interface. virtual int32 GetEntryCount() const; @@ -87,17 +79,6 @@ class BackendImpl : public Backend { virtual void EndEnumeration(void** iter); virtual void GetStats(StatsItems* stats); - // Synchronous implementation of the asynchronous interface. - int SyncOpenEntry(const std::string& key, Entry** entry); - int SyncCreateEntry(const std::string& key, Entry** entry); - int SyncDoomEntry(const std::string& key); - int SyncDoomAllEntries(); - int SyncDoomEntriesBetween(const base::Time initial_time, - const base::Time end_time); - int SyncDoomEntriesSince(const base::Time initial_time); - int SyncOpenNextEntry(void** iter, Entry** next_entry); - void SyncEndEnumeration(void* iter); - // Sets the maximum size for the total amount of data stored by this instance. bool SetMaxSize(int max_bytes); @@ -110,10 +91,6 @@ class BackendImpl : public Backend { // Returns the actual file used to store a given (non-external) address. MappedFile* File(Addr address); - InFlightBackendIO* background_queue() { - return &background_queue_; - } - // Creates an external storage file. bool CreateExternalFile(Addr* address); @@ -216,17 +193,12 @@ class BackendImpl : public Backend { // Clears the counter of references to test handling of corruptions. void ClearRefCountForTest(); - // Sends a dummy operation through the operation queue, for unit tests. - int FlushQueueForTest(CompletionCallback* callback); - // Peforms a simple self-check, and returns the number of dirty items // or an error code (negative value). int SelfCheck(); // Same bahavior as OpenNextEntry but walks the list from back to front. - int OpenPrevEntry(void** iter, Entry** prev_entry, - CompletionCallback* callback); - int SyncOpenPrevEntry(void** iter, Entry** prev_entry); + bool OpenPrevEntry(void** iter, Entry** prev_entry); // Old Backend interface. bool OpenEntry(const std::string& key, Entry** entry); @@ -236,12 +208,11 @@ class BackendImpl : public Backend { bool DoomEntriesBetween(const base::Time initial_time, const base::Time end_time); bool DoomEntriesSince(const base::Time initial_time); + bool OpenNextEntry(void** iter, Entry** next_entry); - // Open or create an entry for the given |key| or |iter|. + // Open or create an entry for the given |key|. EntryImpl* OpenEntryImpl(const std::string& key); EntryImpl* CreateEntryImpl(const std::string& key); - EntryImpl* OpenNextEntryImpl(void** iter); - EntryImpl* OpenPrevEntryImpl(void** iter); private: typedef base::hash_map<CacheAddr, EntryImpl*> EntriesMap; @@ -265,7 +236,7 @@ class BackendImpl : public Backend { EntryImpl* MatchEntry(const std::string& key, uint32 hash, bool find_parent); // Opens the next or previous entry on a cache iteration. - EntryImpl* OpenFollowingEntry(bool forward, void** iter); + bool OpenFollowingEntry(bool forward, void** iter, Entry** next_entry); // Opens the next or previous entry on a single list. If successfull, // |from_entry| will be updated to point to the new entry, otherwise it will @@ -312,7 +283,6 @@ class BackendImpl : public Backend { // Part of the self test. Returns false if the entry is corrupt. bool CheckEntry(EntryImpl* cache_entry); - InFlightBackendIO background_queue_; // The controller of pending operations. scoped_refptr<MappedFile> index_; // The main cache index. FilePath path_; // Path to the folder used as backing storage. Index* data_; // Pointer to the index data. @@ -338,7 +308,6 @@ class BackendImpl : public Backend { Stats stats_; // Usage statistcs. base::RepeatingTimer<BackendImpl> timer_; // Usage timer. - base::WaitableEvent done_; // Signals the end of background work. scoped_refptr<TraceObject> trace_object_; // Inits internal tracing. ScopedRunnableMethodFactory<BackendImpl> factory_; diff --git a/net/disk_cache/backend_unittest.cc b/net/disk_cache/backend_unittest.cc index c92871e..efb7925 100644 --- a/net/disk_cache/backend_unittest.cc +++ b/net/disk_cache/backend_unittest.cc @@ -7,6 +7,7 @@ #include "base/path_service.h" #include "base/platform_thread.h" #include "base/string_util.h" +#include "base/thread.h" #include "net/base/io_buffer.h" #include "net/base/net_errors.h" #include "net/base/test_completion_callback.h" @@ -253,9 +254,8 @@ TEST_F(DiskCacheBackendTest, ExternalFiles) { EXPECT_EQ(0, memcmp(buffer1->data(), buffer2->data(), kSize)); } -// Tests that we deal with file-level pending operations at destruction time. TEST_F(DiskCacheTest, ShutdownWithPendingIO) { - TestCompletionCallback cb; + TestCompletionCallback callback; { FilePath path = GetCacheFilePath(); @@ -267,74 +267,27 @@ TEST_F(DiskCacheTest, ShutdownWithPendingIO) { disk_cache::Backend* cache; int rv = disk_cache::BackendImpl::CreateBackend( path, false, 0, net::DISK_CACHE, disk_cache::kNoRandom, - base::MessageLoopProxy::CreateForCurrentThread(), &cache, &cb); - ASSERT_EQ(net::OK, cb.GetResult(rv)); + cache_thread.message_loop_proxy(), &cache, &callback); + ASSERT_EQ(net::OK, callback.GetResult(rv)); - disk_cache::EntryImpl* entry; - rv = cache->CreateEntry("some key", - reinterpret_cast<disk_cache::Entry**>(&entry), &cb); - ASSERT_EQ(net::OK, cb.GetResult(rv)); + disk_cache::Entry* entry; + rv = cache->CreateEntry("some key", &entry, &callback); + ASSERT_EQ(net::OK, callback.GetResult(rv)); const int kSize = 25000; scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(kSize); CacheTestFillBuffer(buffer->data(), kSize, false); for (int i = 0; i < 10 * 1024 * 1024; i += 64 * 1024) { - // We are using the current thread as the cache thread because we want to - // be able to call directly this method to make sure that the OS (instead - // of us switching thread) is returning IO pending. - rv = entry->WriteDataImpl(0, i, buffer, kSize, &cb, false); + int rv = entry->WriteData(0, i, buffer, kSize, &callback, false); if (rv == net::ERR_IO_PENDING) break; EXPECT_EQ(kSize, rv); } - // Don't call Close() to avoid going through the queue or we'll deadlock - // waiting for the operation to finish. - entry->Release(); - - // The cache destructor will see one pending operation here. - delete cache; - - if (rv == net::ERR_IO_PENDING) { - EXPECT_TRUE(cb.have_result()); - } - } - - MessageLoop::current()->RunAllPending(); -} - -// Tests that we deal with background-thread pending operations. -TEST_F(DiskCacheTest, ShutdownWithPendingIO2) { - TestCompletionCallback cb; - - { - FilePath path = GetCacheFilePath(); - ASSERT_TRUE(DeleteCache(path)); - base::Thread cache_thread("CacheThread"); - ASSERT_TRUE(cache_thread.StartWithOptions( - base::Thread::Options(MessageLoop::TYPE_IO, 0))); - - disk_cache::Backend* cache; - int rv = disk_cache::BackendImpl::CreateBackend( - path, false, 0, net::DISK_CACHE, disk_cache::kNoRandom, - cache_thread.message_loop_proxy(), &cache, &cb); - ASSERT_EQ(net::OK, cb.GetResult(rv)); - - disk_cache::Entry* entry; - rv = cache->CreateEntry("some key", &entry, &cb); - ASSERT_EQ(net::OK, cb.GetResult(rv)); - - const int kSize = 25000; - scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(kSize); - CacheTestFillBuffer(buffer->data(), kSize, false); - - rv = entry->WriteData(0, 0, buffer, kSize, &cb, false); - EXPECT_EQ(net::ERR_IO_PENDING, rv); - entry->Close(); - // The cache destructor will see two pending operations here. + // The cache destructor will see one pending operation here. delete cache; } @@ -449,7 +402,6 @@ void DiskCacheBackendTest::BackendLoad() { entries[i]->Doom(); entries[i]->Close(); } - FlushQueueForTest(); EXPECT_EQ(0, cache_->GetEntryCount()); } @@ -673,7 +625,6 @@ void DiskCacheBackendTest::BackendTrimInvalidEntry() { EXPECT_EQ(2, cache_->GetEntryCount()); SetMaxSize(kSize); entry->Close(); // Trim the cache. - FlushQueueForTest(); // If we evicted the entry in less than 20mS, we have one entry in the cache; // if it took more than that, we posted a task and we'll delete the second @@ -734,7 +685,6 @@ void DiskCacheBackendTest::BackendTrimInvalidEntry2() { } entry->Close(); // Trim the cache. - FlushQueueForTest(); // We may abort the eviction before cleaning up everything. MessageLoop::current()->RunAllPending(); @@ -1309,7 +1259,7 @@ void DiskCacheBackendTest::BackendInvalidRankings() { EXPECT_EQ(2, cache_->GetEntryCount()); EXPECT_NE(net::OK, OpenNextEntry(&iter, &entry)); - FlushQueueForTest(); // Allow the restart to finish. + MessageLoop::current()->RunAllPending(); EXPECT_EQ(0, cache_->GetEntryCount()); } @@ -1360,8 +1310,7 @@ void DiskCacheBackendTest::BackendDisable() { EXPECT_NE(net::OK, CreateEntry("Something new", &entry2)); entry1->Close(); - FlushQueueForTest(); // Flushing the Close posts a task to restart the cache. - FlushQueueForTest(); // This one actually allows that task to complete. + MessageLoop::current()->RunAllPending(); EXPECT_EQ(0, cache_->GetEntryCount()); } @@ -1416,7 +1365,7 @@ void DiskCacheBackendTest::BackendDisable2() { ASSERT_LT(count, 9); }; - FlushQueueForTest(); + MessageLoop::current()->RunAllPending(); EXPECT_EQ(0, cache_->GetEntryCount()); } @@ -1465,7 +1414,7 @@ void DiskCacheBackendTest::BackendDisable3() { entry1->Close(); EXPECT_NE(net::OK, OpenNextEntry(&iter, &entry2)); - FlushQueueForTest(); + MessageLoop::current()->RunAllPending(); ASSERT_EQ(net::OK, CreateEntry("Something new", &entry2)); entry2->Close(); @@ -1533,8 +1482,7 @@ void DiskCacheBackendTest::BackendDisable4() { entry1->Close(); entry2->Close(); entry3->Close(); - FlushQueueForTest(); // Flushing the Close posts a task to restart the cache. - FlushQueueForTest(); // This one actually allows that task to complete. + MessageLoop::current()->RunAllPending(); EXPECT_EQ(0, cache_->GetEntryCount()); } diff --git a/net/disk_cache/disk_cache_test_base.cc b/net/disk_cache/disk_cache_test_base.cc index 0add3c7..7b0cc8e 100644 --- a/net/disk_cache/disk_cache_test_base.cc +++ b/net/disk_cache/disk_cache_test_base.cc @@ -4,7 +4,6 @@ #include "net/disk_cache/disk_cache_test_base.h" -#include "net/base/net_errors.h" #include "net/base/test_completion_callback.h" #include "net/disk_cache/backend_impl.h" #include "net/disk_cache/disk_cache_test_util.h" @@ -67,25 +66,21 @@ void DiskCacheTestWithCache::InitDiskCache() { if (implementation_) return InitDiskCacheImpl(path); - scoped_refptr<base::MessageLoopProxy> thread = - use_current_thread_ ? base::MessageLoopProxy::CreateForCurrentThread() : - cache_thread_.message_loop_proxy(); - TestCompletionCallback cb; int rv = disk_cache::BackendImpl::CreateBackend( path, force_creation_, size_, net::DISK_CACHE, - disk_cache::kNoRandom, thread, &cache_, &cb); + disk_cache::kNoRandom, cache_thread_.message_loop_proxy(), + &cache_, &cb); ASSERT_EQ(net::OK, cb.GetResult(rv)); } void DiskCacheTestWithCache::InitDiskCacheImpl(const FilePath& path) { - scoped_refptr<base::MessageLoopProxy> thread = - use_current_thread_ ? base::MessageLoopProxy::CreateForCurrentThread() : - cache_thread_.message_loop_proxy(); if (mask_) - cache_impl_ = new disk_cache::BackendImpl(path, mask_, thread); + cache_impl_ = new disk_cache::BackendImpl( + path, mask_, cache_thread_.message_loop_proxy()); else - cache_impl_ = new disk_cache::BackendImpl(path, thread); + cache_impl_ = new disk_cache::BackendImpl( + path, cache_thread_.message_loop_proxy()); cache_ = cache_impl_; ASSERT_TRUE(NULL != cache_); @@ -97,9 +92,7 @@ void DiskCacheTestWithCache::InitDiskCacheImpl(const FilePath& path) { cache_impl_->SetNewEviction(); cache_impl_->SetFlags(disk_cache::kNoRandom); - TestCompletionCallback cb; - int rv = cache_impl_->Init(&cb); - ASSERT_EQ(net::OK, cb.GetResult(rv)); + ASSERT_TRUE(cache_impl_->Init()); } void DiskCacheTestWithCache::TearDown() { @@ -119,9 +112,6 @@ void DiskCacheTestWithCache::TearDown() { // We are expected to leak memory when simulating crashes. void DiskCacheTestWithCache::SimulateCrash() { ASSERT_TRUE(implementation_ && !memory_only_); - TestCompletionCallback cb; - int rv = cache_impl_->FlushQueueForTest(&cb); - ASSERT_EQ(net::OK, cb.GetResult(rv)); cache_impl_->ClearRefCountForTest(); delete cache_impl_; @@ -181,12 +171,3 @@ int DiskCacheTestWithCache::OpenNextEntry(void** iter, int rv = cache_->OpenNextEntry(iter, next_entry, &cb); return cb.GetResult(rv); } - -void DiskCacheTestWithCache::FlushQueueForTest() { - if (memory_only_ || !cache_impl_) - return; - - TestCompletionCallback cb; - int rv = cache_impl_->FlushQueueForTest(&cb); - EXPECT_EQ(net::OK, cb.GetResult(rv)); -} diff --git a/net/disk_cache/disk_cache_test_base.h b/net/disk_cache/disk_cache_test_base.h index 6c6b54b..f3c8040 100644 --- a/net/disk_cache/disk_cache_test_base.h +++ b/net/disk_cache/disk_cache_test_base.h @@ -36,7 +36,7 @@ class DiskCacheTestWithCache : public DiskCacheTest { : cache_(NULL), cache_impl_(NULL), mem_cache_(NULL), mask_(0), size_(0), memory_only_(false), implementation_(false), force_creation_(false), new_eviction_(false), first_cleanup_(true), integrity_(true), - use_current_thread_(false), cache_thread_("CacheThread") {} + cache_thread_("CacheThread") {} void InitCache(); virtual void TearDown(); @@ -75,10 +75,6 @@ class DiskCacheTestWithCache : public DiskCacheTest { integrity_ = false; } - void UseCurrentThread() { - use_current_thread_ = true; - } - // Utility methods to access the cache and wait for each operation to finish. int OpenEntry(const std::string& key, disk_cache::Entry** entry); int CreateEntry(const std::string& key, disk_cache::Entry** entry); @@ -88,7 +84,6 @@ class DiskCacheTestWithCache : public DiskCacheTest { const base::Time end_time); int DoomEntriesSince(const base::Time initial_time); int OpenNextEntry(void** iter, disk_cache::Entry** next_entry); - void FlushQueueForTest(); // cache_ will always have a valid object, regardless of how the cache was // initialized. The implementation pointers can be NULL. @@ -104,7 +99,6 @@ class DiskCacheTestWithCache : public DiskCacheTest { bool new_eviction_; bool first_cleanup_; bool integrity_; - bool use_current_thread_; // This is intentionally left uninitialized, to be used by any test. bool success_; diff --git a/net/disk_cache/entry_impl.cc b/net/disk_cache/entry_impl.cc index 7f172ed..1c041d2 100644 --- a/net/disk_cache/entry_impl.cc +++ b/net/disk_cache/entry_impl.cc @@ -89,6 +89,7 @@ EntryImpl::EntryImpl(BackendImpl* backend, Addr address) for (int i = 0; i < kNumStreams; i++) { unreported_size_[i] = 0; } + key_file_ = NULL; } // When an entry is deleted from the cache, we clean up all the data associated @@ -130,7 +131,7 @@ EntryImpl::~EntryImpl() { backend_->CacheEntryDestroyed(entry_.address()); } -void EntryImpl::DoomImpl() { +void EntryImpl::Doom() { if (doomed_) return; @@ -138,12 +139,8 @@ void EntryImpl::DoomImpl() { backend_->InternalDoomEntry(this); } -void EntryImpl::Doom() { - backend_->background_queue()->DoomEntryImpl(this); -} - void EntryImpl::Close() { - backend_->background_queue()->CloseEntryImpl(this); + Release(); } std::string EntryImpl::GetKey() const { @@ -151,26 +148,26 @@ std::string EntryImpl::GetKey() const { if (entry->Data()->key_len <= kMaxInternalKeyLength) return std::string(entry->Data()->key); - // We keep a copy of the key so that we can always return it, even if the - // backend is disabled. - if (!key_.empty()) - return key_; - Addr address(entry->Data()->long_key); DCHECK(address.is_initialized()); size_t offset = 0; if (address.is_block_file()) offset = address.start_block() * address.BlockSize() + kBlockHeaderSize; - COMPILE_ASSERT(kNumStreams == kKeyFileIndex, invalid_key_index); - File* key_file = const_cast<EntryImpl*>(this)->GetBackingFile(address, - kKeyFileIndex); + if (!key_file_) { + // We keep a copy of the file needed to access the key so that we can + // always return this object's key, even if the backend is disabled. + COMPILE_ASSERT(kNumStreams == kKeyFileIndex, invalid_key_index); + key_file_ = const_cast<EntryImpl*>(this)->GetBackingFile(address, + kKeyFileIndex); + } - if (!key_file || - !key_file->Read(WriteInto(&key_, entry->Data()->key_len + 1), - entry->Data()->key_len + 1, offset)) - key_.clear(); - return key_; + std::string key; + if (!key_file_ || + !key_file_->Read(WriteInto(&key, entry->Data()->key_len + 1), + entry->Data()->key_len + 1, offset)) + key.clear(); + return key; } Time EntryImpl::GetLastUsed() const { @@ -191,8 +188,8 @@ int32 EntryImpl::GetDataSize(int index) const { return entry->Data()->data_size[index]; } -int EntryImpl::ReadDataImpl(int index, int offset, net::IOBuffer* buf, - int buf_len, CompletionCallback* callback) { +int EntryImpl::ReadData(int index, int offset, net::IOBuffer* buf, int buf_len, + net::CompletionCallback* completion_callback) { DCHECK(node_.Data()->dirty); if (index < 0 || index >= kNumStreams) return net::ERR_INVALID_ARGUMENT; @@ -236,8 +233,8 @@ int EntryImpl::ReadDataImpl(int index, int offset, net::IOBuffer* buf, kBlockHeaderSize; SyncCallback* io_callback = NULL; - if (callback) - io_callback = new SyncCallback(this, buf, callback); + if (completion_callback) + io_callback = new SyncCallback(this, buf, completion_callback); bool completed; if (!file->Read(buf->data(), buf_len, file_offset, io_callback, &completed)) { @@ -250,33 +247,12 @@ int EntryImpl::ReadDataImpl(int index, int offset, net::IOBuffer* buf, io_callback->Discard(); ReportIOTime(kRead, start); - return (completed || !callback) ? buf_len : net::ERR_IO_PENDING; -} - -int EntryImpl::ReadData(int index, int offset, net::IOBuffer* buf, int buf_len, - net::CompletionCallback* callback) { - if (!callback) - return ReadDataImpl(index, offset, buf, buf_len, callback); - - DCHECK(node_.Data()->dirty); - 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; + return (completed || !completion_callback) ? buf_len : net::ERR_IO_PENDING; } -int EntryImpl::WriteDataImpl(int index, int offset, net::IOBuffer* buf, - int buf_len, CompletionCallback* callback, - bool truncate) { +int EntryImpl::WriteData(int index, int offset, net::IOBuffer* buf, int buf_len, + net::CompletionCallback* completion_callback, + bool truncate) { DCHECK(node_.Data()->dirty); if (index < 0 || index >= kNumStreams) return net::ERR_INVALID_ARGUMENT; @@ -286,7 +262,7 @@ int EntryImpl::WriteDataImpl(int index, int offset, net::IOBuffer* buf, int max_file_size = backend_->MaxFileSize(); - // offset or buf_len could be negative numbers. + // offset of 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; @@ -356,8 +332,8 @@ int EntryImpl::WriteDataImpl(int index, int offset, net::IOBuffer* buf, return 0; SyncCallback* io_callback = NULL; - if (callback) - io_callback = new SyncCallback(this, buf, callback); + if (completion_callback) + io_callback = new SyncCallback(this, buf, completion_callback); bool completed; if (!file->Write(buf->data(), buf_len, file_offset, io_callback, @@ -371,28 +347,11 @@ int EntryImpl::WriteDataImpl(int index, int offset, net::IOBuffer* buf, io_callback->Discard(); ReportIOTime(kWrite, start); - return (completed || !callback) ? buf_len : net::ERR_IO_PENDING; -} - -int EntryImpl::WriteData(int index, int offset, net::IOBuffer* buf, int buf_len, - CompletionCallback* callback, bool truncate) { - if (!callback) - return WriteDataImpl(index, offset, buf, buf_len, callback, truncate); - - DCHECK(node_.Data()->dirty); - 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; + return (completed || !completion_callback) ? buf_len : net::ERR_IO_PENDING; } -int EntryImpl::ReadSparseDataImpl(int64 offset, net::IOBuffer* buf, int buf_len, - CompletionCallback* callback) { +int EntryImpl::ReadSparseData(int64 offset, net::IOBuffer* buf, int buf_len, + net::CompletionCallback* completion_callback) { DCHECK(node_.Data()->dirty); int result = InitSparseData(); if (net::OK != result) @@ -400,23 +359,13 @@ int EntryImpl::ReadSparseDataImpl(int64 offset, net::IOBuffer* buf, int buf_len, TimeTicks start = TimeTicks::Now(); result = sparse_->StartIO(SparseControl::kReadOperation, offset, buf, buf_len, - callback); + completion_callback); ReportIOTime(kSparseRead, start); return result; } -int EntryImpl::ReadSparseData(int64 offset, net::IOBuffer* buf, int buf_len, - net::CompletionCallback* callback) { - if (!callback) - return ReadSparseDataImpl(offset, buf, buf_len, callback); - - backend_->background_queue()->ReadSparseData(this, offset, buf, buf_len, - callback); - return net::ERR_IO_PENDING; -} - -int EntryImpl::WriteSparseDataImpl(int64 offset, net::IOBuffer* buf, - int buf_len, CompletionCallback* callback) { +int EntryImpl::WriteSparseData(int64 offset, net::IOBuffer* buf, int buf_len, + net::CompletionCallback* completion_callback) { DCHECK(node_.Data()->dirty); int result = InitSparseData(); if (net::OK != result) @@ -424,25 +373,11 @@ int EntryImpl::WriteSparseDataImpl(int64 offset, net::IOBuffer* buf, TimeTicks start = TimeTicks::Now(); result = sparse_->StartIO(SparseControl::kWriteOperation, offset, buf, - buf_len, callback); + buf_len, completion_callback); ReportIOTime(kSparseWrite, start); return result; } -int EntryImpl::WriteSparseData(int64 offset, net::IOBuffer* buf, int buf_len, - net::CompletionCallback* callback) { - if (!callback) - return WriteSparseDataImpl(offset, buf, buf_len, callback); - - backend_->background_queue()->WriteSparseData(this, offset, buf, buf_len, - callback); - return net::ERR_IO_PENDING; -} - -int EntryImpl::GetAvailableRangeImpl(int64 offset, int len, int64* start) { - return GetAvailableRange(offset, len, start); -} - int EntryImpl::GetAvailableRange(int64 offset, int len, int64* start) { int result = InitSparseData(); if (net::OK != result) @@ -453,9 +388,7 @@ int EntryImpl::GetAvailableRange(int64 offset, int len, int64* start) { int EntryImpl::GetAvailableRange(int64 offset, int len, int64* start, CompletionCallback* callback) { - backend_->background_queue()->GetAvailableRange(this, offset, len, start, - callback); - return net::ERR_IO_PENDING; + return GetAvailableRange(offset, len, start); } bool EntryImpl::CouldBeSparse() const { @@ -468,26 +401,17 @@ bool EntryImpl::CouldBeSparse() const { } void EntryImpl::CancelSparseIO() { - backend_->background_queue()->CancelSparseIO(this); -} - -void EntryImpl::CancelSparseIOImpl() { if (!sparse_.get()) return; sparse_->CancelIO(); } -int EntryImpl::ReadyForSparseIOImpl(CompletionCallback* callback) { - return sparse_->ReadyToUse(callback); -} - -int EntryImpl::ReadyForSparseIO(net::CompletionCallback* callback) { +int EntryImpl::ReadyForSparseIO(net::CompletionCallback* completion_callback) { if (!sparse_.get()) return net::OK; - backend_->background_queue()->ReadyForSparseIO(this, callback); - return net::ERR_IO_PENDING; + return sparse_->ReadyToUse(completion_callback); } // ------------------------------------------------------------------------ @@ -518,20 +442,19 @@ bool EntryImpl::CreateEntry(Addr node_address, const std::string& key, return false; entry_store->long_key = address.value(); - File* key_file = GetBackingFile(address, kKeyFileIndex); - key_ = key; + key_file_ = GetBackingFile(address, kKeyFileIndex); size_t offset = 0; if (address.is_block_file()) offset = address.start_block() * address.BlockSize() + kBlockHeaderSize; - if (!key_file || !key_file->Write(key.data(), key.size(), offset)) { + if (!key_file_ || !key_file_->Write(key.data(), key.size(), offset)) { DeleteData(address, kKeyFileIndex); return false; } if (address.is_separate_file()) - key_file->SetLength(key.size() + 1); + key_file_->SetLength(key.size() + 1); } else { memcpy(entry_store->key, key.data(), key.size()); entry_store->key[key.size()] = '\0'; diff --git a/net/disk_cache/entry_impl.h b/net/disk_cache/entry_impl.h index 1caece2..8ab4d44 100644 --- a/net/disk_cache/entry_impl.h +++ b/net/disk_cache/entry_impl.h @@ -53,20 +53,6 @@ class EntryImpl : public Entry, public base::RefCounted<EntryImpl> { virtual void CancelSparseIO(); virtual int ReadyForSparseIO(net::CompletionCallback* completion_callback); - // Background implementation of the Entry interface. - void DoomImpl(); - int ReadDataImpl(int index, int offset, net::IOBuffer* buf, int buf_len, - CompletionCallback* callback); - int WriteDataImpl(int index, int offset, net::IOBuffer* buf, int buf_len, - CompletionCallback* callback, bool truncate); - int ReadSparseDataImpl(int64 offset, net::IOBuffer* buf, int buf_len, - CompletionCallback* callback); - int WriteSparseDataImpl(int64 offset, net::IOBuffer* buf, int buf_len, - CompletionCallback* callback); - int GetAvailableRangeImpl(int64 offset, int len, int64* start); - void CancelSparseIOImpl(); - int ReadyForSparseIOImpl(CompletionCallback* callback); - inline CacheEntryBlock* entry() { return &entry_; } @@ -200,7 +186,8 @@ class EntryImpl : public Entry, public base::RefCounted<EntryImpl> { scoped_array<char> user_buffers_[kNumStreams]; // Store user data. // Files to store external user data and key. scoped_refptr<File> files_[kNumStreams + 1]; - mutable std::string key_; // Copy of the key. + // Copy of the file used to store the key. We don't own this object. + mutable File* key_file_; int unreported_size_[kNumStreams]; // Bytes not reported yet to the backend. bool doomed_; // True if this entry was removed from the cache. scoped_ptr<SparseControl> sparse_; // Support for sparse entries. diff --git a/net/disk_cache/entry_unittest.cc b/net/disk_cache/entry_unittest.cc index d92d5c7..95bbb47 100644 --- a/net/disk_cache/entry_unittest.cc +++ b/net/disk_cache/entry_unittest.cc @@ -82,12 +82,10 @@ void DiskCacheEntryTest::InternalSyncIO() { entry1->Doom(); entry1->Close(); - FlushQueueForTest(); EXPECT_EQ(0, cache_->GetEntryCount()); } TEST_F(DiskCacheEntryTest, InternalSyncIO) { - SetDirectMode(); InitCache(); InternalSyncIO(); } @@ -225,12 +223,10 @@ void DiskCacheEntryTest::InternalAsyncIO() { entry1->Doom(); entry1->Close(); - FlushQueueForTest(); EXPECT_EQ(0, cache_->GetEntryCount()); } TEST_F(DiskCacheEntryTest, InternalAsyncIO) { - SetDirectMode(); InitCache(); InternalAsyncIO(); } @@ -273,12 +269,10 @@ void DiskCacheEntryTest::ExternalSyncIO() { entry1->Doom(); entry1->Close(); - FlushQueueForTest(); EXPECT_EQ(0, cache_->GetEntryCount()); } TEST_F(DiskCacheEntryTest, ExternalSyncIO) { - SetDirectMode(); InitCache(); ExternalSyncIO(); } @@ -373,21 +367,19 @@ void DiskCacheEntryTest::ExternalAsyncIO() { EXPECT_TRUE(17000 == ret || net::ERR_IO_PENDING == ret); if (net::ERR_IO_PENDING == ret) expected++; + EXPECT_EQ(37000, entry1->GetDataSize(1)); EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected)); - EXPECT_EQ(37000, entry1->GetDataSize(1)); EXPECT_FALSE(g_cache_tests_error); EXPECT_EQ(expected, g_cache_tests_received); entry1->Doom(); entry1->Close(); - FlushQueueForTest(); EXPECT_EQ(0, cache_->GetEntryCount()); } TEST_F(DiskCacheEntryTest, ExternalAsyncIO) { - SetDirectMode(); InitCache(); ExternalAsyncIO(); } @@ -796,12 +788,10 @@ void DiskCacheEntryTest::DoomNormalEntry() { entry1->Doom(); entry1->Close(); - FlushQueueForTest(); EXPECT_EQ(0, cache_->GetEntryCount()); } TEST_F(DiskCacheEntryTest, DoomEntry) { - SetDirectMode(); InitCache(); DoomNormalEntry(); } @@ -819,7 +809,6 @@ void DiskCacheEntryTest::DoomedEntry() { ASSERT_EQ(net::OK, CreateEntry(key, &entry)); entry->Doom(); - FlushQueueForTest(); EXPECT_EQ(0, cache_->GetEntryCount()); Time initial = Time::Now(); PlatformThread::Sleep(20); @@ -842,7 +831,6 @@ void DiskCacheEntryTest::DoomedEntry() { } TEST_F(DiskCacheEntryTest, DoomedEntry) { - SetDirectMode(); InitCache(); DoomedEntry(); } @@ -1275,8 +1263,6 @@ void DiskCacheEntryTest::DoomSparseEntry() { } TEST_F(DiskCacheEntryTest, DoomSparseEntry) { - SetDirectMode(); - UseCurrentThread(); InitCache(); DoomSparseEntry(); } @@ -1435,7 +1421,6 @@ TEST_F(DiskCacheEntryTest, CleanupSparseEntry) { } TEST_F(DiskCacheEntryTest, CancelSparseIO) { - UseCurrentThread(); InitCache(); std::string key("the first key"); disk_cache::Entry* entry; @@ -1445,20 +1430,25 @@ TEST_F(DiskCacheEntryTest, CancelSparseIO) { scoped_refptr<net::IOBuffer> buf = new net::IOBuffer(kSize); CacheTestFillBuffer(buf->data(), kSize, false); - // This will open and write two "real" entries. TestCompletionCallback cb1, cb2, cb3, cb4, cb5; - int rv = entry->WriteSparseData(1024 * 1024 - 4096, buf, kSize, &cb1); - EXPECT_EQ(net::ERR_IO_PENDING, rv); - int64 offset = 0; - rv = entry->GetAvailableRange(offset, kSize, &offset, &cb5); - rv = cb5.GetResult(rv); - if (!cb1.have_result()) { - // We may or may not have finished writing to the entry. If we have not, - // we cannot start another operation at this time. - EXPECT_EQ(net::ERR_CACHE_OPERATION_NOT_SUPPORTED, rv); + int tries = 0; + const int maxtries = 100; // Avoid hang on infinitely fast disks. + for (int ret = 0; ret != net::ERR_IO_PENDING; offset += kSize * 4) { + ret = entry->WriteSparseData(offset, buf, kSize, &cb1); + if (++tries > maxtries) { + LOG(ERROR) << "Data writes never come back PENDING; skipping test"; + entry->Close(); + return; + } } + // Cannot use the entry at this point. + offset = 0; + int rv = entry->GetAvailableRange(offset, kSize, &offset, &cb5); + EXPECT_EQ(net::ERR_CACHE_OPERATION_NOT_SUPPORTED, cb5.GetResult(rv)); + EXPECT_EQ(net::OK, entry->ReadyForSparseIO(&cb2)); + // We cancel the pending operation, and register multiple notifications. entry->CancelSparseIO(); EXPECT_EQ(net::ERR_IO_PENDING, entry->ReadyForSparseIO(&cb2)); @@ -1466,12 +1456,13 @@ TEST_F(DiskCacheEntryTest, CancelSparseIO) { entry->CancelSparseIO(); // Should be a no op at this point. EXPECT_EQ(net::ERR_IO_PENDING, entry->ReadyForSparseIO(&cb4)); - if (!cb1.have_result()) { - EXPECT_EQ(net::ERR_CACHE_OPERATION_NOT_SUPPORTED, - entry->ReadSparseData(offset, buf, kSize, NULL)); - EXPECT_EQ(net::ERR_CACHE_OPERATION_NOT_SUPPORTED, - entry->WriteSparseData(offset, buf, kSize, NULL)); - } + offset = 0; + rv = entry->GetAvailableRange(offset, kSize, &offset, &cb5); + EXPECT_EQ(net::ERR_CACHE_OPERATION_NOT_SUPPORTED, cb5.GetResult(rv)); + EXPECT_EQ(net::ERR_CACHE_OPERATION_NOT_SUPPORTED, + entry->ReadSparseData(offset, buf, kSize, NULL)); + EXPECT_EQ(net::ERR_CACHE_OPERATION_NOT_SUPPORTED, + entry->WriteSparseData(offset, buf, kSize, NULL)); // Now see if we receive all notifications. EXPECT_EQ(kSize, cb1.GetResult(net::ERR_IO_PENDING)); @@ -1480,6 +1471,7 @@ TEST_F(DiskCacheEntryTest, CancelSparseIO) { EXPECT_EQ(net::OK, cb4.GetResult(net::ERR_IO_PENDING)); rv = entry->GetAvailableRange(offset, kSize, &offset, &cb5); - EXPECT_EQ(0, cb5.GetResult(rv)); + EXPECT_EQ(kSize, cb5.GetResult(rv)); + EXPECT_EQ(net::OK, entry->ReadyForSparseIO(&cb2)); entry->Close(); } diff --git a/net/disk_cache/eviction.cc b/net/disk_cache/eviction.cc index e2e810a..0122b7a 100644 --- a/net/disk_cache/eviction.cc +++ b/net/disk_cache/eviction.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2006-2008 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. @@ -224,7 +224,7 @@ bool Eviction::EvictEntry(CacheRankingsBlock* node, bool empty) { ReportTrimTimes(entry); if (empty || !new_eviction_) { - entry->DoomImpl(); + entry->Doom(); } else { entry->DeleteEntryData(false); EntryStore* info = entry->entry()->Data(); @@ -453,7 +453,7 @@ bool Eviction::RemoveDeletedNode(CacheRankingsBlock* node) { } bool doomed = (entry->entry()->Data()->state == ENTRY_DOOMED); entry->entry()->Data()->state = ENTRY_DOOMED; - entry->DoomImpl(); + entry->Doom(); entry->Release(); return !doomed; } diff --git a/net/disk_cache/file_posix.cc b/net/disk_cache/file_posix.cc index 295f744..cf621f4 100644 --- a/net/disk_cache/file_posix.cc +++ b/net/disk_cache/file_posix.cc @@ -193,9 +193,6 @@ void InFlightIO::PostRead(disk_cache::File *file, void* buf, size_t buf_len, io_list_.insert(operation.get()); file->AddRef(); // Balanced on InvokeCallback() - if (!callback_thread_) - callback_thread_ = MessageLoop::current(); - WorkerPool::PostTask(FROM_HERE, NewRunnableMethod(operation.get(), &BackgroundIO::Read), true); @@ -210,9 +207,6 @@ void InFlightIO::PostWrite(disk_cache::File* file, const void* buf, io_list_.insert(operation.get()); file->AddRef(); // Balanced on InvokeCallback() - if (!callback_thread_) - callback_thread_ = MessageLoop::current(); - WorkerPool::PostTask(FROM_HERE, NewRunnableMethod(operation.get(), &BackgroundIO::Write, delete_buffer), @@ -225,8 +219,6 @@ void InFlightIO::WaitForPendingIO() { IOList::iterator it = io_list_.begin(); InvokeCallback(*it, true); } - // Unit tests can use different threads. - callback_thread_ = NULL; } // Runs on a worker thread. @@ -380,9 +372,8 @@ size_t File::GetLength() { // Static. void File::WaitForPendingIO(int* num_pending_io) { - // We may be running unit tests so we should allow InFlightIO to reset the - // message loop. - Singleton<InFlightIO>::get()->WaitForPendingIO(); + if (*num_pending_io) + Singleton<InFlightIO>::get()->WaitForPendingIO(); } } // namespace disk_cache diff --git a/net/disk_cache/in_flight_backend_io.cc b/net/disk_cache/in_flight_backend_io.cc deleted file mode 100644 index a505c6b..0000000 --- a/net/disk_cache/in_flight_backend_io.cc +++ /dev/null @@ -1,448 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/disk_cache/in_flight_backend_io.h" - -#include "base/compiler_specific.h" -#include "base/logging.h" -#include "net/base/net_errors.h" -#include "net/disk_cache/backend_impl.h" -#include "net/disk_cache/entry_impl.h" - -namespace disk_cache { - -BackendIO::BackendIO(InFlightIO* controller, BackendImpl* backend, - net::CompletionCallback* callback) - : BackgroundIO(controller), backend_(backend), callback_(callback), - operation_(OP_NONE), - ALLOW_THIS_IN_INITIALIZER_LIST( - my_callback_(this, &BackendIO::OnIOComplete)) { -} - -// Runs on the background thread. -void BackendIO::ExecuteOperation() { - if (IsEntryOperation()) - return ExecuteEntryOperation(); - - ExecuteBackendOperation(); -} - -// Runs on the background thread. -void BackendIO::OnIOComplete(int result) { - DCHECK(IsEntryOperation()); - DCHECK_NE(result, net::ERR_IO_PENDING); - result_ = result; - controller_->OnIOComplete(this); -} - -bool BackendIO::IsEntryOperation() { - return operation_ > OP_MAX_BACKEND; -} - -void BackendIO::ReleaseEntry() { - entry_ = NULL; -} - -void BackendIO::Init() { - operation_ = OP_INIT; -} - -void BackendIO::OpenEntry(const std::string& key, Entry** entry) { - operation_ = OP_OPEN; - key_ = key; - entry_ptr_ = entry; -} - -void BackendIO::CreateEntry(const std::string& key, Entry** entry) { - operation_ = OP_CREATE; - key_ = key; - entry_ptr_ = entry; -} - -void BackendIO::DoomEntry(const std::string& key) { - operation_ = OP_DOOM; - key_ = key; -} - -void BackendIO::DoomAllEntries() { - operation_ = OP_DOOM_ALL; -} - -void BackendIO::DoomEntriesBetween(const base::Time initial_time, - const base::Time end_time) { - operation_ = OP_DOOM_BETWEEN; - initial_time_ = initial_time; - end_time_ = end_time; -} - -void BackendIO::DoomEntriesSince(const base::Time initial_time) { - operation_ = OP_DOOM_SINCE; - initial_time_ = initial_time; -} - -void BackendIO::OpenNextEntry(void** iter, Entry** next_entry) { - operation_ = OP_OPEN_NEXT; - iter_ptr_ = iter; - entry_ptr_ = next_entry; -} - -void BackendIO::OpenPrevEntry(void** iter, Entry** prev_entry) { - operation_ = OP_OPEN_PREV; - iter_ptr_ = iter; - entry_ptr_ = prev_entry; -} - -void BackendIO::EndEnumeration(void* iterator) { - operation_ = OP_END_ENUMERATION; - iter_ = iterator; -} - -void BackendIO::CloseEntryImpl(EntryImpl* entry) { - operation_ = OP_CLOSE_ENTRY; - entry_ = entry; -} - -void BackendIO::DoomEntryImpl(EntryImpl* entry) { - operation_ = OP_DOOM_ENTRY; - entry_ = entry; -} - -void BackendIO::FlushQueue() { - operation_ = OP_FLUSH_QUEUE; -} - -void BackendIO::ReadData(EntryImpl* entry, int index, int offset, - net::IOBuffer* buf, int buf_len) { - operation_ = OP_READ; - entry_ = entry; - index_ = index; - offset_ = offset; - buf_ = buf; - buf_len_ = buf_len; -} - -void BackendIO::WriteData(EntryImpl* entry, int index, int offset, - net::IOBuffer* buf, int buf_len, bool truncate) { - operation_ = OP_WRITE; - entry_ = entry; - index_ = index; - offset_ = offset; - buf_ = buf; - buf_len_ = buf_len; - truncate_ = truncate; -} - -void BackendIO::ReadSparseData(EntryImpl* entry, int64 offset, - net::IOBuffer* buf, int buf_len) { - operation_ = OP_READ_SPARSE; - entry_ = entry; - offset64_ = offset; - buf_ = buf; - buf_len_ = buf_len; -} - -void BackendIO::WriteSparseData(EntryImpl* entry, int64 offset, - net::IOBuffer* buf, int buf_len) { - operation_ = OP_WRITE_SPARSE; - entry_ = entry; - offset64_ = offset; - buf_ = buf; - buf_len_ = buf_len; -} - -void BackendIO::GetAvailableRange(EntryImpl* entry, int64 offset, int len, - int64* start) { - operation_ = OP_GET_RANGE; - entry_ = entry; - offset64_ = offset; - buf_len_ = len; - start_ = start; -} - -void BackendIO::CancelSparseIO(EntryImpl* entry) { - operation_ = OP_CANCEL_IO; - entry_ = entry; -} - -void BackendIO::ReadyForSparseIO(EntryImpl* entry) { - operation_ = OP_IS_READY; - entry_ = entry; -} - -// Runs on the background thread. -void BackendIO::ExecuteBackendOperation() { - switch (operation_) { - case OP_INIT: - result_ = backend_->SyncInit(); - break; - case OP_OPEN: - result_ = backend_->SyncOpenEntry(key_, entry_ptr_); - break; - case OP_CREATE: - result_ = backend_->SyncCreateEntry(key_, entry_ptr_); - break; - case OP_DOOM: - result_ = backend_->SyncDoomEntry(key_); - break; - case OP_DOOM_ALL: - result_ = backend_->SyncDoomAllEntries(); - break; - case OP_DOOM_BETWEEN: - result_ = backend_->SyncDoomEntriesBetween(initial_time_, end_time_); - break; - case OP_DOOM_SINCE: - result_ = backend_->SyncDoomEntriesSince(initial_time_); - break; - case OP_OPEN_NEXT: - result_ = backend_->SyncOpenNextEntry(iter_ptr_, entry_ptr_); - break; - case OP_OPEN_PREV: - result_ = backend_->SyncOpenPrevEntry(iter_ptr_, entry_ptr_); - break; - case OP_END_ENUMERATION: - backend_->SyncEndEnumeration(iter_); - result_ = net::OK; - break; - case OP_CLOSE_ENTRY: - entry_->Release(); - result_ = net::OK; - break; - case OP_DOOM_ENTRY: - entry_->DoomImpl(); - result_ = net::OK; - break; - case OP_FLUSH_QUEUE: - result_ = net::OK; - break; - default: - NOTREACHED() << "Invalid Operation"; - result_ = net::ERR_UNEXPECTED; - } - DCHECK_NE(net::ERR_IO_PENDING, result_); - controller_->OnIOComplete(this); -} - -// Runs on the background thread. -void BackendIO::ExecuteEntryOperation() { - switch (operation_) { - case OP_READ: - result_ = entry_->ReadDataImpl(index_, offset_, buf_, buf_len_, - &my_callback_); - break; - case OP_WRITE: - result_ = entry_->WriteDataImpl(index_, offset_, buf_, buf_len_, - &my_callback_, truncate_); - break; - case OP_READ_SPARSE: - result_ = entry_->ReadSparseDataImpl(offset64_, buf_, buf_len_, - &my_callback_); - break; - case OP_WRITE_SPARSE: - result_ = entry_->WriteSparseDataImpl(offset64_, buf_, buf_len_, - &my_callback_); - break; - case OP_GET_RANGE: - result_ = entry_->GetAvailableRangeImpl(offset64_, buf_len_, start_); - break; - case OP_CANCEL_IO: - entry_->CancelSparseIOImpl(); - result_ = net::OK; - break; - case OP_IS_READY: - result_ = entry_->ReadyForSparseIOImpl(&my_callback_); - break; - default: - NOTREACHED() << "Invalid Operation"; - result_ = net::ERR_UNEXPECTED; - } - if (result_ != net::ERR_IO_PENDING) - controller_->OnIOComplete(this); -} - -// --------------------------------------------------------------------------- - -void InFlightBackendIO::Init(CompletionCallback* callback) { - scoped_refptr<BackendIO> operation = new BackendIO(this, backend_, callback); - operation->Init(); - QueueOperation(operation); -} - -void InFlightBackendIO::OpenEntry(const std::string& key, Entry** entry, - CompletionCallback* callback) { - scoped_refptr<BackendIO> operation = new BackendIO(this, backend_, callback); - operation->OpenEntry(key, entry); - QueueOperation(operation); -} - -void InFlightBackendIO::CreateEntry(const std::string& key, Entry** entry, - CompletionCallback* callback) { - scoped_refptr<BackendIO> operation = new BackendIO(this, backend_, callback); - operation->CreateEntry(key, entry); - QueueOperation(operation); -} - -void InFlightBackendIO::DoomEntry(const std::string& key, - CompletionCallback* callback) { - scoped_refptr<BackendIO> operation = new BackendIO(this, backend_, callback); - operation->DoomEntry(key); - QueueOperation(operation); -} - -void InFlightBackendIO::DoomAllEntries(CompletionCallback* callback) { - scoped_refptr<BackendIO> operation = new BackendIO(this, backend_, callback); - operation->DoomAllEntries(); - QueueOperation(operation); -} - -void InFlightBackendIO::DoomEntriesBetween(const base::Time initial_time, - const base::Time end_time, - CompletionCallback* callback) { - scoped_refptr<BackendIO> operation = new BackendIO(this, backend_, callback); - operation->DoomEntriesBetween(initial_time, end_time); - QueueOperation(operation); -} - -void InFlightBackendIO::DoomEntriesSince(const base::Time initial_time, - CompletionCallback* callback) { - scoped_refptr<BackendIO> operation = new BackendIO(this, backend_, callback); - operation->DoomEntriesSince(initial_time); - QueueOperation(operation); -} - -void InFlightBackendIO::OpenNextEntry(void** iter, Entry** next_entry, - CompletionCallback* callback) { - scoped_refptr<BackendIO> operation = new BackendIO(this, backend_, callback); - operation->OpenNextEntry(iter, next_entry); - QueueOperation(operation); -} - -void InFlightBackendIO::OpenPrevEntry(void** iter, Entry** prev_entry, - CompletionCallback* callback) { - scoped_refptr<BackendIO> operation = new BackendIO(this, backend_, callback); - operation->OpenPrevEntry(iter, prev_entry); - QueueOperation(operation); -} - -void InFlightBackendIO::EndEnumeration(void* iterator) { - scoped_refptr<BackendIO> operation = new BackendIO(this, backend_, NULL); - operation->EndEnumeration(iterator); - QueueOperation(operation); -} - -void InFlightBackendIO::CloseEntryImpl(EntryImpl* entry) { - scoped_refptr<BackendIO> operation = new BackendIO(this, backend_, NULL); - operation->CloseEntryImpl(entry); - QueueOperation(operation); -} - -void InFlightBackendIO::DoomEntryImpl(EntryImpl* entry) { - scoped_refptr<BackendIO> operation = new BackendIO(this, backend_, NULL); - operation->DoomEntryImpl(entry); - QueueOperation(operation); -} - -void InFlightBackendIO::FlushQueue(net::CompletionCallback* callback) { - scoped_refptr<BackendIO> operation = new BackendIO(this, backend_, callback); - operation->FlushQueue(); - QueueOperation(operation); -} - -void InFlightBackendIO::ReadData(EntryImpl* entry, int index, int offset, - net::IOBuffer* buf, int buf_len, - CompletionCallback* callback) { - scoped_refptr<BackendIO> operation = new BackendIO(this, backend_, callback); - operation->ReadData(entry, index, offset, buf, buf_len); - QueueOperation(operation); -} - -void InFlightBackendIO::WriteData(EntryImpl* entry, int index, int offset, - net::IOBuffer* buf, int buf_len, - bool truncate, - CompletionCallback* callback) { - scoped_refptr<BackendIO> operation = new BackendIO(this, backend_, callback); - operation->WriteData(entry, index, offset, buf, buf_len, truncate); - QueueOperation(operation); -} - -void InFlightBackendIO::ReadSparseData(EntryImpl* entry, int64 offset, - net::IOBuffer* buf, int buf_len, - CompletionCallback* callback) { - scoped_refptr<BackendIO> operation = new BackendIO(this, backend_, callback); - operation->ReadSparseData(entry, offset, buf, buf_len); - QueueOperation(operation); -} - -void InFlightBackendIO::WriteSparseData(EntryImpl* entry, int64 offset, - net::IOBuffer* buf, int buf_len, - CompletionCallback* callback) { - scoped_refptr<BackendIO> operation = new BackendIO(this, backend_, callback); - operation->WriteSparseData(entry, offset, buf, buf_len); - QueueOperation(operation); -} - -void InFlightBackendIO::GetAvailableRange(EntryImpl* entry, int64 offset, - int len, int64* start, - CompletionCallback* callback) { - scoped_refptr<BackendIO> operation = new BackendIO(this, backend_, callback); - operation->GetAvailableRange(entry, offset, len, start); - QueueOperation(operation); -} - -void InFlightBackendIO::CancelSparseIO(EntryImpl* entry) { - scoped_refptr<BackendIO> operation = new BackendIO(this, backend_, NULL); - operation->ReadyForSparseIO(entry); - QueueOperation(operation); -} - -void InFlightBackendIO::ReadyForSparseIO(EntryImpl* entry, - CompletionCallback* callback) { - scoped_refptr<BackendIO> operation = new BackendIO(this, backend_, callback); - operation->ReadyForSparseIO(entry); - QueueOperation(operation); -} - -void InFlightBackendIO::WaitForPendingIO() { - // We clear the list first so that we don't post more operations after this - // point. - pending_ops_.clear(); - InFlightIO::WaitForPendingIO(); -} - -void InFlightBackendIO::OnOperationComplete(BackgroundIO* operation, - bool cancel) { - BackendIO* op = static_cast<BackendIO*>(operation); - - if (!op->IsEntryOperation() && !pending_ops_.empty()) { - // Process the next request. Note that invoking the callback may result - // in the backend destruction (and with it this object), so we should deal - // with the next operation before invoking the callback. - scoped_refptr<BackendIO> next_op = pending_ops_.front(); - pending_ops_.pop_front(); - PostOperation(next_op); - } - - if (op->callback() && (!cancel || op->IsEntryOperation())) - op->callback()->Run(op->result()); - - if (cancel) - op->ReleaseEntry(); -} - -void InFlightBackendIO::QueueOperation(BackendIO* operation) { - if (operation->IsEntryOperation()) - return PostOperation(operation); - - if (pending_ops_.empty()) - return PostOperation(operation); - - pending_ops_.push_back(operation); -} - -void InFlightBackendIO::PostOperation(BackendIO* operation) { - background_thread_->PostTask(FROM_HERE, - NewRunnableMethod(operation, &BackendIO::ExecuteOperation)); - OnOperationPosted(operation); -} - -} // namespace diff --git a/net/disk_cache/in_flight_backend_io.h b/net/disk_cache/in_flight_backend_io.h deleted file mode 100644 index 4db2d11..0000000 --- a/net/disk_cache/in_flight_backend_io.h +++ /dev/null @@ -1,200 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_DISK_CACHE_IN_FLIGHT_BACKEND_IO_H_ -#define NET_DISK_CACHE_IN_FLIGHT_BACKEND_IO_H_ - -#include <string> - -#include "base/message_loop_proxy.h" -#include "net/base/completion_callback.h" -#include "net/base/io_buffer.h" -#include "net/disk_cache/entry_impl.h" -#include "net/disk_cache/in_flight_io.h" - -namespace disk_cache { - -class BackendImpl; - -// This class represents a single asynchronous disk cache IO operation while it -// is being bounced between threads. -class BackendIO : public BackgroundIO { - public: - BackendIO(InFlightIO* controller, BackendImpl* backend, - net::CompletionCallback* callback); - - // Runs the actual operation on the background thread. - void ExecuteOperation(); - - // Callback implementation. - void OnIOComplete(int result); - - // Returns true if this operation is directed to an entry (vs. the backend). - bool IsEntryOperation(); - - net::CompletionCallback* callback() { return callback_; } - - void ReleaseEntry(); - - // The operations we proxy: - void Init(); - void OpenEntry(const std::string& key, Entry** entry); - void CreateEntry(const std::string& key, Entry** entry); - void DoomEntry(const std::string& key); - void DoomAllEntries(); - void DoomEntriesBetween(const base::Time initial_time, - const base::Time end_time); - void DoomEntriesSince(const base::Time initial_time); - void OpenNextEntry(void** iter, Entry** next_entry); - void OpenPrevEntry(void** iter, Entry** prev_entry); - void EndEnumeration(void* iterator); - void CloseEntryImpl(EntryImpl* entry); - void DoomEntryImpl(EntryImpl* entry); - void FlushQueue(); // Dummy operation. - void ReadData(EntryImpl* entry, int index, int offset, net::IOBuffer* buf, - int buf_len); - void WriteData(EntryImpl* entry, int index, int offset, net::IOBuffer* buf, - int buf_len, bool truncate); - void ReadSparseData(EntryImpl* entry, int64 offset, net::IOBuffer* buf, - int buf_len); - void WriteSparseData(EntryImpl* entry, int64 offset, net::IOBuffer* buf, - int buf_len); - void GetAvailableRange(EntryImpl* entry, int64 offset, int len, int64* start); - void CancelSparseIO(EntryImpl* entry); - void ReadyForSparseIO(EntryImpl* entry); - - private: - // There are two types of operations to proxy: regular backend operations are - // queued so that we don't have more than one operation going on at the same - // time (for instance opening an entry and creating the same entry). On the - // other hand, operations targeted to a given entry can be long lived and - // support multiple simultaneous users (multiple reads or writes to the same - // entry), so they are not queued, just posted to the worker thread as they - // come. - enum Operation { - OP_NONE = 0, - OP_INIT, - OP_OPEN, - OP_CREATE, - OP_DOOM, - OP_DOOM_ALL, - OP_DOOM_BETWEEN, - OP_DOOM_SINCE, - OP_OPEN_NEXT, - OP_OPEN_PREV, - OP_END_ENUMERATION, - OP_CLOSE_ENTRY, - OP_DOOM_ENTRY, - OP_FLUSH_QUEUE, - OP_MAX_BACKEND, - OP_READ, - OP_WRITE, - OP_READ_SPARSE, - OP_WRITE_SPARSE, - OP_GET_RANGE, - OP_CANCEL_IO, - OP_IS_READY - }; - - ~BackendIO() {} - - void ExecuteBackendOperation(); - void ExecuteEntryOperation(); - - BackendImpl* backend_; - net::CompletionCallback* callback_; - Operation operation_; - net::CompletionCallbackImpl<BackendIO> my_callback_; - - // The arguments of all the operations we proxy: - std::string key_; - Entry** entry_ptr_; - base::Time initial_time_; - base::Time end_time_; - void** iter_ptr_; - void* iter_; - EntryImpl* entry_; - int index_; - int offset_; - scoped_refptr<net::IOBuffer> buf_; - int buf_len_; - bool truncate_; - int64 offset64_; - int64* start_; - - DISALLOW_COPY_AND_ASSIGN(BackendIO); -}; - -// The specialized controller that keeps track of current operations. -class InFlightBackendIO : public InFlightIO { - public: - InFlightBackendIO(BackendImpl* backend, - base::MessageLoopProxy* background_thread) - : backend_(backend), background_thread_(background_thread) {} - ~InFlightBackendIO() {} - - // The operations we proxy: - void Init(net::CompletionCallback* callback); - void OpenEntry(const std::string& key, Entry** entry, - net::CompletionCallback* callback); - void CreateEntry(const std::string& key, Entry** entry, - net::CompletionCallback* callback); - void DoomEntry(const std::string& key, net::CompletionCallback* callback); - void DoomAllEntries(net::CompletionCallback* callback); - void DoomEntriesBetween(const base::Time initial_time, - const base::Time end_time, - net::CompletionCallback* callback); - void DoomEntriesSince(const base::Time initial_time, - net::CompletionCallback* callback); - void OpenNextEntry(void** iter, Entry** next_entry, - net::CompletionCallback* callback); - void OpenPrevEntry(void** iter, Entry** prev_entry, - net::CompletionCallback* callback); - void EndEnumeration(void* iterator); - void CloseEntryImpl(EntryImpl* entry); - void DoomEntryImpl(EntryImpl* entry); - void FlushQueue(net::CompletionCallback* callback); - void ReadData(EntryImpl* entry, int index, int offset, net::IOBuffer* buf, - int buf_len, net::CompletionCallback* callback); - void WriteData(EntryImpl* entry, int index, int offset, net::IOBuffer* buf, - int buf_len, bool truncate, net::CompletionCallback* callback); - void ReadSparseData(EntryImpl* entry, int64 offset, net::IOBuffer* buf, - int buf_len, net::CompletionCallback* callback); - void WriteSparseData(EntryImpl* entry, int64 offset, net::IOBuffer* buf, - int buf_len, net::CompletionCallback* callback); - void GetAvailableRange(EntryImpl* entry, int64 offset, int len, int64* start, - net::CompletionCallback* callback); - void CancelSparseIO(EntryImpl* entry); - void ReadyForSparseIO(EntryImpl* entry, net::CompletionCallback* callback); - - // Blocks until all operations are cancelled or completed. - void WaitForPendingIO(); - - scoped_refptr<base::MessageLoopProxy> background_thread() { - return background_thread_; - } - - // Returns true if the current thread is the background thread. - bool BackgroundIsCurrentThread() { - return background_thread_->BelongsToCurrentThread(); - } - - protected: - virtual void OnOperationComplete(BackgroundIO* operation, bool cancel); - - private: - typedef std::list<scoped_refptr<BackendIO> > OperationList; - void QueueOperation(BackendIO* operation); - void PostOperation(BackendIO* operation); - - BackendImpl* backend_; - scoped_refptr<base::MessageLoopProxy> background_thread_; - OperationList pending_ops_; // The list of operations to be posted. - - DISALLOW_COPY_AND_ASSIGN(InFlightBackendIO); -}; - -} // namespace disk_cache - -#endif // NET_DISK_CACHE_IN_FLIGHT_BACKEND_IO_H_ diff --git a/net/disk_cache/in_flight_io.cc b/net/disk_cache/in_flight_io.cc deleted file mode 100644 index 09179ab..0000000 --- a/net/disk_cache/in_flight_io.cc +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright (c) 2006-2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/disk_cache/in_flight_io.h" - -#include "base/logging.h" - -namespace disk_cache { - -// Runs on the IO thread. -void BackgroundIO::OnIOSignalled() { - if (controller_) - controller_->InvokeCallback(this, false); -} - -void BackgroundIO::Cancel() { - DCHECK(controller_); - controller_ = NULL; -} - -// Runs on the background thread. -void BackgroundIO::NotifyController() { - controller_->OnIOComplete(this); -} - -// --------------------------------------------------------------------------- - -void InFlightIO::WaitForPendingIO() { - while (!io_list_.empty()) { - // Block the current thread until all pending IO completes. - IOList::iterator it = io_list_.begin(); - InvokeCallback(*it, true); - } -} - -// Runs on a background thread. -void InFlightIO::OnIOComplete(BackgroundIO* operation) { - callback_thread_->PostTask(FROM_HERE, - NewRunnableMethod(operation, - &BackgroundIO::OnIOSignalled)); - operation->io_completed()->Signal(); -} - -// Runs on the IO thread. -void InFlightIO::InvokeCallback(BackgroundIO* operation, bool cancel_task) { - operation->io_completed()->Wait(); - - if (cancel_task) - operation->Cancel(); - - // Make sure that we remove the operation from the list before invoking the - // callback (so that a subsequent cancel does not invoke the callback again). - DCHECK(io_list_.find(operation) != io_list_.end()); - io_list_.erase(operation); - OnOperationComplete(operation, cancel_task); -} - -// Runs on the IO thread. -void InFlightIO::OnOperationPosted(BackgroundIO* operation) { - io_list_.insert(operation); -} - -} // namespace disk_cache diff --git a/net/disk_cache/in_flight_io.h b/net/disk_cache/in_flight_io.h deleted file mode 100644 index 524d9ce..0000000 --- a/net/disk_cache/in_flight_io.h +++ /dev/null @@ -1,128 +0,0 @@ -// Copyright (c) 2006-2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_DISK_CACHE_IN_FLIGHT_IO_H_ -#define NET_DISK_CACHE_IN_FLIGHT_IO_H_ - -#include <set> - -#include "base/message_loop.h" -#include "base/waitable_event.h" - -namespace disk_cache { - -class InFlightIO; - -// This class represents a single asynchronous IO operation while it is being -// bounced between threads. -class BackgroundIO : public base::RefCountedThreadSafe<BackgroundIO> { - public: - // Other than the actual parameters for the IO operation (including the - // |callback| that must be notified at the end), we need the controller that - // is keeping track of all operations. When done, we notify the controller - // (we do NOT invoke the callback), in the worker thead that completed the - // operation. - explicit BackgroundIO(InFlightIO* controller) - : controller_(controller), result_(-1), io_completed_(true, false) {} - - // This method signals the controller that this operation is finished, in the - // original thread (presumably the IO-Thread). In practice, this is a - // RunableMethod that allows cancellation. - void OnIOSignalled(); - - // Allows the cancellation of the task to notify the controller (step number 8 - // in the diagram below). In practice, if the controller waits for the - // operation to finish it doesn't have to wait for the final task to be - // processed by the message loop so calling this method prevents its delivery. - // Note that this method is not intended to cancel the actual IO operation or - // to prevent the first notification to take place (OnIOComplete). - void Cancel(); - - int result() { return result_; } - - base::WaitableEvent* io_completed() { - return &io_completed_; - } - - protected: - virtual ~BackgroundIO() {} - - InFlightIO* controller_; // The controller that tracks all operations. - int result_; // Final operation result. - - private: - friend class base::RefCountedThreadSafe<BackgroundIO>; - - // Notifies the controller about the end of the operation, from the background - // thread. - void NotifyController(); - - // An event to signal when the operation completes. - base::WaitableEvent io_completed_; - - DISALLOW_COPY_AND_ASSIGN(BackgroundIO); -}; - -// This class keeps track of asynchronous IO operations. A single instance -// of this class is meant to be used to start an asynchronous operation (using -// PostXX, exposed by a derived class). This class will post the operation to a -// worker thread, hanlde the notification when the operation finishes and -// perform the callback on the same thread that was used to start the operation. -// -// The regular sequence of calls is: -// Thread_1 Worker_thread -// 1. DerivedInFlightIO::PostXX() -// 2. -> PostTask -> -// 3. InFlightIO::OnOperationPosted() -// 4. DerivedBackgroundIO::XX() -// 5. IO operation completes -// 6. InFlightIO::OnIOComplete() -// 7. <- PostTask <- -// 8. BackgroundIO::OnIOSignalled() -// 9. InFlightIO::InvokeCallback() -// 10. DerivedInFlightIO::OnOperationComplete() -// 11. invoke callback -// -// Shutdown is a special case that is handled though WaitForPendingIO() instead -// of just waiting for step 7. -class InFlightIO { - public: - InFlightIO() : callback_thread_(MessageLoop::current()) {} - virtual ~InFlightIO() {} - - // Blocks the current thread until all IO operations tracked by this object - // complete. - void WaitForPendingIO(); - - // Called on a background thread when |operation| completes. - void OnIOComplete(BackgroundIO* operation); - - // Invokes the users' completion callback at the end of the IO operation. - // |cancel_task| is true if the actual task posted to the thread is still - // queued (because we are inside WaitForPendingIO), and false if said task is - // the one performing the call. - void InvokeCallback(BackgroundIO* operation, bool cancel_task); - - protected: - // This method is called to signal the completion of the |operation|. |cancel| - // is true if the operation is being cancelled. This method is called on the - // thread that created this object. - virtual void OnOperationComplete(BackgroundIO* operation, bool cancel) = 0; - - // Signals this object that the derived class just posted the |operation| to - // be executed on a background thread. This method must be called on the same - // thread used to create this object. - void OnOperationPosted(BackgroundIO* operation); - - private: - typedef std::set<scoped_refptr<BackgroundIO> > IOList; - - IOList io_list_; // List of pending, in-flight io operations. - MessageLoop* callback_thread_; - DISALLOW_COPY_AND_ASSIGN(InFlightIO); -}; - -} // namespace disk_cache - -#endif // NET_DISK_CACHE_IN_FLIGHT_IO_H_ diff --git a/net/disk_cache/sparse_control.cc b/net/disk_cache/sparse_control.cc index 3726db9..2d9d3c1 100644 --- a/net/disk_cache/sparse_control.cc +++ b/net/disk_cache/sparse_control.cc @@ -126,7 +126,7 @@ void ChildrenDeleter::DeleteChildren() { return Release(); } std::string child_name = GenerateChildName(name_, signature_, child_id); - backend_->SyncDoomEntry(child_name); + backend_->DoomEntry(child_name); children_map_.Set(child_id, false); // Post a task to delete the next child. @@ -373,7 +373,7 @@ bool SparseControl::OpenChild() { CloseChild(); } - // See if we are tracking this child. + // Se if we are tracking this child. if (!ChildPresent()) return ContinueWithoutChild(key); @@ -418,7 +418,7 @@ void SparseControl::CloseChild() { NULL, false); if (rv != sizeof(child_data_)) DLOG(ERROR) << "Failed to save child data"; - child_->Release(); + child_->Close(); child_ = NULL; } @@ -430,8 +430,8 @@ std::string SparseControl::GenerateChildKey() { // We are deleting the child because something went wrong. bool SparseControl::KillChildAndContinue(const std::string& key, bool fatal) { SetChildBit(false); - child_->DoomImpl(); - child_->Release(); + child_->Doom(); + child_->Close(); child_ = NULL; if (fatal) { result_ = net::ERR_CACHE_READ_FAILURE; diff --git a/net/disk_cache/stress_cache.cc b/net/disk_cache/stress_cache.cc index b153659..db84fd8 100644 --- a/net/disk_cache/stress_cache.cc +++ b/net/disk_cache/stress_cache.cc @@ -140,6 +140,7 @@ void StressTheCache(int iteration) { if (!(i % 100)) printf("Entries: %d \r", i); + MessageLoop::current()->RunAllPending(); } } diff --git a/net/net.gyp b/net/net.gyp index 352edb2..b5cfd93 100644 --- a/net/net.gyp +++ b/net/net.gyp @@ -265,10 +265,6 @@ 'disk_cache/hash.cc', 'disk_cache/hash.h', 'disk_cache/histogram_macros.h', - 'disk_cache/in_flight_backend_io.cc', - 'disk_cache/in_flight_backend_io.h', - 'disk_cache/in_flight_io.cc', - 'disk_cache/in_flight_io.h', 'disk_cache/mapped_file.h', 'disk_cache/mapped_file_posix.cc', 'disk_cache/mapped_file_win.cc', diff --git a/net/tools/crash_cache/crash_cache.cc b/net/tools/crash_cache/crash_cache.cc index 1d11013..a26c873 100644 --- a/net/tools/crash_cache/crash_cache.cc +++ b/net/tools/crash_cache/crash_cache.cc @@ -118,14 +118,6 @@ bool CreateTargetFolder(const FilePath& path, RankCrashes action, return file_util::CreateDirectory(*full_path); } -// Makes sure that any pending task is processed. -void FlushQueue(disk_cache::Backend* cache) { - TestCompletionCallback cb; - int rv = - reinterpret_cast<disk_cache::BackendImpl*>(cache)->FlushQueueForTest(&cb); - cb.GetResult(rv); // Ignore the result; -} - // Generates the files for an empty and one item cache. int SimpleInsert(const FilePath& path, RankCrashes action, base::Thread* cache_thread) { @@ -150,7 +142,6 @@ int SimpleInsert(const FilePath& path, RankCrashes action, return GENERIC; entry->Close(); - FlushQueue(cache); DCHECK(action <= disk_cache::INSERT_ONE_3); g_rankings_crash = action; @@ -171,8 +162,7 @@ int SimpleRemove(const FilePath& path, RankCrashes action, TestCompletionCallback cb; disk_cache::Backend* cache; - // Use a simple LRU for eviction. - int rv = disk_cache::CreateCacheBackend(net::MEDIA_CACHE, path, 0, false, + int rv = disk_cache::CreateCacheBackend(net::DISK_CACHE, path, 0, false, cache_thread->message_loop_proxy(), &cache, &cb); if (cb.GetResult(rv) != net::OK || cache->GetEntryCount()) @@ -184,7 +174,6 @@ int SimpleRemove(const FilePath& path, RankCrashes action, return GENERIC; entry->Close(); - FlushQueue(cache); if (action >= disk_cache::REMOVE_TAIL_1) { rv = cache->CreateEntry("some other key", &entry, &cb); @@ -192,7 +181,6 @@ int SimpleRemove(const FilePath& path, RankCrashes action, return GENERIC; entry->Close(); - FlushQueue(cache); } rv = cache->OpenEntry(kCrashEntryName, &entry, &cb); @@ -202,7 +190,6 @@ int SimpleRemove(const FilePath& path, RankCrashes action, g_rankings_crash = action; entry->Doom(); entry->Close(); - FlushQueue(cache); return NOT_REACHED; } @@ -214,8 +201,7 @@ int HeadRemove(const FilePath& path, RankCrashes action, TestCompletionCallback cb; disk_cache::Backend* cache; - // Use a simple LRU for eviction. - int rv = disk_cache::CreateCacheBackend(net::MEDIA_CACHE, path, 0, false, + int rv = disk_cache::CreateCacheBackend(net::DISK_CACHE, path, 0, false, cache_thread->message_loop_proxy(), &cache, &cb); if (cb.GetResult(rv) != net::OK || cache->GetEntryCount()) @@ -227,13 +213,11 @@ int HeadRemove(const FilePath& path, RankCrashes action, return GENERIC; entry->Close(); - FlushQueue(cache); rv = cache->CreateEntry(kCrashEntryName, &entry, &cb); if (cb.GetResult(rv) != net::OK) return GENERIC; entry->Close(); - FlushQueue(cache); rv = cache->OpenEntry(kCrashEntryName, &entry, &cb); if (cb.GetResult(rv) != net::OK) @@ -242,7 +226,6 @@ int HeadRemove(const FilePath& path, RankCrashes action, g_rankings_crash = action; entry->Doom(); entry->Close(); - FlushQueue(cache); return NOT_REACHED; } @@ -258,14 +241,14 @@ int LoadOperations(const FilePath& path, RankCrashes action, if (!cache || !cache->SetMaxSize(0x100000)) return GENERIC; - TestCompletionCallback cb; - int rv = cache->Init(&cb); - if (cb.GetResult(rv) != net::OK || cache->GetEntryCount()) + if (!cache->Init() || cache->GetEntryCount()) return GENERIC; int seed = static_cast<int>(Time::Now().ToInternalValue()); srand(seed); + TestCompletionCallback cb; + int rv; disk_cache::Entry* entry; for (int i = 0; i < 100; i++) { std::string key = GenerateKey(true); @@ -273,13 +256,11 @@ int LoadOperations(const FilePath& path, RankCrashes action, if (cb.GetResult(rv) != net::OK) return GENERIC; entry->Close(); - FlushQueue(cache); if (50 == i && action >= disk_cache::REMOVE_LOAD_1) { rv = cache->CreateEntry(kCrashEntryName, &entry, &cb); if (cb.GetResult(rv) != net::OK) return GENERIC; entry->Close(); - FlushQueue(cache); } } @@ -299,7 +280,6 @@ int LoadOperations(const FilePath& path, RankCrashes action, entry->Doom(); entry->Close(); - FlushQueue(cache); return NOT_REACHED; } diff --git a/net/tools/dump_cache/upgrade.cc b/net/tools/dump_cache/upgrade.cc index 60099b2..5a3cd67 100644 --- a/net/tools/dump_cache/upgrade.cc +++ b/net/tools/dump_cache/upgrade.cc @@ -104,8 +104,7 @@ enum { RESULT_OK = 0, RESULT_UNKNOWN_COMMAND, RESULT_INVALID_PARAMETER, - RESULT_NAME_OVERFLOW, - RESULT_PENDING // This error code is NOT expected by the master process. + RESULT_NAME_OVERFLOW }; // ----------------------------------------------------------------------- @@ -576,7 +575,6 @@ class SlaveSM : public BaseSM { void DoGetNextEntry(); void DoGetPrevEntry(); int32 GetEntryFromList(); - void DoGetEntryComplete(int result); void DoCloseEntry(); void DoGetKey(); void DoGetUseTimes(); @@ -587,19 +585,16 @@ class SlaveSM : public BaseSM { void Fail(); void* iterator_; - Message msg_; // Used for DoReadDataComplete and DoGetEntryComplete. + Message msg_; // Only used for DoReadDataComplete. net::CompletionCallbackImpl<SlaveSM> read_callback_; - net::CompletionCallbackImpl<SlaveSM> next_callback_; scoped_ptr<disk_cache::BackendImpl> cache_; }; SlaveSM::SlaveSM(const std::wstring& path, HANDLE channel) : BaseSM(channel), iterator_(NULL), ALLOW_THIS_IN_INITIALIZER_LIST( - read_callback_(this, &SlaveSM::DoReadDataComplete)), - ALLOW_THIS_IN_INITIALIZER_LIST( - next_callback_(this, &SlaveSM::DoGetEntryComplete)) { + read_callback_(this, &SlaveSM::DoReadDataComplete)) { disk_cache::Backend* cache; TestCompletionCallback cb; int rv = disk_cache::CreateCacheBackend(net::DISK_CACHE, @@ -677,9 +672,6 @@ bool SlaveSM::DoInit() { DEBUGMSG("\t\t\tSlave DoInit\n"); DCHECK(state_ == SLAVE_INITIAL); state_ = SLAVE_WAITING; - if (!cache_.get()) - return false; - return ReceiveMsg(); } @@ -708,11 +700,6 @@ void SlaveSM::DoGetPrevEntry() { msg.result = RESULT_UNKNOWN_COMMAND; } else { msg.result = GetEntryFromList(); - if (msg.result == RESULT_PENDING) { - // We are not done yet. - msg_ = msg; - return; - } msg.long_arg1 = reinterpret_cast<int64>(entry_); } SendMsg(msg); @@ -728,31 +715,23 @@ int32 SlaveSM::GetEntryFromList() { if (entry_) entry_->Close(); - int rv; + bool ret; if (input_->msg.command == GET_NEXT_ENTRY) { - rv = cache_->OpenNextEntry(&iterator_, - reinterpret_cast<disk_cache::Entry**>(&entry_), - &next_callback_); + ret = cache_->OpenNextEntry(&iterator_, + reinterpret_cast<disk_cache::Entry**>(&entry_)); } else { DCHECK(input_->msg.command == GET_PREV_ENTRY); - rv = cache_->OpenPrevEntry(&iterator_, - reinterpret_cast<disk_cache::Entry**>(&entry_), - &next_callback_); + ret = cache_->OpenPrevEntry(&iterator_, + reinterpret_cast<disk_cache::Entry**>(&entry_)); } - DCHECK_EQ(net::ERR_IO_PENDING, rv); - return RESULT_PENDING; -} -void SlaveSM::DoGetEntryComplete(int result) { - DEBUGMSG("\t\t\tSlave DoGetEntryComplete\n"); - if (result != net::OK) { + if (!ret) entry_ = NULL; + + if (!entry_) DEBUGMSG("\t\t\tSlave end of list\n"); - } - msg_.result = RESULT_OK; - msg_.long_arg1 = reinterpret_cast<int64>(entry_); - SendMsg(msg_); + return RESULT_OK; } void SlaveSM::DoCloseEntry() { |