Index: net/disk_cache/backend_impl.cc |
=================================================================== |
--- net/disk_cache/backend_impl.cc (revision 51873) |
+++ net/disk_cache/backend_impl.cc (working copy) |
@@ -162,105 +162,6 @@ |
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 @@ |
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; |
+ } |
-int BackendImpl::SyncInit() { |
- if (Init()) |
+ *backend = NULL; |
+ delete cache; |
+ if (!force) |
+ return net::ERR_FAILED; |
+ |
+ 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 @@ |
// 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,36 +335,18 @@ |
return !disabled_; |
} |
-int BackendImpl::Init(CompletionCallback* callback) { |
- background_queue_.Init(callback); |
- return net::ERR_IO_PENDING; |
-} |
- |
BackendImpl::~BackendImpl() { |
- background_queue_.WaitForPendingIO(); |
+ Trace("Backend destructor"); |
+ if (!init_) |
+ return; |
- 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(); |
- } |
-} |
+ if (data_) |
+ data_->header.crash = 0; |
-void BackendImpl::CleanupCache() { |
- Trace("Backend Cleanup"); |
- if (init_) { |
- if (data_) |
- data_->header.crash = 0; |
+ timer_.Stop(); |
- timer_.Stop(); |
- File::WaitForPendingIO(&num_pending_io_); |
- DCHECK(!num_refs_); |
- } |
- factory_.RevokeAll(); |
- done_.Signal(); |
+ File::WaitForPendingIO(&num_pending_io_); |
+ DCHECK(!num_refs_); |
} |
// ------------------------------------------------------------------------ |
@@ -490,17 +393,18 @@ |
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) { |
@@ -580,21 +484,15 @@ |
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; |
@@ -604,24 +502,21 @@ |
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; |
@@ -643,14 +538,7 @@ |
} |
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; |
@@ -666,27 +554,27 @@ |
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; |
@@ -695,72 +583,59 @@ |
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; |
} |
@@ -1141,11 +1016,6 @@ |
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"; |
@@ -1166,22 +1036,10 @@ |
return CheckAllEntries(); |
} |
-int BackendImpl::SyncOpenPrevEntry(void** iter, Entry** prev_entry) { |
- *prev_entry = OpenPrevEntryImpl(iter); |
- return (*prev_entry) ? net::OK : net::ERR_FAILED; |
+bool BackendImpl::OpenPrevEntry(void** iter, Entry** prev_entry) { |
+ return OpenFollowingEntry(false, iter, prev_entry); |
} |
-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); |
-} |
- |
// ------------------------------------------------------------------------ |
// We just created a new file so we're going to write the header and set the |
@@ -1293,7 +1151,7 @@ |
// 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); |
} |
@@ -1443,11 +1301,14 @@ |
} |
// 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]; |
@@ -1467,7 +1328,7 @@ |
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. |
@@ -1503,19 +1364,18 @@ |
} |
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, |