diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-01-20 13:40:20 +0100 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-01-22 12:41:23 +0000 |
commit | 7961cea6d1041e3e454dae6a1da660b453efd238 (patch) | |
tree | c0eeb4a9ff9ba32986289c1653d9608e53ccb444 /chromium/net/disk_cache | |
parent | b7034d0803538058e5c9d904ef03cf5eab34f6ef (diff) | |
download | qtwebengine-chromium-7961cea6d1041e3e454dae6a1da660b453efd238.tar.gz |
BASELINE: Update Chromium to 78.0.3904.130
Change-Id: If185e0c0061b3437531c97c9c8c78f239352a68b
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/net/disk_cache')
33 files changed, 1189 insertions, 950 deletions
diff --git a/chromium/net/disk_cache/backend_cleanup_tracker_unittest.cc b/chromium/net/disk_cache/backend_cleanup_tracker_unittest.cc index 1ed8ecca40d..96013c179f9 100644 --- a/chromium/net/disk_cache/backend_cleanup_tracker_unittest.cc +++ b/chromium/net/disk_cache/backend_cleanup_tracker_unittest.cc @@ -8,7 +8,7 @@ #include "base/callback.h" #include "base/files/scoped_temp_dir.h" #include "base/memory/ref_counted.h" -#include "net/test/test_with_scoped_task_environment.h" +#include "net/test/test_with_task_environment.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -18,7 +18,7 @@ namespace { using testing::UnorderedElementsAre; using testing::IsEmpty; -class BackendCleanupTrackerTest : public net::TestWithScopedTaskEnvironment { +class BackendCleanupTrackerTest : public net::TestWithTaskEnvironment { protected: BackendCleanupTrackerTest() = default; diff --git a/chromium/net/disk_cache/backend_unittest.cc b/chromium/net/disk_cache/backend_unittest.cc index b7bba50b9bf..04246a726cb 100644 --- a/chromium/net/disk_cache/backend_unittest.cc +++ b/chromium/net/disk_cache/backend_unittest.cc @@ -56,6 +56,7 @@ #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +using disk_cache::EntryResult; using net::test::IsError; using net::test::IsOk; using testing::ByRef; @@ -103,12 +104,12 @@ std::unique_ptr<disk_cache::BackendImpl> CreateExistingEntryCache( if (cb.GetResult(rv) != net::OK) return std::unique_ptr<disk_cache::BackendImpl>(); - disk_cache::Entry* entry = nullptr; - rv = cache->CreateEntry(kExistingEntryKey, net::HIGHEST, &entry, - cb.callback()); - if (cb.GetResult(rv) != net::OK) + TestEntryResultCompletionCallback cb2; + EntryResult result = + cache->CreateEntry(kExistingEntryKey, net::HIGHEST, cb2.callback()); + result = cb2.GetResult(std::move(result)); + if (result.net_error() != net::OK) return std::unique_ptr<disk_cache::BackendImpl>(); - entry->Close(); return cache; } @@ -211,17 +212,21 @@ int DiskCacheBackendTest::GeneratePendingIO(net::TestCompletionCallback* cb) { return net::ERR_FAILED; } - disk_cache::Entry* entry; - int rv = - cache_->CreateEntry("some key", net::HIGHEST, &entry, cb->callback()); - if (cb->GetResult(rv) != net::OK) + TestEntryResultCompletionCallback create_cb; + EntryResult entry_result; + entry_result = + cache_->CreateEntry("some key", net::HIGHEST, create_cb.callback()); + entry_result = create_cb.GetResult(std::move(entry_result)); + if (entry_result.net_error() != net::OK) return net::ERR_CACHE_CREATE_FAILURE; + disk_cache::Entry* entry = entry_result.ReleaseEntry(); const int kSize = 25000; scoped_refptr<net::IOBuffer> buffer = base::MakeRefCounted<net::IOBuffer>(kSize); CacheTestFillBuffer(buffer->data(), kSize, false); + int rv = net::OK; 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 @@ -625,16 +630,18 @@ TEST_F(DiskCacheBackendTest, CreateBackendDoubleOpenEntry) { EXPECT_EQ(net::ERR_IO_PENDING, rv2); EXPECT_FALSE(cb2.have_result()); - disk_cache::Entry* entry = nullptr; - rv = cache->CreateEntry("key", net::HIGHEST, &entry, cb.callback()); - ASSERT_EQ(net::OK, cb.GetResult(rv)); + TestEntryResultCompletionCallback cb3; + EntryResult entry_result = + cache->CreateEntry("key", net::HIGHEST, cb3.callback()); + entry_result = cb3.GetResult(std::move(entry_result)); + ASSERT_EQ(net::OK, entry_result.net_error()); cache.reset(); // Still doesn't exist. EXPECT_FALSE(cb2.have_result()); - entry->Close(); + entry_result.ReleaseEntry()->Close(); // Now should exist. EXPECT_THAT(cb2.GetResult(rv2), IsOk()); @@ -663,9 +670,11 @@ TEST_F(DiskCacheBackendTest, CreateBackendPostCleanup) { EXPECT_THAT(cb.GetResult(rv), IsOk()); ASSERT_TRUE(cache.get()); - disk_cache::Entry* entry = nullptr; - rv = cache->CreateEntry("key", net::HIGHEST, &entry, cb.callback()); - ASSERT_EQ(net::OK, cb.GetResult(rv)); + TestEntryResultCompletionCallback cb2; + EntryResult result = cache->CreateEntry("key", net::HIGHEST, cb2.callback()); + result = cb2.GetResult(std::move(result)); + ASSERT_EQ(net::OK, result.net_error()); + disk_cache::Entry* entry = result.ReleaseEntry(); EXPECT_EQ(kBufSize, WriteData(entry, 0, 0, buffer.get(), kBufSize, false)); entry->Close(); @@ -709,9 +718,12 @@ TEST_F(DiskCacheBackendTest, SimpleCreateBackendRecoveryAppCache) { ASSERT_TRUE(cache.get()); // Create an entry. - disk_cache::Entry* entry = nullptr; - rv = cache->CreateEntry("key", net::HIGHEST, &entry, cb.callback()); - ASSERT_EQ(net::OK, cb.GetResult(rv)); + TestEntryResultCompletionCallback cb2; + disk_cache::EntryResult result = + cache->CreateEntry("key", net::HIGHEST, cb2.callback()); + result = cb2.GetResult(std::move(result)); + ASSERT_EQ(net::OK, result.net_error()); + disk_cache::Entry* entry = result.ReleaseEntry(); EXPECT_EQ(kBufSize, WriteData(entry, 0, 0, buffer.get(), kBufSize, false)); entry->Close(); @@ -966,7 +978,7 @@ TEST_F(DiskCacheBackendTest, MultipleInstancesWithPendingFileIO) { // Tests that we deal with background-thread pending operations. void DiskCacheBackendTest::BackendShutdownWithPendingIO(bool fast) { - net::TestCompletionCallback cb; + TestEntryResultCompletionCallback cb; { ASSERT_TRUE(CleanupCacheDir()); @@ -977,12 +989,12 @@ void DiskCacheBackendTest::BackendShutdownWithPendingIO(bool fast) { CreateBackend(flags); - disk_cache::Entry* entry; - int rv = - cache_->CreateEntry("some key", net::HIGHEST, &entry, cb.callback()); - ASSERT_THAT(cb.GetResult(rv), IsOk()); + EntryResult result = + cache_->CreateEntry("some key", net::HIGHEST, cb.callback()); + result = cb.GetResult(std::move(result)); + ASSERT_THAT(result.net_error(), IsOk()); - entry->Close(); + result.ReleaseEntry()->Close(); // The cache destructor will see one pending operation here. cache_.reset(); @@ -1008,7 +1020,7 @@ TEST_F(DiskCacheBackendTest, ShutdownWithPendingIO_Fast) { // Tests that we deal with create-type pending operations. void DiskCacheBackendTest::BackendShutdownWithPendingCreate(bool fast) { - net::TestCompletionCallback cb; + TestEntryResultCompletionCallback cb; { ASSERT_TRUE(CleanupCacheDir()); @@ -1017,10 +1029,9 @@ void DiskCacheBackendTest::BackendShutdownWithPendingCreate(bool fast) { fast ? disk_cache::kNone : disk_cache::kNoRandom; CreateBackend(flags); - disk_cache::Entry* entry; - int rv = - cache_->CreateEntry("some key", net::HIGHEST, &entry, cb.callback()); - ASSERT_THAT(rv, IsError(net::ERR_IO_PENDING)); + EntryResult result = + cache_->CreateEntry("some key", net::HIGHEST, cb.callback()); + ASSERT_THAT(result.net_error(), IsError(net::ERR_IO_PENDING)); cache_.reset(); EXPECT_FALSE(cb.have_result()); @@ -1052,14 +1063,14 @@ void DiskCacheBackendTest::BackendShutdownWithPendingDoom() { disk_cache::BackendFlags flags = disk_cache::kNoRandom; CreateBackend(flags); - disk_cache::Entry* entry; - int rv = - cache_->CreateEntry("some key", net::HIGHEST, &entry, cb.callback()); - ASSERT_THAT(cb.GetResult(rv), IsOk()); - entry->Close(); - entry = nullptr; + TestEntryResultCompletionCallback cb2; + EntryResult result = + cache_->CreateEntry("some key", net::HIGHEST, cb2.callback()); + result = cb2.GetResult(std::move(result)); + ASSERT_THAT(result.net_error(), IsOk()); + result.ReleaseEntry()->Close(); - rv = cache_->DoomEntry("some key", net::HIGHEST, cb.callback()); + int rv = cache_->DoomEntry("some key", net::HIGHEST, cb.callback()); ASSERT_THAT(rv, IsError(net::ERR_IO_PENDING)); cache_.reset(); @@ -2546,12 +2557,11 @@ TEST_F(DiskCacheTest, SimpleCacheControlRestart) { ASSERT_THAT(cb.GetResult(rv), IsOk()); EXPECT_EQ(1, cache->GetEntryCount()); - disk_cache::Entry* entry = nullptr; - rv = cache->OpenEntry(kExistingEntryKey, net::HIGHEST, &entry, - cb.callback()); - ASSERT_THAT(cb.GetResult(rv), IsOk()); - EXPECT_NE(nullptr, entry); - entry->Close(); + TestEntryResultCompletionCallback cb2; + EntryResult result = + cache->OpenEntry(kExistingEntryKey, net::HIGHEST, cb2.callback()); + result = cb2.GetResult(std::move(result)); + result.ReleaseEntry()->Close(); } } @@ -2587,12 +2597,12 @@ TEST_F(DiskCacheTest, SimpleCacheControlLeave) { ASSERT_THAT(cb.GetResult(rv), IsOk()); EXPECT_EQ(1, cache->GetEntryCount()); - disk_cache::Entry* entry = nullptr; - rv = cache->OpenEntry(kExistingEntryKey, net::HIGHEST, &entry, - cb.callback()); - ASSERT_THAT(cb.GetResult(rv), IsOk()); - EXPECT_NE(nullptr, entry); - entry->Close(); + TestEntryResultCompletionCallback cb2; + EntryResult result = + cache->OpenEntry(kExistingEntryKey, net::HIGHEST, cb2.callback()); + result = cb2.GetResult(std::move(result)); + ASSERT_THAT(result.net_error(), IsOk()); + result.ReleaseEntry()->Close(); } } @@ -3720,11 +3730,13 @@ TEST_F(DiskCacheTest, MultipleInstances) { ASSERT_TRUE(cache[0].get() != nullptr && cache[1].get() != nullptr); std::string key("the first key"); - disk_cache::Entry* entry; for (int i = 0; i < kNumberOfCaches; i++) { - rv = cache[i]->CreateEntry(key, net::HIGHEST, &entry, cb.callback()); - ASSERT_THAT(cb.GetResult(rv), IsOk()); - entry->Close(); + TestEntryResultCompletionCallback cb2; + EntryResult result = + cache[i]->CreateEntry(key, net::HIGHEST, cb2.callback()); + result = cb2.GetResult(std::move(result)); + ASSERT_THAT(result.net_error(), IsOk()); + result.ReleaseEntry()->Close(); } } @@ -4273,8 +4285,8 @@ TEST_F(DiskCacheBackendTest, DISABLED_SimpleCachePrioritizedEntryOrder) { // priority order. disk_cache::SimpleBackendImpl* simple_cache = static_cast<disk_cache::SimpleBackendImpl*>(cache_.get()); - auto task_runner = base::CreateSequencedTaskRunnerWithTraits( - {base::TaskPriority::USER_VISIBLE, base::MayBlock()}); + auto task_runner = base::CreateSequencedTaskRunner( + {base::ThreadPool(), base::TaskPriority::USER_VISIBLE, base::MayBlock()}); simple_cache->SetWorkerPoolForTesting(task_runner); // Create three entries. Priority order is 3, 1, 2 because 3 has the highest @@ -4365,8 +4377,8 @@ TEST_F(DiskCacheBackendTest, SimpleCacheFIFOEntryOrder) { // priority order. disk_cache::SimpleBackendImpl* simple_cache = static_cast<disk_cache::SimpleBackendImpl*>(cache_.get()); - auto task_runner = base::CreateSequencedTaskRunnerWithTraits( - {base::TaskPriority::USER_VISIBLE, base::MayBlock()}); + auto task_runner = base::CreateSequencedTaskRunner( + {base::ThreadPool(), base::TaskPriority::USER_VISIBLE, base::MayBlock()}); simple_cache->SetWorkerPoolForTesting(task_runner); // Create three entries. If their priority was honored, they'd run in order @@ -4791,57 +4803,59 @@ void DiskCacheBackendTest::BackendOpenOrCreateEntry() { } // Test that new key is created. - disk_cache::EntryWithOpened es1; - ASSERT_THAT(OpenOrCreateEntry("first", &es1), IsOk()); - ASSERT_TRUE(nullptr != es1.entry); - ASSERT_FALSE(es1.opened); + disk_cache::EntryResult es1 = OpenOrCreateEntry("first"); + ASSERT_THAT(es1.net_error(), IsOk()); + ASSERT_FALSE(es1.opened()); + disk_cache::Entry* e1 = es1.ReleaseEntry(); + ASSERT_TRUE(nullptr != e1); // Test that existing key is opened and its entry matches. - disk_cache::EntryWithOpened es2; - ASSERT_THAT(OpenOrCreateEntry("first", &es2), IsOk()); - ASSERT_TRUE(nullptr != es2.entry); - ASSERT_TRUE(es2.opened); - ASSERT_EQ(es1.entry, es2.entry); + disk_cache::EntryResult es2 = OpenOrCreateEntry("first"); + ASSERT_THAT(es2.net_error(), IsOk()); + ASSERT_TRUE(es2.opened()); + disk_cache::Entry* e2 = es2.ReleaseEntry(); + ASSERT_TRUE(nullptr != e2); + ASSERT_EQ(e1, e2); // Test that different keys' entries are not the same. - disk_cache::EntryWithOpened es3; - ASSERT_THAT(OpenOrCreateEntry("second", &es3), IsOk()); - ASSERT_TRUE(nullptr != es2.entry); - ASSERT_FALSE(es3.opened); - ASSERT_NE(es3.entry, es1.entry); + disk_cache::EntryResult es3 = OpenOrCreateEntry("second"); + ASSERT_THAT(es3.net_error(), IsOk()); + ASSERT_FALSE(es3.opened()); + disk_cache::Entry* e3 = es3.ReleaseEntry(); + ASSERT_TRUE(nullptr != e3); + ASSERT_NE(e3, e1); // Test that a new entry can be created with the same key as a doomed entry. - es3.entry->Doom(); - disk_cache::EntryWithOpened es4; - ASSERT_THAT(OpenOrCreateEntry("second", &es4), IsOk()); - ASSERT_TRUE(nullptr != es4.entry); - ASSERT_FALSE(es4.opened); - ASSERT_NE(es4.entry, es3.entry); + e3->Doom(); + disk_cache::EntryResult es4 = OpenOrCreateEntry("second"); + ASSERT_THAT(es4.net_error(), IsOk()); + ASSERT_FALSE(es4.opened()); + disk_cache::Entry* e4 = es4.ReleaseEntry(); + ASSERT_TRUE(nullptr != e4); + ASSERT_NE(e4, e3); // Verify the expected number of entries ASSERT_EQ(2, cache_->GetEntryCount()); - es1.entry->Close(); - es2.entry->Close(); - es3.entry->Close(); - es4.entry->Close(); + e1->Close(); + e2->Close(); + e3->Close(); + e4->Close(); - // Test proper cancellation of writes to EntryWithOpened. In-memory cache + // Test proper cancellation of callback. In-memory cache // is always synchronous, so this isn't' meaningful for it. if (!memory_only_) { - auto heap_entry_with_open = std::make_unique<disk_cache::EntryWithOpened>(); - net::TestCompletionCallback callback; + TestEntryResultCompletionCallback callback; // Using "first" here: // 1) It's an existing entry, so SimpleCache can't cheat with an optimistic // create. // 2) "second"'s creation is a cheated post-doom create one, which also // makes testing trickier. - int rv = cache_->OpenOrCreateEntry( - "first", net::HIGHEST, heap_entry_with_open.get(), callback.callback()); - ASSERT_EQ(net::ERR_IO_PENDING, rv); + EntryResult result = + cache_->OpenOrCreateEntry("first", net::HIGHEST, callback.callback()); + ASSERT_EQ(net::ERR_IO_PENDING, result.net_error()); cache_ = nullptr; - heap_entry_with_open = nullptr; // Callback is supposed to be cancelled, so have to flush everything // to check for any trouble. @@ -4870,8 +4884,8 @@ void DiskCacheBackendTest::BackendDeadOpenNextEntry() { std::unique_ptr<disk_cache::Backend::Iterator> iter = cache_->CreateIterator(); cache_.reset(); - disk_cache::Entry* out = nullptr; - ASSERT_EQ(net::ERR_FAILED, iter->OpenNextEntry(&out, base::DoNothing())); + EntryResult result = iter->OpenNextEntry(base::DoNothing()); + ASSERT_EQ(net::ERR_FAILED, result.net_error()); } TEST_F(DiskCacheBackendTest, BlockFileBackendDeadOpenNextEntry) { @@ -4900,29 +4914,25 @@ void DiskCacheBackendTest::BackendIteratorConcurrentDoom() { disk_cache::Entry* entry3 = nullptr; EXPECT_EQ(net::OK, OpenEntry("Key0", &entry3)); - net::TestCompletionCallback cb; - disk_cache::Entry* entry_iter = nullptr; - int rv = iter->OpenNextEntry(&entry_iter, cb.callback()); - EXPECT_EQ(net::OK, cb.GetResult(rv)); + TestEntryResultCompletionCallback cb; + EntryResult result_iter = iter->OpenNextEntry(cb.callback()); + result_iter = cb.GetResult(std::move(result_iter)); + EXPECT_EQ(net::OK, result_iter.net_error()); net::TestCompletionCallback cb_doom; int rv_doom = cache_->DoomAllEntries(cb_doom.callback()); EXPECT_EQ(net::OK, cb_doom.GetResult(rv_doom)); - net::TestCompletionCallback cb2; - disk_cache::Entry* entry_iter2 = nullptr; - int rv2 = iter->OpenNextEntry(&entry_iter2, cb2.callback()); + TestEntryResultCompletionCallback cb2; + EntryResult result_iter2 = iter->OpenNextEntry(cb2.callback()); + result_iter2 = cb2.GetResult(std::move(result_iter2)); - rv2 = cb2.GetResult(rv2); - EXPECT_TRUE(rv2 == net::ERR_FAILED || rv2 == net::OK); + EXPECT_TRUE(result_iter2.net_error() == net::ERR_FAILED || + result_iter2.net_error() == net::OK); entry1->Close(); entry2->Close(); entry3->Close(); - if (entry_iter) - entry_iter->Close(); - if (entry_iter2) - entry_iter2->Close(); } TEST_F(DiskCacheBackendTest, BlockFileIteratorConcurrentDoom) { @@ -4996,22 +5006,18 @@ TEST_F(DiskCacheBackendTest, SimpleOwnershipTransferBackendDestroyRace) { explicit CleanupContext(bool* ran_ptr) : ran_ptr(ran_ptr) {} ~CleanupContext() { *ran_ptr = true; - // A realistic CleanupContext would call Close on non-null, - // which would be a double-Close when what this is testing was broken. - // Here, just check for expected case. - EXPECT_EQ(owned_entry, nullptr); } bool* ran_ptr; - disk_cache::Entry* owned_entry = nullptr; }; const char kKey[] = "skeleton"; - // See https://crbug.com/946349 - // This tests that if the SimpleBackendImpl is destroyed after SimpleEntryImpl - // decides to return an entry to the caller, but before the callback is run - // that no entry is leaked, and that the out pointer is not written to. + // This test was for a fix for see https://crbug.com/946349, but the mechanics + // of that failure became impossible after a follow up API refactor. Still, + // the timing is strange, and warrant coverage; in particular this tests what + // happen if the SimpleBackendImpl is destroyed after SimpleEntryImpl + // decides to return an entry to the caller, but before the callback is run. SetSimpleCacheMode(); InitCache(); @@ -5022,23 +5028,26 @@ TEST_F(DiskCacheBackendTest, SimpleOwnershipTransferBackendDestroyRace) { bool cleanup_context_ran = false; auto cleanup_context = std::make_unique<CleanupContext>(&cleanup_context_ran); - disk_cache::Entry** dest = &cleanup_context->owned_entry; // The OpenEntry code below will find a pre-existing entry in a READY state, // so it will immediately post a task to return a result. Destroying the // backend before running the event loop again will run that callback in the // dead-backend state, while OpenEntry completion was still with it alive. - EXPECT_EQ(net::ERR_IO_PENDING, - cache_->OpenEntry( - kKey, net::HIGHEST, dest, - base::BindOnce( - [](std::unique_ptr<CleanupContext>, int net_status) { - // The callback is here for ownership of CleanupContext, - // and it shouldn't get invoked in this test. - ADD_FAILURE() << "This should not actually run"; - }, - std::move(cleanup_context)))); + EntryResult result = cache_->OpenEntry( + kKey, net::HIGHEST, + base::BindOnce( + [](std::unique_ptr<CleanupContext>, EntryResult result) { + // The callback is here for ownership of CleanupContext, + // and it shouldn't get invoked in this test. Normal + // one would transfer result.entry to CleanupContext. + ADD_FAILURE() << "This should not actually run"; + + // ... but if it ran, it also shouldn't see the pointer. + EXPECT_EQ(nullptr, result.ReleaseEntry()); + }, + std::move(cleanup_context))); + EXPECT_EQ(net::ERR_IO_PENDING, result.net_error()); cache_.reset(); // Give CleanupContext a chance to do its thing. diff --git a/chromium/net/disk_cache/blockfile/backend_impl.cc b/chromium/net/disk_cache/blockfile/backend_impl.cc index b231b7caa42..365080f7ebe 100644 --- a/chromium/net/disk_cache/blockfile/backend_impl.cc +++ b/chromium/net/disk_cache/blockfile/backend_impl.cc @@ -15,7 +15,7 @@ #include "base/hash/hash.h" #include "base/lazy_instance.h" #include "base/location.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_type.h" #include "base/metrics/field_trial.h" #include "base/metrics/histogram.h" #include "base/rand_util.h" @@ -118,7 +118,7 @@ class CacheThread : public base::Thread { public: CacheThread() : base::Thread("CacheThread_BlockFile") { CHECK( - StartWithOptions(base::Thread::Options(base::MessageLoop::TYPE_IO, 0))); + StartWithOptions(base::Thread::Options(base::MessagePumpType::IO, 0))); } ~CacheThread() override { @@ -1244,31 +1244,29 @@ int32_t BackendImpl::GetEntryCount() const { return not_deleted; } -net::Error BackendImpl::OpenOrCreateEntry(const std::string& key, - net::RequestPriority request_priority, - EntryWithOpened* entry_struct, - CompletionOnceCallback callback) { +EntryResult BackendImpl::OpenOrCreateEntry( + const std::string& key, + net::RequestPriority request_priority, + EntryResultCallback callback) { DCHECK(!callback.is_null()); - background_queue_.OpenOrCreateEntry(key, entry_struct, std::move(callback)); - return net::ERR_IO_PENDING; + background_queue_.OpenOrCreateEntry(key, std::move(callback)); + return EntryResult::MakeError(net::ERR_IO_PENDING); } -net::Error BackendImpl::OpenEntry(const std::string& key, - net::RequestPriority request_priority, - Entry** entry, - CompletionOnceCallback callback) { +EntryResult BackendImpl::OpenEntry(const std::string& key, + net::RequestPriority request_priority, + EntryResultCallback callback) { DCHECK(!callback.is_null()); - background_queue_.OpenEntry(key, entry, std::move(callback)); - return net::ERR_IO_PENDING; + background_queue_.OpenEntry(key, std::move(callback)); + return EntryResult::MakeError(net::ERR_IO_PENDING); } -net::Error BackendImpl::CreateEntry(const std::string& key, - net::RequestPriority request_priority, - Entry** entry, - CompletionOnceCallback callback) { +EntryResult BackendImpl::CreateEntry(const std::string& key, + net::RequestPriority request_priority, + EntryResultCallback callback) { DCHECK(!callback.is_null()); - background_queue_.CreateEntry(key, entry, std::move(callback)); - return net::ERR_IO_PENDING; + background_queue_.CreateEntry(key, std::move(callback)); + return EntryResult::MakeError(net::ERR_IO_PENDING); } net::Error BackendImpl::DoomEntry(const std::string& key, @@ -1324,13 +1322,11 @@ class BackendImpl::IteratorImpl : public Backend::Iterator { background_queue_->EndEnumeration(std::move(iterator_)); } - net::Error OpenNextEntry(Entry** next_entry, - net::CompletionOnceCallback callback) override { + EntryResult OpenNextEntry(EntryResultCallback callback) override { if (!background_queue_) - return net::ERR_FAILED; - background_queue_->OpenNextEntry(iterator_.get(), next_entry, - std::move(callback)); - return net::ERR_IO_PENDING; + return EntryResult::MakeError(net::ERR_FAILED); + background_queue_->OpenNextEntry(iterator_.get(), std::move(callback)); + return EntryResult::MakeError(net::ERR_IO_PENDING); } private: diff --git a/chromium/net/disk_cache/blockfile/backend_impl.h b/chromium/net/disk_cache/blockfile/backend_impl.h index 16a492ba739..a48da439ef3 100644 --- a/chromium/net/disk_cache/blockfile/backend_impl.h +++ b/chromium/net/disk_cache/blockfile/backend_impl.h @@ -271,18 +271,15 @@ class NET_EXPORT_PRIVATE BackendImpl : public Backend { // Backend implementation. int32_t GetEntryCount() const override; - net::Error OpenOrCreateEntry(const std::string& key, - net::RequestPriority request_priority, - EntryWithOpened* entry_struct, - CompletionOnceCallback callback) override; - net::Error OpenEntry(const std::string& key, - net::RequestPriority request_priority, - Entry** entry, - CompletionOnceCallback callback) override; - net::Error CreateEntry(const std::string& key, - net::RequestPriority request_priority, - Entry** entry, - CompletionOnceCallback callback) override; + EntryResult OpenOrCreateEntry(const std::string& key, + net::RequestPriority request_priority, + EntryResultCallback callback) override; + EntryResult OpenEntry(const std::string& key, + net::RequestPriority request_priority, + EntryResultCallback callback) override; + EntryResult CreateEntry(const std::string& key, + net::RequestPriority request_priority, + EntryResultCallback callback) override; net::Error DoomEntry(const std::string& key, net::RequestPriority priority, CompletionOnceCallback callback) override; diff --git a/chromium/net/disk_cache/blockfile/entry_impl.cc b/chromium/net/disk_cache/blockfile/entry_impl.cc index 8e5fc81b4f8..054f8d3fcc8 100644 --- a/chromium/net/disk_cache/blockfile/entry_impl.cc +++ b/chromium/net/disk_cache/blockfile/entry_impl.cc @@ -458,7 +458,7 @@ bool EntryImpl::CreateEntry(Addr node_address, 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() + 1, offset)) { DeleteData(address, kKeyFileIndex); return false; } @@ -789,7 +789,7 @@ std::string EntryImpl::GetKey() const { CacheEntryBlock* entry = const_cast<CacheEntryBlock*>(&entry_); int key_len = entry->Data()->key_len; if (key_len <= kMaxInternalKeyLength) - return std::string(entry->Data()->key); + return std::string(entry->Data()->key, key_len); // We keep a copy of the key so that we can always return it, even if the // backend is disabled. @@ -808,12 +808,18 @@ std::string EntryImpl::GetKey() const { if (!key_file) return std::string(); - ++key_len; // We store a trailing \0 on disk that we read back below. + ++key_len; // We store a trailing \0 on disk. if (!offset && key_file->GetLength() != static_cast<size_t>(key_len)) return std::string(); - if (!key_file->Read(base::WriteInto(&key_, key_len), key_len, offset)) + // WriteInto will ensure that key_.length() == key_len - 1, and so + // key_.c_str()[key_len] will be '\0'. Taking advantage of this, do not + // attempt read up to the expected on-disk '\0' --- which would be |key_len| + // bytes total --- as if due to a corrupt file it isn't |key_| would get its + // internal nul messed up. + if (!key_file->Read(base::WriteInto(&key_, key_len), key_len - 1, offset)) key_.clear(); + DCHECK_LE(strlen(key_.data()), static_cast<size_t>(key_len)); return key_; } diff --git a/chromium/net/disk_cache/blockfile/file_ios.cc b/chromium/net/disk_cache/blockfile/file_ios.cc index 914899b00ea..3576a84e4cd 100644 --- a/chromium/net/disk_cache/blockfile/file_ios.cc +++ b/chromium/net/disk_cache/blockfile/file_ios.cc @@ -121,10 +121,10 @@ void FileInFlightIO::PostRead(disk_cache::File *file, void* buf, size_t buf_len, new FileBackgroundIO(file, buf, buf_len, offset, callback, this)); file->AddRef(); // Balanced on OnOperationComplete() - base::PostTaskWithTraits( - FROM_HERE, - {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, - base::BindOnce(&FileBackgroundIO::Read, operation.get())); + base::PostTask(FROM_HERE, + {base::ThreadPool(), base::MayBlock(), + base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, + base::BindOnce(&FileBackgroundIO::Read, operation.get())); OnOperationPosted(operation.get()); } @@ -135,10 +135,10 @@ void FileInFlightIO::PostWrite(disk_cache::File* file, const void* buf, new FileBackgroundIO(file, buf, buf_len, offset, callback, this)); file->AddRef(); // Balanced on OnOperationComplete() - base::PostTaskWithTraits( - FROM_HERE, - {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, - base::BindOnce(&FileBackgroundIO::Write, operation.get())); + base::PostTask(FROM_HERE, + {base::ThreadPool(), base::MayBlock(), + base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, + base::BindOnce(&FileBackgroundIO::Write, operation.get())); OnOperationPosted(operation.get()); } diff --git a/chromium/net/disk_cache/blockfile/file_posix.cc b/chromium/net/disk_cache/blockfile/file_posix.cc index e6c045b199e..56e9f84d576 100644 --- a/chromium/net/disk_cache/blockfile/file_posix.cc +++ b/chromium/net/disk_cache/blockfile/file_posix.cc @@ -13,7 +13,7 @@ #include "base/logging.h" #include "base/run_loop.h" #include "base/task/post_task.h" -#include "base/task/thread_pool/thread_pool.h" +#include "base/task/thread_pool/thread_pool_instance.h" #include "net/base/net_errors.h" #include "net/disk_cache/disk_cache.h" @@ -73,8 +73,9 @@ bool File::Read(void* buffer, size_t buffer_len, size_t offset, return false; } - base::PostTaskWithTraitsAndReplyWithResult( - FROM_HERE, {base::TaskPriority::USER_BLOCKING, base::MayBlock()}, + base::PostTaskAndReplyWithResult( + FROM_HERE, + {base::ThreadPool(), base::TaskPriority::USER_BLOCKING, base::MayBlock()}, base::BindOnce(&File::DoRead, base::Unretained(this), buffer, buffer_len, offset), base::BindOnce(&File::OnOperationComplete, this, callback)); @@ -101,8 +102,9 @@ bool File::Write(const void* buffer, size_t buffer_len, size_t offset, // finish before it reads from the network again. // TODO(fdoray): Consider removing this from the critical path of network // requests and changing the priority to BACKGROUND. - base::PostTaskWithTraitsAndReplyWithResult( - FROM_HERE, {base::TaskPriority::USER_BLOCKING, base::MayBlock()}, + base::PostTaskAndReplyWithResult( + FROM_HERE, + {base::ThreadPool(), base::TaskPriority::USER_BLOCKING, base::MayBlock()}, base::BindOnce(&File::DoWrite, base::Unretained(this), buffer, buffer_len, offset), base::BindOnce(&File::OnOperationComplete, this, callback)); diff --git a/chromium/net/disk_cache/blockfile/in_flight_backend_io.cc b/chromium/net/disk_cache/blockfile/in_flight_backend_io.cc index c4922955b42..b7c901bceb5 100644 --- a/chromium/net/disk_cache/blockfile/in_flight_backend_io.cc +++ b/chromium/net/disk_cache/blockfile/in_flight_backend_io.cc @@ -37,12 +37,23 @@ EntryImpl* LeakEntryImpl(scoped_refptr<EntryImpl> entry) { BackendIO::BackendIO(InFlightIO* controller, BackendImpl* backend, net::CompletionOnceCallback callback) + : BackendIO(controller, backend) { + callback_ = std::move(callback); +} + +BackendIO::BackendIO(InFlightIO* controller, + BackendImpl* backend, + EntryResultCallback callback) + : BackendIO(controller, backend) { + entry_result_callback_ = std::move(callback); +} + +BackendIO::BackendIO(InFlightIO* controller, BackendImpl* backend) : BackgroundIO(controller), backend_(backend), - callback_(std::move(callback)), operation_(OP_NONE), - entry_ptr_(nullptr), - entry_with_opened_ptr_(nullptr), + out_entry_(nullptr), + out_entry_opened_(false), iterator_(nullptr), entry_(nullptr), index_(0), @@ -76,16 +87,10 @@ void BackendIO::OnDone(bool cancel) { CACHE_UMA(TIMES, "TotalIOTime", 0, ElapsedTime()); } - if (!ReturnsEntry() && !ReturnsEntryWithOpened()) - return; - - EntryImpl* working_entry = - ReturnsEntry() ? static_cast<EntryImpl*>(*entry_ptr_) - : static_cast<EntryImpl*>(entry_with_opened_ptr_->entry); - if (result() == net::OK) { - working_entry->OnEntryCreated(backend_); + if (ReturnsEntry() && result_ == net::OK) { + static_cast<EntryImpl*>(out_entry_)->OnEntryCreated(backend_); if (cancel) - working_entry->Close(); + out_entry_->Close(); } } @@ -97,27 +102,35 @@ void BackendIO::RunCallback(int result) { std::move(callback_).Run(result); } +void BackendIO::RunEntryResultCallback() { + EntryResult entry_result; + if (result_ != net::OK) { + entry_result = EntryResult::MakeError(static_cast<net::Error>(result())); + } else if (out_entry_opened_) { + entry_result = EntryResult::MakeOpened(out_entry_); + } else { + entry_result = EntryResult::MakeCreated(out_entry_); + } + std::move(entry_result_callback_).Run(std::move(entry_result)); +} + void BackendIO::Init() { operation_ = OP_INIT; } -void BackendIO::OpenOrCreateEntry(const std::string& key, - EntryWithOpened* entry_struct) { +void BackendIO::OpenOrCreateEntry(const std::string& key) { operation_ = OP_OPEN_OR_CREATE; key_ = key; - entry_with_opened_ptr_ = entry_struct; } -void BackendIO::OpenEntry(const std::string& key, Entry** entry) { +void BackendIO::OpenEntry(const std::string& key) { operation_ = OP_OPEN; key_ = key; - entry_ptr_ = entry; } -void BackendIO::CreateEntry(const std::string& key, Entry** entry) { +void BackendIO::CreateEntry(const std::string& key) { operation_ = OP_CREATE; key_ = key; - entry_ptr_ = entry; } void BackendIO::DoomEntry(const std::string& key) { @@ -145,11 +158,9 @@ void BackendIO::CalculateSizeOfAllEntries() { operation_ = OP_SIZE_ALL; } -void BackendIO::OpenNextEntry(Rankings::Iterator* iterator, - Entry** next_entry) { +void BackendIO::OpenNextEntry(Rankings::Iterator* iterator) { operation_ = OP_OPEN_NEXT; iterator_ = iterator; - entry_ptr_ = next_entry; } void BackendIO::EndEnumeration(std::unique_ptr<Rankings::Iterator> iterator) { @@ -249,11 +260,7 @@ BackendIO::~BackendIO() = default; bool BackendIO::ReturnsEntry() { return operation_ == OP_OPEN || operation_ == OP_CREATE || - operation_ == OP_OPEN_NEXT; -} - -bool BackendIO::ReturnsEntryWithOpened() { - return operation_ == OP_OPEN_OR_CREATE; + operation_ == OP_OPEN_NEXT || operation_ == OP_OPEN_OR_CREATE; } base::TimeDelta BackendIO::ElapsedTime() const { @@ -271,27 +278,29 @@ void BackendIO::ExecuteBackendOperation() { result_ = backend_->SyncOpenEntry(key_, &entry); if (result_ == net::OK) { - entry_with_opened_ptr_->entry = LeakEntryImpl(std::move(entry)); - entry_with_opened_ptr_->opened = true; + out_entry_ = LeakEntryImpl(std::move(entry)); + out_entry_opened_ = true; break; } // Opening failed, create an entry instead. result_ = backend_->SyncCreateEntry(key_, &entry); - entry_with_opened_ptr_->entry = LeakEntryImpl(std::move(entry)); - entry_with_opened_ptr_->opened = false; + out_entry_ = LeakEntryImpl(std::move(entry)); + out_entry_opened_ = false; break; } case OP_OPEN: { scoped_refptr<EntryImpl> entry; result_ = backend_->SyncOpenEntry(key_, &entry); - *entry_ptr_ = LeakEntryImpl(std::move(entry)); + out_entry_ = LeakEntryImpl(std::move(entry)); + out_entry_opened_ = true; break; } case OP_CREATE: { scoped_refptr<EntryImpl> entry; result_ = backend_->SyncCreateEntry(key_, &entry); - *entry_ptr_ = LeakEntryImpl(std::move(entry)); + out_entry_ = LeakEntryImpl(std::move(entry)); + out_entry_opened_ = false; break; } case OP_DOOM: @@ -312,7 +321,8 @@ void BackendIO::ExecuteBackendOperation() { case OP_OPEN_NEXT: { scoped_refptr<EntryImpl> entry; result_ = backend_->SyncOpenNextEntry(iterator_, &entry); - *entry_ptr_ = LeakEntryImpl(std::move(entry)); + out_entry_ = LeakEntryImpl(std::move(entry)); + out_entry_opened_ = true; break; } case OP_END_ENUMERATION: @@ -407,31 +417,27 @@ void InFlightBackendIO::Init(net::CompletionOnceCallback callback) { PostOperation(FROM_HERE, operation.get()); } -void InFlightBackendIO::OpenOrCreateEntry( - const std::string& key, - EntryWithOpened* entry_struct, - net::CompletionOnceCallback callback) { +void InFlightBackendIO::OpenOrCreateEntry(const std::string& key, + EntryResultCallback callback) { scoped_refptr<BackendIO> operation( new BackendIO(this, backend_, std::move(callback))); - operation->OpenOrCreateEntry(key, entry_struct); + operation->OpenOrCreateEntry(key); PostOperation(FROM_HERE, operation.get()); } void InFlightBackendIO::OpenEntry(const std::string& key, - Entry** entry, - net::CompletionOnceCallback callback) { + EntryResultCallback callback) { scoped_refptr<BackendIO> operation( new BackendIO(this, backend_, std::move(callback))); - operation->OpenEntry(key, entry); + operation->OpenEntry(key); PostOperation(FROM_HERE, operation.get()); } void InFlightBackendIO::CreateEntry(const std::string& key, - Entry** entry, - net::CompletionOnceCallback callback) { + EntryResultCallback callback) { scoped_refptr<BackendIO> operation( new BackendIO(this, backend_, std::move(callback))); - operation->CreateEntry(key, entry); + operation->CreateEntry(key); PostOperation(FROM_HERE, operation.get()); } @@ -477,11 +483,10 @@ void InFlightBackendIO::DoomEntriesSince(const base::Time initial_time, } void InFlightBackendIO::OpenNextEntry(Rankings::Iterator* iterator, - Entry** next_entry, - net::CompletionOnceCallback callback) { + EntryResultCallback callback) { scoped_refptr<BackendIO> operation( new BackendIO(this, backend_, std::move(callback))); - operation->OpenNextEntry(iterator, next_entry); + operation->OpenNextEntry(iterator); PostOperation(FROM_HERE, operation.get()); } @@ -614,6 +619,11 @@ void InFlightBackendIO::OnOperationComplete(BackgroundIO* operation, if (op->has_callback() && (!cancel || op->IsEntryOperation())) op->RunCallback(op->result()); + + if (op->has_entry_result_callback() && !cancel) { + DCHECK(!op->IsEntryOperation()); + op->RunEntryResultCallback(); + } } void InFlightBackendIO::PostOperation(const base::Location& from_here, diff --git a/chromium/net/disk_cache/blockfile/in_flight_backend_io.h b/chromium/net/disk_cache/blockfile/in_flight_backend_io.h index 724cc338323..d06436e90c4 100644 --- a/chromium/net/disk_cache/blockfile/in_flight_backend_io.h +++ b/chromium/net/disk_cache/blockfile/in_flight_backend_io.h @@ -18,6 +18,7 @@ #include "net/base/io_buffer.h" #include "net/disk_cache/blockfile/in_flight_io.h" #include "net/disk_cache/blockfile/rankings.h" +#include "net/disk_cache/disk_cache.h" namespace base { class Location; @@ -26,9 +27,7 @@ class Location; namespace disk_cache { class BackendImpl; -class Entry; class EntryImpl; -struct EntryWithOpened; // This class represents a single asynchronous disk cache IO operation while it // is being bounced between threads. @@ -38,6 +37,10 @@ class BackendIO : public BackgroundIO { BackendImpl* backend, net::CompletionOnceCallback callback); + BackendIO(InFlightIO* controller, + BackendImpl* backend, + EntryResultCallback callback); + // Runs the actual operation on the background thread. void ExecuteOperation(); @@ -54,18 +57,23 @@ class BackendIO : public BackgroundIO { bool has_callback() const { return !callback_.is_null(); } void RunCallback(int result); + bool has_entry_result_callback() const { + return !entry_result_callback_.is_null(); + } + void RunEntryResultCallback(); + // The operations we proxy: void Init(); - void OpenOrCreateEntry(const std::string& key, EntryWithOpened* entry_struct); - void OpenEntry(const std::string& key, Entry** entry); - void CreateEntry(const std::string& key, Entry** entry); + void OpenOrCreateEntry(const std::string& key); + void OpenEntry(const std::string& key); + void CreateEntry(const std::string& key); 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 CalculateSizeOfAllEntries(); - void OpenNextEntry(Rankings::Iterator* iterator, Entry** next_entry); + void OpenNextEntry(Rankings::Iterator* iterator); void EndEnumeration(std::unique_ptr<Rankings::Iterator> iterator); void OnExternalCacheHit(const std::string& key); void CloseEntryImpl(EntryImpl* entry); @@ -92,6 +100,8 @@ class BackendIO : public BackgroundIO { void ReadyForSparseIO(EntryImpl* entry); private: + BackendIO(InFlightIO* controller, BackendImpl* backend); + // There are two types of operations to proxy: regular backend operations are // executed sequentially (queued by the message loop). On the other hand, // operations targeted to a given entry can be long lived and support multiple @@ -129,7 +139,6 @@ class BackendIO : public BackgroundIO { // Returns true if this operation returns an entry. bool ReturnsEntry(); - bool ReturnsEntryWithOpened(); // Returns the time that has passed since the operation was created. base::TimeDelta ElapsedTime() const; @@ -141,10 +150,13 @@ class BackendIO : public BackgroundIO { net::CompletionOnceCallback callback_; Operation operation_; + // Used for ops that open or create entries. + EntryResultCallback entry_result_callback_; + Entry* out_entry_; // if set, already has the user's ref added. + bool out_entry_opened_; + // The arguments of all the operations we proxy: std::string key_; - Entry** entry_ptr_; - EntryWithOpened* entry_with_opened_ptr_; base::Time initial_time_; base::Time end_time_; Rankings::Iterator* iterator_; @@ -173,15 +185,9 @@ class InFlightBackendIO : public InFlightIO { // Proxied operations. void Init(net::CompletionOnceCallback callback); - void OpenOrCreateEntry(const std::string& key, - EntryWithOpened* entry_struct, - net::CompletionOnceCallback callback); - void OpenEntry(const std::string& key, - Entry** entry, - net::CompletionOnceCallback callback); - void CreateEntry(const std::string& key, - Entry** entry, - net::CompletionOnceCallback callback); + void OpenOrCreateEntry(const std::string& key, EntryResultCallback callback); + void OpenEntry(const std::string& key, EntryResultCallback callback); + void CreateEntry(const std::string& key, EntryResultCallback callback); void DoomEntry(const std::string& key, net::CompletionOnceCallback callback); void DoomAllEntries(net::CompletionOnceCallback callback); void DoomEntriesBetween(const base::Time initial_time, @@ -191,8 +197,7 @@ class InFlightBackendIO : public InFlightIO { net::CompletionOnceCallback callback); void CalculateSizeOfAllEntries(net::CompletionOnceCallback callback); void OpenNextEntry(Rankings::Iterator* iterator, - Entry** next_entry, - net::CompletionOnceCallback callback); + EntryResultCallback callback); void EndEnumeration(std::unique_ptr<Rankings::Iterator> iterator); void OnExternalCacheHit(const std::string& key); void CloseEntryImpl(EntryImpl* entry); diff --git a/chromium/net/disk_cache/cache_util.cc b/chromium/net/disk_cache/cache_util.cc index 173dc9d2bcb..57cba5984c2 100644 --- a/chromium/net/disk_cache/cache_util.cc +++ b/chromium/net/disk_cache/cache_util.cc @@ -143,10 +143,11 @@ bool DelayedCacheCleanup(const base::FilePath& full_path) { return false; } - base::PostTaskWithTraits(FROM_HERE, - {base::MayBlock(), base::TaskPriority::BEST_EFFORT, - base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, - base::BindOnce(&CleanupCallback, path, name_str)); + base::PostTask( + FROM_HERE, + {base::ThreadPool(), base::MayBlock(), base::TaskPriority::BEST_EFFORT, + base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, + base::BindOnce(&CleanupCallback, path, name_str)); return true; } diff --git a/chromium/net/disk_cache/disk_cache.cc b/chromium/net/disk_cache/disk_cache.cc index 06066616755..2bd21ba0680 100644 --- a/chromium/net/disk_cache/disk_cache.cc +++ b/chromium/net/disk_cache/disk_cache.cc @@ -9,7 +9,7 @@ #include "base/macros.h" #include "base/metrics/field_trial.h" #include "base/single_thread_task_runner.h" -#include "base/task/thread_pool/thread_pool.h" +#include "base/task/thread_pool/thread_pool_instance.h" #include "build/build_config.h" #include "net/base/cache_type.h" #include "net/base/net_errors.h" @@ -311,13 +311,6 @@ void FlushCacheThreadForTesting() { BackendImpl::FlushForTesting(); } -net::Error Backend::OpenOrCreateEntry(const std::string& key, - net::RequestPriority priority, - EntryWithOpened* entry_struct, - CompletionOnceCallback callback) { - return net::ERR_NOT_IMPLEMENTED; -} - int64_t Backend::CalculateSizeOfEntriesBetween( base::Time initial_time, base::Time end_time, @@ -331,4 +324,64 @@ uint8_t Backend::GetEntryInMemoryData(const std::string& key) { void Backend::SetEntryInMemoryData(const std::string& key, uint8_t data) {} +EntryResult::EntryResult() = default; +EntryResult::~EntryResult() = default; + +EntryResult::EntryResult(EntryResult&& other) { + net_error_ = other.net_error_; + entry_ = std::move(other.entry_); + opened_ = other.opened_; + + other.net_error_ = net::ERR_FAILED; + other.opened_ = false; +} + +EntryResult& EntryResult::operator=(EntryResult&& other) { + net_error_ = other.net_error_; + entry_ = std::move(other.entry_); + opened_ = other.opened_; + + other.net_error_ = net::ERR_FAILED; + other.opened_ = false; + return *this; +} + +// static +EntryResult EntryResult::MakeOpened(Entry* new_entry) { + DCHECK(new_entry); + + EntryResult result; + result.net_error_ = net::OK; + result.entry_.reset(new_entry); + result.opened_ = true; + return result; +} + +// static +EntryResult EntryResult::MakeCreated(Entry* new_entry) { + DCHECK(new_entry); + + EntryResult result; + result.net_error_ = net::OK; + result.entry_.reset(new_entry); + result.opened_ = false; + return result; +} + +// static +EntryResult EntryResult::MakeError(net::Error status) { + DCHECK_NE(status, net::OK); + + EntryResult result; + result.net_error_ = status; + return result; +} + +Entry* EntryResult::ReleaseEntry() { + Entry* ret = entry_.release(); + net_error_ = net::ERR_FAILED; + opened_ = false; + return ret; +} + } // namespace disk_cache diff --git a/chromium/net/disk_cache/disk_cache.h b/chromium/net/disk_cache/disk_cache.h index 1abeb681a7c..91aaa7d6f8c 100644 --- a/chromium/net/disk_cache/disk_cache.h +++ b/chromium/net/disk_cache/disk_cache.h @@ -46,7 +46,8 @@ namespace disk_cache { class Entry; class Backend; -struct EntryWithOpened; +class EntryResult; +using EntryResultCallback = base::OnceCallback<void(EntryResult)>; // Returns an instance of a Backend of the given |type|. |path| points to a // folder where the cached data will be stored (if appropriate). This cache @@ -119,27 +120,30 @@ NET_EXPORT void FlushCacheThreadForTesting(); // The root interface for a disk cache instance. class NET_EXPORT Backend { public: - typedef net::CompletionOnceCallback CompletionOnceCallback; - typedef net::Int64CompletionOnceCallback Int64CompletionOnceCallback; + using CompletionOnceCallback = net::CompletionOnceCallback; + using Int64CompletionOnceCallback = net::Int64CompletionOnceCallback; + using EntryResultCallback = disk_cache::EntryResultCallback; + using EntryResult = disk_cache::EntryResult; class Iterator { public: virtual ~Iterator() {} - // OpenNextEntry returns |net::OK| and provides |next_entry| if there is an - // entry to enumerate. It returns |net::ERR_FAILED| at the end of - // enumeration. If the function returns |net::ERR_IO_PENDING|, then the - // final result will be passed to the provided |callback|, otherwise - // |callback| will not be called. If any entry in the cache is modified - // during iteration, the result of this function is thereafter undefined. + // OpenNextEntry returns a result with net_error() |net::OK| and provided + // entry if there is an entry to enumerate which it can return immediately. + // It returns a result with net_error() |net::ERR_FAILED| at the end of + // enumeration. If the function returns a result with net_error() + // |net::ERR_IO_PENDING|, then the final result will be passed to the + // provided |callback|, otherwise |callback| will not be called. If any + // entry in the cache is modified during iteration, the result of this + // function is thereafter undefined. // // Calling OpenNextEntry after the backend which created it is destroyed // may fail with |net::ERR_FAILED|; however it should not crash. // // Some cache backends make stronger guarantees about mutation during // iteration, see top comment in simple_backend_impl.h for details. - virtual net::Error OpenNextEntry(Entry** next_entry, - CompletionOnceCallback callback) = 0; + virtual EntryResult OpenNextEntry(EntryResultCallback callback) = 0; }; // If the backend is destroyed when there are operations in progress (any @@ -162,48 +166,39 @@ class NET_EXPORT Backend { virtual int32_t GetEntryCount() const = 0; // Atomically attempts to open an existing entry based on |key| or, if none - // already exists, to create a new entry. Upon success |entry_struct| contains - // a struct with 1) an entry pointer to either a preexisting or newly created - // entry 2) a bool indicting if the entry was opened or not. When the entry - // pointer is no longer needed, its Close method should be called. The return - // value is a net error code. If this method returns ERR_IO_PENDING, the - // |callback| will be invoked when the entry is available. The pointer to - // receive the |entry_struct| must remain valid until the operation completes. - // The |priority| of the entry determines its priority in the background - // worker pools. + // already exists, to create a new entry. Returns an EntryResult object, + // which contains 1) network error code; 2) if the error code is OK, + // an owning pointer to either a preexisting or a newly created + // entry; 3) a bool indicating if the entry was opened or not. When the entry + // pointer is no longer needed, its Close() method should be called. If this + // method return value has net_error() == ERR_IO_PENDING, the + // |callback| will be invoked when the entry is available. The |priority| of + // the entry determines its priority in the background worker pools. // // This method should be the preferred way to obtain an entry over using // OpenEntry() or CreateEntry() separately in order to simplify consumer // logic. - virtual net::Error OpenOrCreateEntry(const std::string& key, - net::RequestPriority priority, - EntryWithOpened* entry_struct, - CompletionOnceCallback callback); - - // Opens an existing entry. Upon success, |entry| holds a pointer to an Entry - // object representing the specified disk cache entry. When the entry pointer - // is no longer needed, its Close method should be called. The return value is - // a net error code. If this method returns ERR_IO_PENDING, the |callback| - // will be invoked when the entry is available. The pointer to receive the - // |entry| must remain valid until the operation completes. The |priority| - // of the entry determines its priority in the background worker pools. - virtual net::Error OpenEntry(const std::string& key, - net::RequestPriority priority, - Entry** entry, - CompletionOnceCallback callback) = 0; - - // Creates a new entry. Upon success, the out param holds a pointer to an - // Entry object representing the newly created disk cache entry. When the - // entry pointer is no longer needed, its Close method should be called. The - // return value is a net error code. If this method returns ERR_IO_PENDING, - // the |callback| will be invoked when the entry is available. The pointer to - // receive the |entry| must remain valid until the operation completes. The - // |priority| of the entry determines its priority in the background worker - // pools. - virtual net::Error CreateEntry(const std::string& key, - net::RequestPriority priority, - Entry** entry, - CompletionOnceCallback callback) = 0; + virtual EntryResult OpenOrCreateEntry(const std::string& key, + net::RequestPriority priority, + EntryResultCallback callback) = 0; + + // Opens an existing entry, returning status code, and, if successful, an + // entry pointer packaged up into an EntryResult. If return value's + // net_error() is ERR_IO_PENDING, the |callback| will be invoked when the + // entry is available. The |priority| of the entry determines its priority in + // the background worker pools. + virtual EntryResult OpenEntry(const std::string& key, + net::RequestPriority priority, + EntryResultCallback) = 0; + + // Creates a new entry, returning status code, and, if successful, and + // an entry pointer packaged up into an EntryResult. If return value's + // net_error() is ERR_IO_PENDING, the |callback| will be invoked when the + // entry is available. The |priority| of the entry determines its priority in + // the background worker pools. + virtual EntryResult CreateEntry(const std::string& key, + net::RequestPriority priority, + EntryResultCallback callback) = 0; // Marks the entry, specified by the given key, for deletion. The return value // is a net error code. If this method returns ERR_IO_PENDING, the |callback| @@ -462,16 +457,6 @@ class NET_EXPORT Entry { virtual ~Entry() {} }; -// This struct is used to allow OpenOrCreateEntry() to return both an entry -// pointer as well as a bool indicating whether the entry was opened or -// not (i.e.: created). -struct EntryWithOpened { - explicit EntryWithOpened(Entry* e) : entry(e), opened(false) {} - EntryWithOpened() : entry(nullptr), opened(false) {} - Entry* entry; - bool opened; -}; - struct EntryDeleter { void operator()(Entry* entry) { // Note that |entry| is ref-counted. @@ -485,6 +470,51 @@ struct EntryDeleter { // hasn't yet completed but the browser is shutting down). typedef std::unique_ptr<Entry, EntryDeleter> ScopedEntryPtr; +// Represents the result of an entry open or create operation. +// This is a move-only, owning type, which will close the entry it owns unless +// it's released from it via ReleaseEntry (or it's moved away from). +class NET_EXPORT EntryResult { + public: + EntryResult(); + ~EntryResult(); + EntryResult(EntryResult&&); + EntryResult& operator=(EntryResult&&); + + EntryResult(const EntryResult&) = delete; + EntryResult& operator=(const EntryResult&) = delete; + + // Creates an entry result representing successfully opened (pre-existing) + // cache entry. |new_entry| must be non-null. + static EntryResult MakeOpened(Entry* new_entry); + + // Creates an entry result representing successfully created (new) + // cache entry. |new_entry| must be non-null. + static EntryResult MakeCreated(Entry* new_entry); + + // Creates an entry result representing an error. Status must not be net::OK. + static EntryResult MakeError(net::Error status); + + // Relinquishes ownership of the entry, and returns a pointer to it. + // Will return nullptr if there is no such entry. + // WARNING: clears net_error() to ERR_FAILED, opened() to false. + Entry* ReleaseEntry(); + + // ReleaseEntry() will return a non-null pointer if and only if this is + // net::OK before the call to it. + net::Error net_error() const { return net_error_; } + + // Returns true if an existing entry was opened rather than a new one created. + // Implies net_error() == net::OK and non-null entry. + bool opened() const { return opened_; } + + private: + // Invariant to keep: |entry_| != nullptr iff |net_error_| == net::OK; + // |opened_| set only if entry is set. + net::Error net_error_ = net::ERR_FAILED; + bool opened_ = false; + ScopedEntryPtr entry_; +}; + } // namespace disk_cache #endif // NET_DISK_CACHE_DISK_CACHE_H_ diff --git a/chromium/net/disk_cache/disk_cache_fuzzer.cc b/chromium/net/disk_cache/disk_cache_fuzzer.cc index a840879548a..2f1ee041605 100644 --- a/chromium/net/disk_cache/disk_cache_fuzzer.cc +++ b/chromium/net/disk_cache/disk_cache_fuzzer.cc @@ -19,7 +19,7 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_refptr.h" -#include "base/test/scoped_task_environment.h" +#include "base/test/task_environment.h" #include "base/time/time.h" #include "net/base/cache_type.h" #include "net/base/io_buffer.h" @@ -84,10 +84,9 @@ struct InitGlobals { // Mark this thread as an IO_THREAD with MOCK_TIME, and ensure that Now() // is driven from the same mock clock. - scoped_task_environment_ = - std::make_unique<base::test::ScopedTaskEnvironment>( - base::test::ScopedTaskEnvironment::MainThreadType::IO, - base::test::ScopedTaskEnvironment::TimeSource::MOCK_TIME_AND_NOW); + task_environment_ = std::make_unique<base::test::TaskEnvironment>( + base::test::TaskEnvironment::MainThreadType::IO, + base::test::TaskEnvironment::TimeSource::MOCK_TIME); // Disable noisy logging as per "libFuzzer in Chrome" documentation: // testing/libfuzzer/getting_started.md#Disable-noisy-error-message-logging. @@ -106,7 +105,7 @@ struct InitGlobals { } // This allows us to mock time for all threads. - std::unique_ptr<base::test::ScopedTaskEnvironment> scoped_task_environment_; + std::unique_ptr<base::test::TaskEnvironment> task_environment_; // Used as a pre-filled buffer for all writes. scoped_refptr<net::IOBuffer> buffer_; @@ -137,7 +136,7 @@ class DiskCacheLPMFuzzer { struct EntryInfo { EntryInfo() = default; disk_cache::Entry* entry_ptr = nullptr; - std::unique_ptr<net::TestCompletionCallback> tcb; + std::unique_ptr<TestEntryResultCompletionCallback> tcb; DISALLOW_COPY_AND_ASSIGN(EntryInfo); }; @@ -146,20 +145,20 @@ class DiskCacheLPMFuzzer { // Waits for an entry to be ready. Only should be called if there is a pending // callback for this entry; i.e. ei->tcb != nullptr. // Also takes the rv that the cache entry creation functions return, and does - // not wait if rv != net::ERR_IO_PENDING (and would never have called the - // callback). - int WaitOnEntry(EntryInfo* ei, int rv = net::ERR_IO_PENDING); + // not wait if rv.net_error != net::ERR_IO_PENDING (and would never have + // called the callback). + disk_cache::EntryResult WaitOnEntry( + EntryInfo* ei, + disk_cache::EntryResult result = + disk_cache::EntryResult::MakeError(net::ERR_IO_PENDING)); // Used as a callback for entry-opening backend calls. Will record the entry // in the map as usable and will release any entry-specific calls waiting for // the entry to be ready. - void OpenCacheEntryCallback( - scoped_refptr<base::RefCountedData<disk_cache::EntryWithOpened>> - entry_result, - uint64_t entry_id, - bool async, - bool set_is_sparse, - int rv); + void OpenCacheEntryCallback(uint64_t entry_id, + bool async, + bool set_is_sparse, + disk_cache::EntryResult result); // Waits for the entry to finish opening, in the async case. Then, if the // entry is successfully open (callback returns net::OK, or was already @@ -341,51 +340,55 @@ void DiskCacheLPMFuzzer::RunTaskForTest(base::OnceClosure closure) { // Resets the cb in the map so that WriteData and other calls that work on an // entry don't wait for its result. void DiskCacheLPMFuzzer::OpenCacheEntryCallback( - scoped_refptr<base::RefCountedData<disk_cache::EntryWithOpened>> - entry_result, uint64_t entry_id, bool async, bool set_is_sparse, - int rv) { + disk_cache::EntryResult result) { // TODO(mpdenton) if this fails should we delete the entry entirely? // Would need to mark it for deletion and delete it later, as // IsValidEntry might be waiting for it. EntryInfo* ei = &open_cache_entries_[entry_id]; - // It's important to write the pointer here and not let it be set directly - // by OpenEntry & co., since the callback is when the item is transferred to - // the client, so there may be a window in between the write and callback - // where the backend is destroyed, invalidating the transfer. - // Writes can also happen on a different thread, so unless the read is - // sequenced with it, it would be a race, and ei->entry_ptr is read quite a - // bit. - ei->entry_ptr = entry_result->data.entry; - ei->tcb->callback().Run(rv); - // If this entry was just created, set it as sparse if applicable. - if (set_is_sparse && ei->entry_ptr) { - sparse_entry_tracker_[ei->entry_ptr] = true; - } - if (async && ei->entry_ptr) { - MAYBE_PRINT << " [Async opening of cache entry for \"" - << ei->entry_ptr->GetKey() << "\" callback (rv = " << rv << ")]" - << std::endl; + if (async) { + int rv = result.net_error(); + ei->entry_ptr = result.ReleaseEntry(); + // We are responsible for setting things up. + if (set_is_sparse && ei->entry_ptr) { + sparse_entry_tracker_[ei->entry_ptr] = true; + } + if (ei->entry_ptr) { + MAYBE_PRINT << " [Async opening of cache entry for \"" + << ei->entry_ptr->GetKey() << "\" callback (rv = " << rv + << ")]" << std::endl; + } + // Unblock any subsequent ops waiting for this --- they don't care about + // the actual return value, but use something distinctive for debugging. + ei->tcb->callback().Run( + disk_cache::EntryResult::MakeError(net::ERR_FILE_VIRUS_INFECTED)); + } else { + // The operation code will pull the result out of the completion callback, + // so hand it to it. + ei->tcb->callback().Run(std::move(result)); } } -int DiskCacheLPMFuzzer::WaitOnEntry(EntryInfo* ei, int rv) { +disk_cache::EntryResult DiskCacheLPMFuzzer::WaitOnEntry( + EntryInfo* ei, + disk_cache::EntryResult result) { CHECK(ei->tcb); - rv = ei->tcb->GetResult(rv); + result = ei->tcb->GetResult(std::move(result)); + // Reset the callback so nobody accidentally waits on a callback that never // comes. ei->tcb.reset(); - return rv; + return result; } bool DiskCacheLPMFuzzer::IsValidEntry(EntryInfo* ei) { if (ei->tcb) { // If we have a callback, we are the first to access this async-created // entry. Wait for it, and then delete it so nobody waits on it again. - return WaitOnEntry(ei) == net::OK; + WaitOnEntry(ei); } // entry_ptr will be nullptr if the entry has been closed. return ei->entry_ptr != nullptr; @@ -439,7 +442,7 @@ void DiskCacheLPMFuzzer::RunCommands( // Handle any callbacks that other threads may have posted to us in the // meantime, so any successful async OpenEntry's (etc.) add their // entry_ptr's to the map. - init_globals->scoped_task_environment_->RunUntilIdle(); + init_globals->task_environment_->RunUntilIdle(); switch (command.fuzz_command_oneof_case()) { case disk_cache_fuzzer::FuzzCommand::kSetMaxSize: { @@ -463,30 +466,29 @@ void DiskCacheLPMFuzzer::RunCommands( std::string key_str = ToKey(key_id); created_cache_entries_[key_id] = key_str; - auto entry_result = base::MakeRefCounted< - base::RefCountedData<disk_cache::EntryWithOpened>>(); - disk_cache::EntryWithOpened* entry_result_ptr = &entry_result->data; EntryInfo* entry_info = &open_cache_entries_[entry_id]; - entry_info->tcb = std::make_unique<net::TestCompletionCallback>(); - net::CompletionOnceCallback cb = base::BindOnce( - &DiskCacheLPMFuzzer::OpenCacheEntryCallback, base::Unretained(this), - entry_result, entry_id, async, is_sparse); + entry_info->tcb = std::make_unique<TestEntryResultCompletionCallback>(); + disk_cache::EntryResultCallback cb = + base::BindOnce(&DiskCacheLPMFuzzer::OpenCacheEntryCallback, + base::Unretained(this), entry_id, async, is_sparse); MAYBE_PRINT << "CreateEntry(\"" << key_str << "\", set_is_sparse = " << is_sparse << ") = " << std::flush; - int rv = cache_->CreateEntry(key_str, pri, &entry_result_ptr->entry, - std::move(cb)); - if (!async || rv != net::ERR_IO_PENDING) { - rv = WaitOnEntry(entry_info, rv); - // Ensure we mark sparsity, even if the callback never ran. + disk_cache::EntryResult result = + cache_->CreateEntry(key_str, pri, std::move(cb)); + if (!async || result.net_error() != net::ERR_IO_PENDING) { + result = WaitOnEntry(entry_info, std::move(result)); + int rv = result.net_error(); + + // Ensure we mark sparsity, save entry if the callback never ran. if (rv == net::OK) { - entry_info->entry_ptr = entry_result_ptr->entry; + entry_info->entry_ptr = result.ReleaseEntry(); sparse_entry_tracker_[entry_info->entry_ptr] = is_sparse; } MAYBE_PRINT << rv << std::endl; - } else if (rv == net::ERR_IO_PENDING) { + } else { MAYBE_PRINT << "net::ERR_IO_PENDING (async)" << std::endl; } break; @@ -507,25 +509,23 @@ void DiskCacheLPMFuzzer::RunCommands( if (open_cache_entries_.find(entry_id) != open_cache_entries_.end()) continue; // Don't overwrite a currently open cache entry. - auto entry_result = base::MakeRefCounted< - base::RefCountedData<disk_cache::EntryWithOpened>>(); - disk_cache::EntryWithOpened* entry_result_ptr = &entry_result->data; EntryInfo* entry_info = &open_cache_entries_[entry_id]; - entry_info->tcb = std::make_unique<net::TestCompletionCallback>(); - net::CompletionOnceCallback cb = base::BindOnce( - &DiskCacheLPMFuzzer::OpenCacheEntryCallback, base::Unretained(this), - entry_result, entry_id, async, false); + entry_info->tcb = std::make_unique<TestEntryResultCompletionCallback>(); + disk_cache::EntryResultCallback cb = + base::BindOnce(&DiskCacheLPMFuzzer::OpenCacheEntryCallback, + base::Unretained(this), entry_id, async, false); auto key_it = GetNextValue(&created_cache_entries_, key_id); MAYBE_PRINT << "OpenEntry(\"" << key_it->second << "\") = " << std::flush; - int rv = cache_->OpenEntry(key_it->second, pri, - &entry_result_ptr->entry, std::move(cb)); - if (!async || rv != net::ERR_IO_PENDING) { - rv = WaitOnEntry(entry_info, rv); + disk_cache::EntryResult result = + cache_->OpenEntry(key_it->second, pri, std::move(cb)); + if (!async || result.net_error() != net::ERR_IO_PENDING) { + result = WaitOnEntry(entry_info, std::move(result)); + int rv = result.net_error(); if (rv == net::OK) - entry_info->entry_ptr = entry_result_ptr->entry; + entry_info->entry_ptr = result.ReleaseEntry(); MAYBE_PRINT << rv << std::endl; } else { MAYBE_PRINT << "net::ERR_IO_PENDING (async)" << std::endl; @@ -562,32 +562,29 @@ void DiskCacheLPMFuzzer::RunCommands( } // Setup for callbacks. - auto entry_result = base::MakeRefCounted< - base::RefCountedData<disk_cache::EntryWithOpened>>(); - disk_cache::EntryWithOpened* entry_result_ptr = &entry_result->data; EntryInfo* entry_info = &open_cache_entries_[entry_id]; - entry_info->tcb = std::make_unique<net::TestCompletionCallback>(); - net::CompletionOnceCallback cb = base::BindOnce( - &DiskCacheLPMFuzzer::OpenCacheEntryCallback, base::Unretained(this), - entry_result, entry_id, async, is_sparse); + entry_info->tcb = std::make_unique<TestEntryResultCompletionCallback>(); + disk_cache::EntryResultCallback cb = + base::BindOnce(&DiskCacheLPMFuzzer::OpenCacheEntryCallback, + base::Unretained(this), entry_id, async, is_sparse); // Will only be set as sparse if it is created and not opened. MAYBE_PRINT << "OpenOrCreateEntry(\"" << key_str << "\", set_is_sparse = " << is_sparse << ") = " << std::flush; - int rv = cache_->OpenOrCreateEntry(key_str, pri, entry_result_ptr, - std::move(cb)); - if (!async || rv != net::ERR_IO_PENDING) { - rv = WaitOnEntry(entry_info, rv); - // We still hold a reference to |entry_result| so we can use it. - entry_info->entry_ptr = entry_result_ptr->entry; + disk_cache::EntryResult result = + cache_->OpenOrCreateEntry(key_str, pri, std::move(cb)); + if (!async || result.net_error() != net::ERR_IO_PENDING) { + result = WaitOnEntry(entry_info, std::move(result)); + int rv = result.net_error(); + bool opened = result.opened(); + entry_info->entry_ptr = result.ReleaseEntry(); // Ensure we mark sparsity, even if the callback never ran. - if (rv == net::OK && !entry_result_ptr->opened) + if (rv == net::OK && !opened) sparse_entry_tracker_[entry_info->entry_ptr] = is_sparse; - MAYBE_PRINT << rv << ", opened = " << entry_result_ptr->opened - << std::endl; + MAYBE_PRINT << rv << ", opened = " << opened << std::endl; } else { MAYBE_PRINT << "net::ERR_IO_PENDING (async)" << std::endl; } @@ -808,23 +805,21 @@ void DiskCacheLPMFuzzer::RunCommands( auto iterator_it = GetNextValue(&open_iterators_, it_id); - auto entry_result = base::MakeRefCounted< - base::RefCountedData<disk_cache::EntryWithOpened>>(); - disk_cache::EntryWithOpened* entry_result_ptr = &entry_result->data; EntryInfo* entry_info = &open_cache_entries_[entry_id]; - entry_info->tcb = std::make_unique<net::TestCompletionCallback>(); - net::CompletionOnceCallback cb = base::BindOnce( - &DiskCacheLPMFuzzer::OpenCacheEntryCallback, base::Unretained(this), - entry_result, entry_id, async, false); + entry_info->tcb = std::make_unique<TestEntryResultCompletionCallback>(); + disk_cache::EntryResultCallback cb = + base::BindOnce(&DiskCacheLPMFuzzer::OpenCacheEntryCallback, + base::Unretained(this), entry_id, async, false); MAYBE_PRINT << "Iterator(" << ione.it_id() << ").OpenNextEntry() = " << std::flush; - int rv = iterator_it->second->OpenNextEntry(&entry_result_ptr->entry, - std::move(cb)); - if (!async || rv != net::ERR_IO_PENDING) { - rv = WaitOnEntry(entry_info, rv); - entry_info->entry_ptr = entry_result_ptr->entry; + disk_cache::EntryResult result = + iterator_it->second->OpenNextEntry(std::move(cb)); + if (!async || result.net_error() != net::ERR_IO_PENDING) { + result = WaitOnEntry(entry_info, std::move(result)); + int rv = result.net_error(); + entry_info->entry_ptr = result.ReleaseEntry(); // Print return value, and key if applicable. if (!entry_info->entry_ptr) { MAYBE_PRINT << rv << std::endl; @@ -842,7 +837,7 @@ void DiskCacheLPMFuzzer::RunCommands( command.fast_forward_by().capped_num_millis() % kMaxNumMillisToWait); MAYBE_PRINT << "FastForwardBy(" << to_wait << ")" << std::endl; - init_globals->scoped_task_environment_->FastForwardBy(to_wait); + init_globals->task_environment_->FastForwardBy(to_wait); base::Time curr_time = base::Time::Now(); saved_times_[command.fast_forward_by().time_id()] = curr_time; @@ -1145,9 +1140,10 @@ void DiskCacheLPMFuzzer::CreateBackend( MAYBE_PRINT << "Waiting for simple cache index to be ready..." << std::endl; net::TestCompletionCallback wait_for_index_cb; - rv = simple_cache_impl_->index()->ExecuteWhenReady( + simple_cache_impl_->index()->ExecuteWhenReady( wait_for_index_cb.callback()); - CHECK_EQ(wait_for_index_cb.GetResult(rv), net::OK); + rv = wait_for_index_cb.WaitForResult(); + CHECK_EQ(rv, net::OK); } } else { MAYBE_PRINT << "Using blockfile cache"; @@ -1216,7 +1212,7 @@ DiskCacheLPMFuzzer::~DiskCacheLPMFuzzer() { // TODO(mpdenton) should also be documented? open_iterators_.clear(); // Just in case, finish any callbacks. - init_globals->scoped_task_environment_->RunUntilIdle(); + init_globals->task_environment_->RunUntilIdle(); // Close all entries that haven't been closed yet. CloseAllRemainingEntries(); // Destroy the backend. @@ -1225,13 +1221,13 @@ DiskCacheLPMFuzzer::~DiskCacheLPMFuzzer() { // Here we won't bother with waiting for our OpenEntry* callbacks. cache_.reset(); // Finish any callbacks that came in before backend destruction. - init_globals->scoped_task_environment_->RunUntilIdle(); + init_globals->task_environment_->RunUntilIdle(); // Close all entries that haven't been closed yet. CloseAllRemainingEntries(); } // Make sure any tasks triggered by the CloseEntry's have run. - init_globals->scoped_task_environment_->RunUntilIdle(); + init_globals->task_environment_->RunUntilIdle(); if (simple_cache_impl_) CHECK(simple_file_tracker_->IsEmptyForTesting()); base::RunLoop().RunUntilIdle(); diff --git a/chromium/net/disk_cache/disk_cache_perftest.cc b/chromium/net/disk_cache/disk_cache_perftest.cc index 1f16e54ca1a..56fef9b1861 100644 --- a/chromium/net/disk_cache/disk_cache_perftest.cc +++ b/chromium/net/disk_cache/disk_cache_perftest.cc @@ -112,9 +112,7 @@ class WriteHandler { protected: void CreateNextEntry(); - void CreateCallback(std::unique_ptr<disk_cache::Entry*> unique_entry_ptr, - int data_len, - int result); + void CreateCallback(int data_len, disk_cache::EntryResult result); void WriteDataCallback(disk_cache::Entry* entry, int next_offset, int data_len, @@ -149,25 +147,21 @@ void WriteHandler::Run() { void WriteHandler::CreateNextEntry() { ASSERT_GT(kNumEntries, next_entry_index_); TestEntry test_entry = test_->entries()[next_entry_index_++]; - disk_cache::Entry** entry_ptr = new disk_cache::Entry*(); - std::unique_ptr<disk_cache::Entry*> unique_entry_ptr(entry_ptr); - net::CompletionRepeatingCallback callback = + auto callback = base::BindRepeating(&WriteHandler::CreateCallback, base::Unretained(this), - base::Passed(&unique_entry_ptr), test_entry.data_len); - int result = - cache_->CreateEntry(test_entry.key, net::HIGHEST, entry_ptr, callback); - if (result != net::ERR_IO_PENDING) - callback.Run(result); + test_entry.data_len); + disk_cache::EntryResult result = + cache_->CreateEntry(test_entry.key, net::HIGHEST, callback); + if (result.net_error() != net::ERR_IO_PENDING) + callback.Run(std::move(result)); } -void WriteHandler::CreateCallback(std::unique_ptr<disk_cache::Entry*> entry_ptr, - int data_len, - int result) { - if (CheckForErrorAndCancel(result)) +void WriteHandler::CreateCallback(int data_len, + disk_cache::EntryResult result) { + if (CheckForErrorAndCancel(result.net_error())) return; - disk_cache::Entry* entry = *entry_ptr; - + disk_cache::Entry* entry = result.ReleaseEntry(); net::CompletionRepeatingCallback callback = base::BindRepeating( &WriteHandler::WriteDataCallback, base::Unretained(this), entry, 0, data_len, kHeadersSize); @@ -243,9 +237,8 @@ class ReadHandler { void OpenNextEntry(int parallel_operation_index); void OpenCallback(int parallel_operation_index, - std::unique_ptr<disk_cache::Entry*> unique_entry_ptr, int data_len, - int result); + disk_cache::EntryResult result); void ReadDataCallback(int parallel_operation_index, disk_cache::Entry* entry, int next_offset, @@ -280,26 +273,22 @@ void ReadHandler::Run() { void ReadHandler::OpenNextEntry(int parallel_operation_index) { ASSERT_GT(kNumEntries, next_entry_index_); TestEntry test_entry = test_->entries()[next_entry_index_++]; - disk_cache::Entry** entry_ptr = new disk_cache::Entry*(); - std::unique_ptr<disk_cache::Entry*> unique_entry_ptr(entry_ptr); - net::CompletionRepeatingCallback callback = + auto callback = base::BindRepeating(&ReadHandler::OpenCallback, base::Unretained(this), - parallel_operation_index, - base::Passed(&unique_entry_ptr), test_entry.data_len); - int result = - cache_->OpenEntry(test_entry.key, net::HIGHEST, entry_ptr, callback); - if (result != net::ERR_IO_PENDING) - callback.Run(result); + parallel_operation_index, test_entry.data_len); + disk_cache::EntryResult result = + cache_->OpenEntry(test_entry.key, net::HIGHEST, callback); + if (result.net_error() != net::ERR_IO_PENDING) + callback.Run(std::move(result)); } void ReadHandler::OpenCallback(int parallel_operation_index, - std::unique_ptr<disk_cache::Entry*> entry_ptr, int data_len, - int result) { - if (CheckForErrorAndCancel(result)) + disk_cache::EntryResult result) { + if (CheckForErrorAndCancel(result.net_error())) return; - disk_cache::Entry* entry = *entry_ptr; + disk_cache::Entry* entry = result.ReleaseEntry(); EXPECT_EQ(data_len, entry->GetDataSize(1)); @@ -525,13 +514,15 @@ TEST_F(DiskCachePerfTest, SimpleCacheInitialReadPortion) { disk_cache::Entry* cache_entry[kBatchSize]; for (int i = 0; i < kBatchSize; ++i) { - net::TestCompletionCallback cb; - int rv = cache_->CreateEntry(base::NumberToString(i), net::HIGHEST, - &cache_entry[i], cb.callback()); - ASSERT_EQ(net::OK, cb.GetResult(rv)); + TestEntryResultCompletionCallback cb_create; + disk_cache::EntryResult result = cb_create.GetResult(cache_->CreateEntry( + base::NumberToString(i), net::HIGHEST, cb_create.callback())); + ASSERT_EQ(net::OK, result.net_error()); + cache_entry[i] = result.ReleaseEntry(); - rv = cache_entry[i]->WriteData(0, 0, buffer1.get(), kHeadersSize, - cb.callback(), false); + net::TestCompletionCallback cb; + int rv = cache_entry[i]->WriteData(0, 0, buffer1.get(), kHeadersSize, + cb.callback(), false); ASSERT_EQ(kHeadersSize, cb.GetResult(rv)); rv = cache_entry[i]->WriteData(1, 0, buffer2.get(), kBodySize, cb.callback(), false); diff --git a/chromium/net/disk_cache/disk_cache_test_base.cc b/chromium/net/disk_cache/disk_cache_test_base.cc index eb7b3aee111..35c36db62a4 100644 --- a/chromium/net/disk_cache/disk_cache_test_base.cc +++ b/chromium/net/disk_cache/disk_cache_test_base.cc @@ -34,7 +34,10 @@ using net::test::IsOk; DiskCacheTest::DiskCacheTest() { CHECK(temp_dir_.CreateUniqueTempDir()); - cache_path_ = temp_dir_.GetPath(); + // Put the cache into a subdir of |temp_dir_|, to permit tests to safely + // remove the cache directory without risking collisions with other tests. + cache_path_ = temp_dir_.GetPath().AppendASCII("cache"); + CHECK(base::CreateDirectory(cache_path_)); } DiskCacheTest::~DiskCacheTest() = default; @@ -68,9 +71,12 @@ DiskCacheTestWithCache::TestIterator::~TestIterator() = default; int DiskCacheTestWithCache::TestIterator::OpenNextEntry( disk_cache::Entry** next_entry) { - net::TestCompletionCallback cb; - int rv = iterator_->OpenNextEntry(next_entry, cb.callback()); - return cb.GetResult(rv); + TestEntryResultCompletionCallback cb; + disk_cache::EntryResult result = + cb.GetResult(iterator_->OpenNextEntry(cb.callback())); + int rv = result.net_error(); + *next_entry = result.ReleaseEntry(); + return rv; } DiskCacheTestWithCache::DiskCacheTestWithCache() @@ -133,20 +139,18 @@ void DiskCacheTestWithCache::SetMaxSize(int64_t size, bool should_succeed) { EXPECT_EQ(should_succeed, mem_cache_->SetMaxSize(size)); } -int DiskCacheTestWithCache::OpenOrCreateEntry( - const std::string& key, - disk_cache::EntryWithOpened* entry_struct) { - return OpenOrCreateEntryWithPriority(key, net::HIGHEST, entry_struct); +disk_cache::EntryResult DiskCacheTestWithCache::OpenOrCreateEntry( + const std::string& key) { + return OpenOrCreateEntryWithPriority(key, net::HIGHEST); } -int DiskCacheTestWithCache::OpenOrCreateEntryWithPriority( +disk_cache::EntryResult DiskCacheTestWithCache::OpenOrCreateEntryWithPriority( const std::string& key, - net::RequestPriority request_priority, - disk_cache::EntryWithOpened* entry_struct) { - net::TestCompletionCallback cb; - int rv = cache_->OpenOrCreateEntry(key, request_priority, entry_struct, - cb.callback()); - return cb.GetResult(rv); + net::RequestPriority request_priority) { + TestEntryResultCompletionCallback cb; + disk_cache::EntryResult result = + cache_->OpenOrCreateEntry(key, request_priority, cb.callback()); + return cb.GetResult(std::move(result)); } int DiskCacheTestWithCache::OpenEntry(const std::string& key, @@ -158,9 +162,12 @@ int DiskCacheTestWithCache::OpenEntryWithPriority( const std::string& key, net::RequestPriority request_priority, disk_cache::Entry** entry) { - net::TestCompletionCallback cb; - int rv = cache_->OpenEntry(key, request_priority, entry, cb.callback()); - return cb.GetResult(rv); + TestEntryResultCompletionCallback cb; + disk_cache::EntryResult result = + cb.GetResult(cache_->OpenEntry(key, request_priority, cb.callback())); + int rv = result.net_error(); + *entry = result.ReleaseEntry(); + return rv; } int DiskCacheTestWithCache::CreateEntry(const std::string& key, @@ -172,9 +179,12 @@ int DiskCacheTestWithCache::CreateEntryWithPriority( const std::string& key, net::RequestPriority request_priority, disk_cache::Entry** entry) { - net::TestCompletionCallback cb; - int rv = cache_->CreateEntry(key, request_priority, entry, cb.callback()); - return cb.GetResult(rv); + TestEntryResultCompletionCallback cb; + disk_cache::EntryResult result = + cb.GetResult(cache_->CreateEntry(key, request_priority, cb.callback())); + int rv = result.net_error(); + *entry = result.ReleaseEntry(); + return rv; } int DiskCacheTestWithCache::DoomEntry(const std::string& key) { @@ -387,9 +397,10 @@ void DiskCacheTestWithCache::CreateBackend(uint32_t flags) { cache_ = std::move(simple_backend); if (simple_cache_wait_for_index_) { net::TestCompletionCallback wait_for_index_cb; - rv = simple_cache_impl_->index()->ExecuteWhenReady( + simple_cache_impl_->index()->ExecuteWhenReady( wait_for_index_cb.callback()); - ASSERT_THAT(wait_for_index_cb.GetResult(rv), IsOk()); + rv = wait_for_index_cb.WaitForResult(); + ASSERT_THAT(rv, IsOk()); } return; } diff --git a/chromium/net/disk_cache/disk_cache_test_base.h b/chromium/net/disk_cache/disk_cache_test_base.h index 595a4767f7c..9d00822e84c 100644 --- a/chromium/net/disk_cache/disk_cache_test_base.h +++ b/chromium/net/disk_cache/disk_cache_test_base.h @@ -15,7 +15,7 @@ #include "base/threading/thread.h" #include "net/base/cache_type.h" #include "net/disk_cache/disk_cache.h" -#include "net/test/test_with_scoped_task_environment.h" +#include "net/test/test_with_task_environment.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/platform_test.h" @@ -40,8 +40,7 @@ class SimpleFileTracker; // Mac, so this needs to be a PlatformTest. Even tests that do not require a // cache (and that do not need to be a DiskCacheTestWithCache) are susceptible // to this problem; all such tests should use TEST_F(DiskCacheTest, ...). -class DiskCacheTest : public PlatformTest, - public net::WithScopedTaskEnvironment { +class DiskCacheTest : public PlatformTest, public net::WithTaskEnvironment { protected: DiskCacheTest(); ~DiskCacheTest() override; @@ -132,11 +131,12 @@ class DiskCacheTestWithCache : public DiskCacheTest { } // Utility methods to access the cache and wait for each operation to finish. - int OpenOrCreateEntry(const std::string& key, - disk_cache::EntryWithOpened* entry_struct); - int OpenOrCreateEntryWithPriority(const std::string& key, - net::RequestPriority request_priority, - disk_cache::EntryWithOpened* entry_struct); + // Also closer to legacy API. + // TODO(morlovich): Port all the tests to EntryResult. + disk_cache::EntryResult OpenOrCreateEntry(const std::string& key); + disk_cache::EntryResult OpenOrCreateEntryWithPriority( + const std::string& key, + net::RequestPriority request_priority); int OpenEntry(const std::string& key, disk_cache::Entry** entry); int OpenEntryWithPriority(const std::string& key, net::RequestPriority request_priority, diff --git a/chromium/net/disk_cache/disk_cache_test_util.cc b/chromium/net/disk_cache/disk_cache_test_util.cc index 8af0da2e8f7..651533b1fe6 100644 --- a/chromium/net/disk_cache/disk_cache_test_util.cc +++ b/chromium/net/disk_cache/disk_cache_test_util.cc @@ -80,6 +80,20 @@ bool CheckCacheIntegrity(const base::FilePath& path, // ----------------------------------------------------------------------- +TestEntryResultCompletionCallback::TestEntryResultCompletionCallback() = + default; + +TestEntryResultCompletionCallback::~TestEntryResultCompletionCallback() = + default; + +disk_cache::Backend::EntryResultCallback +TestEntryResultCompletionCallback::callback() { + return base::BindOnce(&TestEntryResultCompletionCallback::SetResult, + base::Unretained(this)); +} + +// ----------------------------------------------------------------------- + MessageLoopHelper::MessageLoopHelper() : num_callbacks_(0), num_iterations_(0), @@ -148,3 +162,8 @@ void CallbackTest::Run(int result) { helper_->CallbackWasCalled(); } + +void CallbackTest::RunWithEntry(disk_cache::EntryResult result) { + last_entry_result_ = std::move(result); + Run(last_entry_result_.net_error()); +} diff --git a/chromium/net/disk_cache/disk_cache_test_util.h b/chromium/net/disk_cache/disk_cache_test_util.h index a79fa0710fc..24c7573462b 100644 --- a/chromium/net/disk_cache/disk_cache_test_util.h +++ b/chromium/net/disk_cache/disk_cache_test_util.h @@ -15,6 +15,8 @@ #include "base/run_loop.h" #include "base/timer/timer.h" #include "build/build_config.h" +#include "net/base/test_completion_callback.h" +#include "net/disk_cache/disk_cache.h" // Re-creates a given test file inside the cache test folder. bool CreateCacheTestFile(const base::FilePath& name); @@ -37,6 +39,31 @@ bool CheckCacheIntegrity(const base::FilePath& path, // ----------------------------------------------------------------------- +// Like net::TestCompletionCallback, but for EntryResultCallback. + +struct EntryResultIsPendingHelper { + bool operator()(const disk_cache::EntryResult& result) const { + return result.net_error() == net::ERR_IO_PENDING; + } +}; +using TestEntryResultCompletionCallbackBase = + net::internal::TestCompletionCallbackTemplate<disk_cache::EntryResult, + EntryResultIsPendingHelper>; + +class TestEntryResultCompletionCallback + : public TestEntryResultCompletionCallbackBase { + public: + TestEntryResultCompletionCallback(); + ~TestEntryResultCompletionCallback() override; + + disk_cache::Backend::EntryResultCallback callback(); + + private: + DISALLOW_COPY_AND_ASSIGN(TestEntryResultCompletionCallback); +}; + +// ----------------------------------------------------------------------- + // Simple helper to deal with the message loop on a test. class MessageLoopHelper { public: @@ -98,13 +125,18 @@ class CallbackTest { ~CallbackTest(); void Run(int result); + void RunWithEntry(disk_cache::EntryResult result); int last_result() const { return last_result_; } + disk_cache::EntryResult ReleaseLastEntryResult() { + return std::move(last_entry_result_); + } private: MessageLoopHelper* helper_; int reuse_; int last_result_; + disk_cache::EntryResult last_entry_result_; DISALLOW_COPY_AND_ASSIGN(CallbackTest); }; diff --git a/chromium/net/disk_cache/entry_unittest.cc b/chromium/net/disk_cache/entry_unittest.cc index f39812a5287..045fcb32bc0 100644 --- a/chromium/net/disk_cache/entry_unittest.cc +++ b/chromium/net/disk_cache/entry_unittest.cc @@ -44,6 +44,8 @@ using net::test::IsError; using net::test::IsOk; using base::Time; +using disk_cache::EntryResult; +using disk_cache::EntryResultCallback; using disk_cache::ScopedEntryPtr; // Tests that can run with different types of caches. @@ -2656,6 +2658,67 @@ TEST_F(DiskCacheEntryTest, KeySanityCheck) { DisableIntegrityCheck(); } +TEST_F(DiskCacheEntryTest, KeySanityCheck2) { + UseCurrentThread(); + InitCache(); + std::string key("the first key"); + disk_cache::Entry* entry; + ASSERT_THAT(CreateEntry(key, &entry), IsOk()); + + disk_cache::EntryImpl* entry_impl = + static_cast<disk_cache::EntryImpl*>(entry); + disk_cache::EntryStore* store = entry_impl->entry()->Data(); + + // Fill in the rest of inline key store with non-nulls. Unlike in + // KeySanityCheck, this does not change the length to identify it as + // stored under |long_key|. + memset(store->key + key.size(), 'k', sizeof(store->key) - key.size()); + entry_impl->entry()->set_modified(); + entry->Close(); + + // We have a corrupt entry. Now reload it. We should NOT read beyond the + // allocated buffer here. + ASSERT_NE(net::OK, OpenEntry(key, &entry)); + DisableIntegrityCheck(); +} + +TEST_F(DiskCacheEntryTest, KeySanityCheck3) { + const size_t kVeryLong = 40 * 1024; + UseCurrentThread(); + InitCache(); + std::string key(kVeryLong, 'a'); + disk_cache::Entry* entry; + ASSERT_THAT(CreateEntry(key, &entry), IsOk()); + + disk_cache::EntryImpl* entry_impl = + static_cast<disk_cache::EntryImpl*>(entry); + disk_cache::EntryStore* store = entry_impl->entry()->Data(); + + // Test meaningful when using long keys; and also want this to be + // an external file to avoid needing to duplicate offset math here. + disk_cache::Addr key_addr(store->long_key); + ASSERT_TRUE(key_addr.is_initialized()); + ASSERT_TRUE(key_addr.is_separate_file()); + + // Close the entry before messing up its files. + entry->Close(); + + // Mess up the terminating null in the external key file. + auto key_file = + base::MakeRefCounted<disk_cache::File>(true /* want sync ops*/); + ASSERT_TRUE(key_file->Init(cache_impl_->GetFileName(key_addr))); + + ASSERT_TRUE(key_file->Write("b", 1u, kVeryLong)); + key_file = nullptr; + + // This case gets graceful recovery. + ASSERT_THAT(OpenEntry(key, &entry), IsOk()); + + // Make sure the key object isn't messed up. + EXPECT_EQ(kVeryLong, strlen(entry->GetKey().data())); + entry->Close(); +} + TEST_F(DiskCacheEntryTest, SimpleCacheInternalAsyncIO) { SetSimpleCacheMode(); InitCache(); @@ -3003,18 +3066,17 @@ TEST_F(DiskCacheEntryTest, SimpleCacheQueuedOpenOnDoomedEntry) { entry->Close(); - disk_cache::Entry* entry2 = nullptr; // Done via cache_ -> no event loop. - net::TestCompletionCallback cb; - ASSERT_EQ(net::ERR_IO_PENDING, - cache_->OpenEntry(key, net::HIGHEST, &entry2, cb.callback())); + TestEntryResultCompletionCallback cb; + EntryResult result = cache_->OpenEntry(key, net::HIGHEST, cb.callback()); + ASSERT_EQ(net::ERR_IO_PENDING, result.net_error()); net::TestCompletionCallback cb2; cache_->DoomEntry(key, net::HIGHEST, cb2.callback()); // Now event loop. - EXPECT_EQ(net::OK, cb.WaitForResult()); - ASSERT_TRUE(entry2 != nullptr); - entry2->Close(); + result = cb.WaitForResult(); + EXPECT_EQ(net::OK, result.net_error()); + result.ReleaseEntry()->Close(); EXPECT_EQ(net::OK, cb2.WaitForResult()); EXPECT_EQ(0, cache_->GetEntryCount()); @@ -3224,13 +3286,14 @@ TEST_F(DiskCacheEntryTest, SimpleCacheOptimistic) { CacheTestFillBuffer(buffer1->data(), kSize1, false); CacheTestFillBuffer(buffer2->data(), kSize2, false); - disk_cache::Entry* entry = nullptr; // Create is optimistic, must return OK. - ASSERT_EQ(net::OK, - cache_->CreateEntry(key, net::HIGHEST, &entry, - base::BindOnce(&CallbackTest::Run, - base::Unretained(&callback1)))); - EXPECT_NE(null, entry); + EntryResult result = + cache_->CreateEntry(key, net::HIGHEST, + base::BindOnce(&CallbackTest::RunWithEntry, + base::Unretained(&callback1))); + ASSERT_EQ(net::OK, result.net_error()); + disk_cache::Entry* entry = result.ReleaseEntry(); + ASSERT_NE(null, entry); ScopedEntryPtr entry_closer(entry); // This write may or may not be optimistic (it depends if the previous @@ -3281,32 +3344,35 @@ TEST_F(DiskCacheEntryTest, SimpleCacheOptimistic2) { // Create, Open, Close, Close. SetSimpleCacheMode(); InitCache(); - disk_cache::Entry* null = nullptr; const char key[] = "the first key"; MessageLoopHelper helper; CallbackTest callback1(&helper, false); CallbackTest callback2(&helper, false); - disk_cache::Entry* entry = nullptr; - ASSERT_EQ(net::OK, - cache_->CreateEntry(key, net::HIGHEST, &entry, - base::BindOnce(&CallbackTest::Run, - base::Unretained(&callback1)))); - EXPECT_NE(null, entry); + EntryResult result = + cache_->CreateEntry(key, net::HIGHEST, + base::BindOnce(&CallbackTest::RunWithEntry, + base::Unretained(&callback1))); + ASSERT_EQ(net::OK, result.net_error()); + disk_cache::Entry* entry = result.ReleaseEntry(); + ASSERT_NE(nullptr, entry); ScopedEntryPtr entry_closer(entry); - disk_cache::Entry* entry2 = nullptr; - ASSERT_EQ(net::ERR_IO_PENDING, - cache_->OpenEntry(key, net::HIGHEST, &entry2, - base::BindOnce(&CallbackTest::Run, - base::Unretained(&callback2)))); + EntryResult result2 = + cache_->OpenEntry(key, net::HIGHEST, + base::BindOnce(&CallbackTest::RunWithEntry, + base::Unretained(&callback2))); + ASSERT_EQ(net::ERR_IO_PENDING, result2.net_error()); ASSERT_TRUE(helper.WaitUntilCacheIoFinished(1)); - - EXPECT_NE(null, entry2); + result2 = callback2.ReleaseLastEntryResult(); + EXPECT_EQ(net::OK, result2.net_error()); + disk_cache::Entry* entry2 = result2.ReleaseEntry(); + EXPECT_NE(nullptr, entry2); EXPECT_EQ(entry, entry2); // We have to call close twice, since we called create and open above. + // (the other closes is from |entry_closer|). entry->Close(); // Check that we are not leaking. @@ -3319,23 +3385,24 @@ TEST_F(DiskCacheEntryTest, SimpleCacheOptimistic3) { // Create, Close, Open, Close. SetSimpleCacheMode(); InitCache(); - disk_cache::Entry* null = nullptr; const char key[] = "the first key"; - disk_cache::Entry* entry = nullptr; - ASSERT_EQ(net::OK, cache_->CreateEntry(key, net::HIGHEST, &entry, - net::CompletionOnceCallback())); - EXPECT_NE(null, entry); + EntryResult result = + cache_->CreateEntry(key, net::HIGHEST, EntryResultCallback()); + ASSERT_EQ(net::OK, result.net_error()); + disk_cache::Entry* entry = result.ReleaseEntry(); + ASSERT_NE(nullptr, entry); entry->Close(); - net::TestCompletionCallback cb; - disk_cache::Entry* entry2 = nullptr; - ASSERT_EQ(net::ERR_IO_PENDING, - cache_->OpenEntry(key, net::HIGHEST, &entry2, cb.callback())); - ASSERT_THAT(cb.GetResult(net::ERR_IO_PENDING), IsOk()); + TestEntryResultCompletionCallback cb; + EntryResult result2 = cache_->OpenEntry(key, net::HIGHEST, cb.callback()); + ASSERT_EQ(net::ERR_IO_PENDING, result2.net_error()); + result2 = cb.WaitForResult(); + ASSERT_THAT(result2.net_error(), IsOk()); + disk_cache::Entry* entry2 = result2.ReleaseEntry(); ScopedEntryPtr entry_closer(entry2); - EXPECT_NE(null, entry2); + EXPECT_NE(nullptr, entry2); EXPECT_EQ(entry, entry2); // Check that we are not leaking. @@ -3348,7 +3415,6 @@ TEST_F(DiskCacheEntryTest, SimpleCacheOptimistic4) { // Create, Close, Write, Open, Open, Close, Write, Read, Close. SetSimpleCacheMode(); InitCache(); - disk_cache::Entry* null = nullptr; const char key[] = "the first key"; net::TestCompletionCallback cb; @@ -3356,11 +3422,12 @@ TEST_F(DiskCacheEntryTest, SimpleCacheOptimistic4) { scoped_refptr<net::IOBuffer> buffer1 = base::MakeRefCounted<net::IOBuffer>(kSize1); CacheTestFillBuffer(buffer1->data(), kSize1, false); - disk_cache::Entry* entry = nullptr; - ASSERT_EQ(net::OK, cache_->CreateEntry(key, net::HIGHEST, &entry, - net::CompletionOnceCallback())); - EXPECT_NE(null, entry); + EntryResult result = + cache_->CreateEntry(key, net::HIGHEST, EntryResultCallback()); + ASSERT_EQ(net::OK, result.net_error()); + disk_cache::Entry* entry = result.ReleaseEntry(); + ASSERT_NE(nullptr, entry); entry->Close(); // Lets do a Write so we block until both the Close and the Write @@ -3376,17 +3443,20 @@ TEST_F(DiskCacheEntryTest, SimpleCacheOptimistic4) { // At this point the |entry| must have been destroyed, and called // RemoveSelfFromBackend(). - disk_cache::Entry* entry2 = nullptr; - ASSERT_EQ(net::ERR_IO_PENDING, - cache_->OpenEntry(key, net::HIGHEST, &entry2, cb.callback())); - ASSERT_THAT(cb.GetResult(net::ERR_IO_PENDING), IsOk()); - EXPECT_NE(null, entry2); - - disk_cache::Entry* entry3 = nullptr; - ASSERT_EQ(net::ERR_IO_PENDING, - cache_->OpenEntry(key, net::HIGHEST, &entry3, cb.callback())); - ASSERT_THAT(cb.GetResult(net::ERR_IO_PENDING), IsOk()); - EXPECT_NE(null, entry3); + TestEntryResultCompletionCallback cb2; + EntryResult result2 = cache_->OpenEntry(key, net::HIGHEST, cb2.callback()); + ASSERT_EQ(net::ERR_IO_PENDING, result2.net_error()); + result2 = cb2.WaitForResult(); + ASSERT_THAT(result2.net_error(), IsOk()); + disk_cache::Entry* entry2 = result2.ReleaseEntry(); + EXPECT_NE(nullptr, entry2); + + EntryResult result3 = cache_->OpenEntry(key, net::HIGHEST, cb2.callback()); + ASSERT_EQ(net::ERR_IO_PENDING, result3.net_error()); + result3 = cb2.WaitForResult(); + ASSERT_THAT(result3.net_error(), IsOk()); + disk_cache::Entry* entry3 = result3.ReleaseEntry(); + EXPECT_NE(nullptr, entry3); EXPECT_EQ(entry2, entry3); entry3->Close(); @@ -3414,7 +3484,6 @@ TEST_F(DiskCacheEntryTest, SimpleCacheOptimistic5) { // Create, Doom, Write, Read, Close. SetSimpleCacheMode(); InitCache(); - disk_cache::Entry* null = nullptr; const char key[] = "the first key"; net::TestCompletionCallback cb; @@ -3422,11 +3491,12 @@ TEST_F(DiskCacheEntryTest, SimpleCacheOptimistic5) { scoped_refptr<net::IOBuffer> buffer1 = base::MakeRefCounted<net::IOBuffer>(kSize1); CacheTestFillBuffer(buffer1->data(), kSize1, false); - disk_cache::Entry* entry = nullptr; - ASSERT_EQ(net::OK, cache_->CreateEntry(key, net::HIGHEST, &entry, - net::CompletionOnceCallback())); - EXPECT_NE(null, entry); + EntryResult result = + cache_->CreateEntry(key, net::HIGHEST, EntryResultCallback()); + ASSERT_EQ(net::OK, result.net_error()); + disk_cache::Entry* entry = result.ReleaseEntry(); + ASSERT_NE(nullptr, entry); ScopedEntryPtr entry_closer(entry); entry->Doom(); @@ -3449,7 +3519,6 @@ TEST_F(DiskCacheEntryTest, SimpleCacheOptimistic6) { // Create, Write, Doom, Doom, Read, Doom, Close. SetSimpleCacheMode(); InitCache(); - disk_cache::Entry* null = nullptr; const char key[] = "the first key"; net::TestCompletionCallback cb; @@ -3459,11 +3528,12 @@ TEST_F(DiskCacheEntryTest, SimpleCacheOptimistic6) { scoped_refptr<net::IOBuffer> buffer1_read = base::MakeRefCounted<net::IOBuffer>(kSize1); CacheTestFillBuffer(buffer1->data(), kSize1, false); - disk_cache::Entry* entry = nullptr; - ASSERT_EQ(net::OK, cache_->CreateEntry(key, net::HIGHEST, &entry, - net::CompletionOnceCallback())); - EXPECT_NE(null, entry); + EntryResult result = + cache_->CreateEntry(key, net::HIGHEST, EntryResultCallback()); + ASSERT_EQ(net::OK, result.net_error()); + disk_cache::Entry* entry = result.ReleaseEntry(); + EXPECT_NE(nullptr, entry); ScopedEntryPtr entry_closer(entry); EXPECT_EQ( @@ -3490,11 +3560,12 @@ TEST_F(DiskCacheEntryTest, SimpleCacheOptimisticWriteReleases) { InitCache(); const char key[] = "the first key"; - disk_cache::Entry* entry = nullptr; // First, an optimistic create. - ASSERT_EQ(net::OK, cache_->CreateEntry(key, net::HIGHEST, &entry, - net::CompletionOnceCallback())); + EntryResult result = + cache_->CreateEntry(key, net::HIGHEST, EntryResultCallback()); + ASSERT_EQ(net::OK, result.net_error()); + disk_cache::Entry* entry = result.ReleaseEntry(); ASSERT_TRUE(entry); ScopedEntryPtr entry_closer(entry); @@ -3523,7 +3594,6 @@ TEST_F(DiskCacheEntryTest, SimpleCacheCreateDoomRace) { // Create, Doom, Write, Close, Check files are not on disk anymore. SetSimpleCacheMode(); InitCache(); - disk_cache::Entry* null = nullptr; const char key[] = "the first key"; net::TestCompletionCallback cb; @@ -3531,11 +3601,12 @@ TEST_F(DiskCacheEntryTest, SimpleCacheCreateDoomRace) { scoped_refptr<net::IOBuffer> buffer1 = base::MakeRefCounted<net::IOBuffer>(kSize1); CacheTestFillBuffer(buffer1->data(), kSize1, false); - disk_cache::Entry* entry = nullptr; - ASSERT_EQ(net::OK, cache_->CreateEntry(key, net::HIGHEST, &entry, - net::CompletionOnceCallback())); - EXPECT_NE(null, entry); + EntryResult result = + cache_->CreateEntry(key, net::HIGHEST, EntryResultCallback()); + ASSERT_EQ(net::OK, result.net_error()); + disk_cache::Entry* entry = result.ReleaseEntry(); + EXPECT_NE(nullptr, entry); EXPECT_THAT(cache_->DoomEntry(key, net::HIGHEST, cb.callback()), IsError(net::ERR_IO_PENDING)); @@ -3566,26 +3637,25 @@ TEST_F(DiskCacheEntryTest, SimpleCacheDoomCreateRace) { SetCacheType(net::APP_CACHE); SetSimpleCacheMode(); InitCache(); - disk_cache::Entry* null = nullptr; const char key[] = "the first key"; - net::TestCompletionCallback create_callback; + TestEntryResultCompletionCallback create_callback; - disk_cache::Entry* entry1 = nullptr; - ASSERT_EQ(net::OK, - create_callback.GetResult(cache_->CreateEntry( - key, net::HIGHEST, &entry1, create_callback.callback()))); + EntryResult result1 = create_callback.GetResult( + cache_->CreateEntry(key, net::HIGHEST, create_callback.callback())); + ASSERT_EQ(net::OK, result1.net_error()); + disk_cache::Entry* entry1 = result1.ReleaseEntry(); ScopedEntryPtr entry1_closer(entry1); - EXPECT_NE(null, entry1); + EXPECT_NE(nullptr, entry1); net::TestCompletionCallback doom_callback; EXPECT_EQ(net::ERR_IO_PENDING, cache_->DoomEntry(key, net::HIGHEST, doom_callback.callback())); - disk_cache::Entry* entry2 = nullptr; - ASSERT_EQ(net::OK, - create_callback.GetResult(cache_->CreateEntry( - key, net::HIGHEST, &entry2, create_callback.callback()))); + EntryResult result2 = create_callback.GetResult( + cache_->CreateEntry(key, net::HIGHEST, create_callback.callback())); + ASSERT_EQ(net::OK, result2.net_error()); + disk_cache::Entry* entry2 = result2.ReleaseEntry(); ScopedEntryPtr entry2_closer(entry2); EXPECT_THAT(doom_callback.GetResult(net::ERR_IO_PENDING), IsOk()); } @@ -3605,13 +3675,15 @@ TEST_F(DiskCacheEntryTest, SimpleCacheDoomCreateOptimistic) { net::TestCompletionCallback doom_callback; cache_->DoomEntry(kKey, net::HIGHEST, doom_callback.callback()); - disk_cache::Entry* entry2 = nullptr; - net::TestCompletionCallback create_callback; + TestEntryResultCompletionCallback create_callback; // Open entry2, with same key. With optimistic ops, this should succeed // immediately, hence us using cache_->CreateEntry directly rather than using // the DiskCacheTestWithCache::CreateEntry wrapper which blocks when needed. - ASSERT_EQ(net::OK, cache_->CreateEntry(kKey, net::HIGHEST, &entry2, - create_callback.callback())); + EntryResult result2 = + cache_->CreateEntry(kKey, net::HIGHEST, create_callback.callback()); + ASSERT_EQ(net::OK, result2.net_error()); + disk_cache::Entry* entry2 = result2.ReleaseEntry(); + ASSERT_NE(nullptr, entry2); // Do some I/O to make sure it's alive. const int kSize = 2048; @@ -3647,13 +3719,15 @@ TEST_F(DiskCacheEntryTest, SimpleCacheDoomCreateOptimisticMassDoom) { net::TestCompletionCallback doom_callback; cache_->DoomEntry(kKey, net::HIGHEST, doom_callback.callback()); - disk_cache::Entry* entry2 = nullptr; - net::TestCompletionCallback create_callback; + TestEntryResultCompletionCallback create_callback; // Open entry2, with same key. With optimistic ops, this should succeed // immediately, hence us using cache_->CreateEntry directly rather than using // the DiskCacheTestWithCache::CreateEntry wrapper which blocks when needed. - ASSERT_EQ(net::OK, cache_->CreateEntry(kKey, net::HIGHEST, &entry2, - create_callback.callback())); + EntryResult result = + cache_->CreateEntry(kKey, net::HIGHEST, create_callback.callback()); + ASSERT_EQ(net::OK, result.net_error()); + disk_cache::Entry* entry2 = result.ReleaseEntry(); + ASSERT_NE(nullptr, entry2); net::TestCompletionCallback doomall_callback; @@ -3685,10 +3759,11 @@ TEST_F(DiskCacheEntryTest, SimpleCacheDoomOpenOptimistic) { // Try to open entry. This should detect a miss immediately, since it's // the only thing after a doom. - disk_cache::Entry* entry2 = nullptr; - net::TestCompletionCallback open_callback; - EXPECT_EQ(net::ERR_FAILED, cache_->OpenEntry(kKey, net::HIGHEST, &entry2, - open_callback.callback())); + + EntryResult result2 = + cache_->OpenEntry(kKey, net::HIGHEST, EntryResultCallback()); + EXPECT_EQ(net::ERR_FAILED, result2.net_error()); + EXPECT_EQ(nullptr, result2.ReleaseEntry()); doom_callback.WaitForResult(); } @@ -3793,14 +3868,15 @@ TEST_F(DiskCacheEntryTest, SimpleCacheOptimisticCreateFailsOnOpen) { // Create a corrupt file in place of a future entry. Optimistic create should // initially succeed, but realize later that creation failed. const std::string key = "the key"; - net::TestCompletionCallback cb; disk_cache::Entry* entry = nullptr; disk_cache::Entry* entry2 = nullptr; EXPECT_TRUE(disk_cache::simple_util::CreateCorruptFileForTests( key, cache_path_)); - EXPECT_THAT(cache_->CreateEntry(key, net::HIGHEST, &entry, cb.callback()), - IsOk()); + EntryResult result = + cache_->CreateEntry(key, net::HIGHEST, EntryResultCallback()); + EXPECT_THAT(result.net_error(), IsOk()); + entry = result.ReleaseEntry(); ASSERT_TRUE(entry); ScopedEntryPtr entry_closer(entry); ASSERT_NE(net::OK, OpenEntry(key, &entry2)); @@ -3937,9 +4013,10 @@ TEST_F(DiskCacheEntryTest, SimpleCacheInFlightRead) { InitCache(); const char key[] = "the first key"; - disk_cache::Entry* entry = nullptr; - ASSERT_EQ(net::OK, cache_->CreateEntry(key, net::HIGHEST, &entry, - net::CompletionOnceCallback())); + EntryResult result = + cache_->CreateEntry(key, net::HIGHEST, EntryResultCallback()); + ASSERT_EQ(net::OK, result.net_error()); + disk_cache::Entry* entry = result.ReleaseEntry(); ScopedEntryPtr entry_closer(entry); const int kBufferSize = 1024; @@ -3981,15 +4058,16 @@ TEST_F(DiskCacheEntryTest, SimpleCacheOpenCreateRaceWithNoIndex) { // Assume the index is not initialized, which is likely, since we are blocking // the IO thread from executing the index finalization step. - disk_cache::Entry* entry1; - net::TestCompletionCallback cb1; - disk_cache::Entry* entry2; - net::TestCompletionCallback cb2; - int rv1 = cache_->OpenEntry("key", net::HIGHEST, &entry1, cb1.callback()); - int rv2 = cache_->CreateEntry("key", net::HIGHEST, &entry2, cb2.callback()); + TestEntryResultCompletionCallback cb1; + TestEntryResultCompletionCallback cb2; + EntryResult rv1 = cache_->OpenEntry("key", net::HIGHEST, cb1.callback()); + EntryResult rv2 = cache_->CreateEntry("key", net::HIGHEST, cb2.callback()); - EXPECT_THAT(cb1.GetResult(rv1), IsError(net::ERR_FAILED)); - ASSERT_THAT(cb2.GetResult(rv2), IsOk()); + rv1 = cb1.GetResult(std::move(rv1)); + EXPECT_THAT(rv1.net_error(), IsError(net::ERR_FAILED)); + rv2 = cb2.GetResult(std::move(rv2)); + ASSERT_THAT(rv2.net_error(), IsOk()); + disk_cache::Entry* entry2 = rv2.ReleaseEntry(); // Try to get an alias for entry2. Open should succeed, and return the same // pointer. @@ -5348,8 +5426,6 @@ TEST_F(DiskCacheEntryTest, SimpleCacheCloseResurrection) { disk_cache::SimpleBackendImpl::FlushWorkerPoolForTesting(); base::RunLoop().RunUntilIdle(); - disk_cache::Entry* entry2 = nullptr; - net::TestCompletionCallback cb_open; int rv = entry->WriteData(1, 0, buffer.get(), kSize, net::CompletionOnceCallback(), false); @@ -5357,15 +5433,19 @@ TEST_F(DiskCacheEntryTest, SimpleCacheCloseResurrection) { ASSERT_EQ(kSize, rv); // Since the write is still pending, the open will get queued... - int rv2 = cache_->OpenEntry(kKey, net::HIGHEST, &entry2, cb_open.callback()); - EXPECT_EQ(net::ERR_IO_PENDING, rv2); + TestEntryResultCompletionCallback cb_open; + EntryResult result2 = + cache_->OpenEntry(kKey, net::HIGHEST, cb_open.callback()); + EXPECT_EQ(net::ERR_IO_PENDING, result2.net_error()); // ... as the open is queued, this Close will temporarily reduce the number // of external references to 0. This should not break things. entry->Close(); // Wait till open finishes. - ASSERT_EQ(net::OK, cb_open.GetResult(rv2)); + result2 = cb_open.GetResult(std::move(result2)); + ASSERT_EQ(net::OK, result2.net_error()); + disk_cache::Entry* entry2 = result2.ReleaseEntry(); ASSERT_TRUE(entry2 != nullptr); // Get first close a chance to finish. diff --git a/chromium/net/disk_cache/memory/mem_backend_impl.cc b/chromium/net/disk_cache/memory/mem_backend_impl.cc index bddd885827e..f0d1f3af6ff 100644 --- a/chromium/net/disk_cache/memory/mem_backend_impl.cc +++ b/chromium/net/disk_cache/memory/mem_backend_impl.cc @@ -164,52 +164,42 @@ int32_t MemBackendImpl::GetEntryCount() const { return static_cast<int32_t>(entries_.size()); } -net::Error MemBackendImpl::OpenOrCreateEntry(const std::string& key, - net::RequestPriority priority, - EntryWithOpened* entry_struct, - CompletionOnceCallback callback) { - net::Error rv = OpenEntry(key, priority, &(entry_struct->entry), - CompletionOnceCallback()); - if (rv == net::OK) { - entry_struct->opened = true; - return rv; - } +EntryResult MemBackendImpl::OpenOrCreateEntry(const std::string& key, + net::RequestPriority priority, + EntryResultCallback callback) { + EntryResult result = OpenEntry(key, priority, EntryResultCallback()); + if (result.net_error() == net::OK) + return result; + // Key was not opened, try creating it instead. - rv = CreateEntry(key, priority, &(entry_struct->entry), - CompletionOnceCallback()); - entry_struct->opened = false; - return rv; + return CreateEntry(key, priority, EntryResultCallback()); } -net::Error MemBackendImpl::OpenEntry(const std::string& key, - net::RequestPriority request_priority, - Entry** entry, - CompletionOnceCallback callback) { +EntryResult MemBackendImpl::OpenEntry(const std::string& key, + net::RequestPriority request_priority, + EntryResultCallback callback) { auto it = entries_.find(key); if (it == entries_.end()) - return net::ERR_FAILED; + return EntryResult::MakeError(net::ERR_FAILED); it->second->Open(); - *entry = it->second; - return net::OK; + return EntryResult::MakeOpened(it->second); } -net::Error MemBackendImpl::CreateEntry(const std::string& key, - net::RequestPriority request_priority, - Entry** entry, - CompletionOnceCallback callback) { +EntryResult MemBackendImpl::CreateEntry(const std::string& key, + net::RequestPriority request_priority, + EntryResultCallback callback) { std::pair<EntryMap::iterator, bool> create_result = entries_.insert(EntryMap::value_type(key, nullptr)); const bool did_insert = create_result.second; if (!did_insert) - return net::ERR_FAILED; + return EntryResult::MakeError(net::ERR_FAILED); MemEntryImpl* cache_entry = new MemEntryImpl(weak_factory_.GetWeakPtr(), key, net_log_); create_result.first->second = cache_entry; - *entry = cache_entry; - return net::OK; + return EntryResult::MakeCreated(cache_entry); } net::Error MemBackendImpl::DoomEntry(const std::string& key, @@ -281,10 +271,9 @@ class MemBackendImpl::MemIterator final : public Backend::Iterator { explicit MemIterator(base::WeakPtr<MemBackendImpl> backend) : backend_(backend) {} - net::Error OpenNextEntry(Entry** next_entry, - CompletionOnceCallback callback) override { + EntryResult OpenNextEntry(EntryResultCallback callback) override { if (!backend_) - return net::ERR_FAILED; + return EntryResult::MakeError(net::ERR_FAILED); if (!backend_keys_) { backend_keys_ = std::make_unique<Strings>(backend_->entries_.size()); @@ -297,9 +286,8 @@ class MemBackendImpl::MemIterator final : public Backend::Iterator { while (true) { if (current_ == backend_keys_->end()) { - *next_entry = nullptr; backend_keys_.reset(); - return net::ERR_FAILED; + return EntryResult::MakeError(net::ERR_FAILED); } const auto& entry_iter = backend_->entries_.find(*current_); @@ -310,8 +298,7 @@ class MemBackendImpl::MemIterator final : public Backend::Iterator { } entry_iter->second->Open(); - *next_entry = entry_iter->second; - return net::OK; + return EntryResult::MakeOpened(entry_iter->second); } } diff --git a/chromium/net/disk_cache/memory/mem_backend_impl.h b/chromium/net/disk_cache/memory/mem_backend_impl.h index 046fed2a222..449741bd786 100644 --- a/chromium/net/disk_cache/memory/mem_backend_impl.h +++ b/chromium/net/disk_cache/memory/mem_backend_impl.h @@ -85,18 +85,15 @@ class NET_EXPORT_PRIVATE MemBackendImpl final : public Backend { // Backend interface. int32_t GetEntryCount() const override; - net::Error OpenOrCreateEntry(const std::string& key, - net::RequestPriority request_priority, - EntryWithOpened* entry_struct, - CompletionOnceCallback callback) override; - net::Error OpenEntry(const std::string& key, - net::RequestPriority request_priority, - Entry** entry, - CompletionOnceCallback callback) override; - net::Error CreateEntry(const std::string& key, - net::RequestPriority request_priority, - Entry** entry, - CompletionOnceCallback callback) override; + EntryResult OpenOrCreateEntry(const std::string& key, + net::RequestPriority request_priority, + EntryResultCallback callback) override; + EntryResult OpenEntry(const std::string& key, + net::RequestPriority request_priority, + EntryResultCallback callback) override; + EntryResult CreateEntry(const std::string& key, + net::RequestPriority request_priority, + EntryResultCallback callback) override; net::Error DoomEntry(const std::string& key, net::RequestPriority priority, CompletionOnceCallback callback) override; diff --git a/chromium/net/disk_cache/memory/mem_entry_impl.cc b/chromium/net/disk_cache/memory/mem_entry_impl.cc index bb9affc918b..93680d2aec2 100644 --- a/chromium/net/disk_cache/memory/mem_entry_impl.cc +++ b/chromium/net/disk_cache/memory/mem_entry_impl.cc @@ -103,8 +103,8 @@ MemEntryImpl::MemEntryImpl(base::WeakPtr<MemBackendImpl> backend, void MemEntryImpl::Open() { // Only a parent entry can be opened. DCHECK_EQ(PARENT_ENTRY, type()); + CHECK_NE(ref_count_, std::numeric_limits<uint32_t>::max()); ++ref_count_; - DCHECK_GE(ref_count_, 1); DCHECK(!doomed_); } @@ -144,6 +144,7 @@ void MemEntryImpl::Doom() { void MemEntryImpl::Close() { DCHECK_EQ(PARENT_ENTRY, type()); + CHECK_GT(ref_count_, 0u); --ref_count_; if (ref_count_ == 0 && !doomed_) { // At this point the user is clearly done writing, so make sure there isn't @@ -156,7 +157,6 @@ void MemEntryImpl::Close() { } } } - DCHECK_GE(ref_count_, 0); if (!ref_count_ && doomed_) delete this; } diff --git a/chromium/net/disk_cache/memory/mem_entry_impl.h b/chromium/net/disk_cache/memory/mem_entry_impl.h index a372dd5e9fa..be4934c02e3 100644 --- a/chromium/net/disk_cache/memory/mem_entry_impl.h +++ b/chromium/net/disk_cache/memory/mem_entry_impl.h @@ -179,7 +179,7 @@ class NET_EXPORT_PRIVATE MemEntryImpl final std::string key_; std::vector<char> data_[kNumStreams]; // User data. - int ref_count_; + uint32_t ref_count_; int64_t child_id_; // The ID of a child entry. int child_first_pos_; // The position of the first byte in a child diff --git a/chromium/net/disk_cache/simple/simple_backend_impl.cc b/chromium/net/disk_cache/simple/simple_backend_impl.cc index 018d6ae4d96..b01fce4d4a3 100644 --- a/chromium/net/disk_cache/simple/simple_backend_impl.cc +++ b/chromium/net/disk_cache/simple/simple_backend_impl.cc @@ -26,7 +26,7 @@ #include "base/sequenced_task_runner.h" #include "base/system/sys_info.h" #include "base/task/post_task.h" -#include "base/task/thread_pool/thread_pool.h" +#include "base/task/thread_pool/thread_pool_instance.h" #include "base/task_runner_util.h" #include "base/threading/sequenced_task_runner_handle.h" #include "base/time/time.h" @@ -143,6 +143,19 @@ void RunOperationAndCallback( copyable_callback.Run(operation_result); } +// Same but for things that work with EntryResult. +void RunEntryResultOperationAndCallback( + base::OnceCallback<EntryResult(EntryResultCallback)> operation, + EntryResultCallback operation_callback) { + base::RepeatingCallback<void(EntryResult)> copyable_callback; + if (operation_callback) + copyable_callback = + base::AdaptCallbackForRepeating(std::move(operation_callback)); + EntryResult operation_result = std::move(operation).Run(copyable_callback); + if (operation_result.net_error() != net::ERR_IO_PENDING && copyable_callback) + copyable_callback.Run(std::move(operation_result)); +} + void RecordIndexLoad(net::CacheType cache_type, base::TimeTicks constructed_since, int result) { @@ -206,8 +219,9 @@ SimpleBackendImpl::SimpleBackendImpl( file_tracker_(file_tracker ? file_tracker : g_simple_file_tracker.Pointer()), path_(path), - cache_runner_(base::CreateSequencedTaskRunnerWithTraits( - {base::MayBlock(), base::TaskPriority::USER_BLOCKING, + cache_runner_(base::CreateSequencedTaskRunner( + {base::ThreadPool(), base::MayBlock(), + base::TaskPriority::USER_BLOCKING, base::TaskShutdownBehavior::BLOCK_SHUTDOWN})), orig_max_size_(max_bytes), entry_operations_mode_((cache_type == net::DISK_CACHE || @@ -236,8 +250,8 @@ void SimpleBackendImpl::SetWorkerPoolForTesting( } net::Error SimpleBackendImpl::Init(CompletionOnceCallback completion_callback) { - auto worker_pool = base::CreateTaskRunnerWithTraits( - {base::MayBlock(), base::WithBaseSyncPrimitives(), + auto worker_pool = base::CreateTaskRunner( + {base::ThreadPool(), base::MayBlock(), base::WithBaseSyncPrimitives(), base::TaskPriority::USER_BLOCKING, base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}); @@ -366,10 +380,9 @@ int32_t SimpleBackendImpl::GetEntryCount() const { return index_->GetEntryCount(); } -net::Error SimpleBackendImpl::OpenEntry(const std::string& key, - net::RequestPriority request_priority, - Entry** entry, - CompletionOnceCallback callback) { +EntryResult SimpleBackendImpl::OpenEntry(const std::string& key, + net::RequestPriority request_priority, + EntryResultCallback callback) { const uint64_t entry_hash = simple_util::GetEntryHashKey(key); std::vector<PostDoomWaiter>* post_doom = nullptr; @@ -386,23 +399,24 @@ net::Error SimpleBackendImpl::OpenEntry(const std::string& key, net::NetLogEventType::SIMPLE_CACHE_ENTRY_OPEN_CALL); log_for_entry.AddEventWithNetErrorCode( net::NetLogEventType::SIMPLE_CACHE_ENTRY_OPEN_END, net::ERR_FAILED); - return net::ERR_FAILED; + return EntryResult::MakeError(net::ERR_FAILED); } - base::OnceCallback<net::Error(CompletionOnceCallback)> operation = + base::OnceCallback<EntryResult(EntryResultCallback)> operation = base::BindOnce(&SimpleBackendImpl::OpenEntry, base::Unretained(this), - key, request_priority, entry); - post_doom->emplace_back(base::BindOnce( - &RunOperationAndCallback, std::move(operation), std::move(callback))); - return net::ERR_IO_PENDING; + key, request_priority); + post_doom->emplace_back(base::BindOnce(&RunEntryResultOperationAndCallback, + std::move(operation), + std::move(callback))); + return EntryResult::MakeError(net::ERR_IO_PENDING); } - return simple_entry->OpenEntry(entry, std::move(callback)); + return simple_entry->OpenEntry(std::move(callback)); } -net::Error SimpleBackendImpl::CreateEntry(const std::string& key, - net::RequestPriority request_priority, - Entry** entry, - CompletionOnceCallback callback) { +EntryResult SimpleBackendImpl::CreateEntry( + const std::string& key, + net::RequestPriority request_priority, + EntryResultCallback callback) { DCHECK_LT(0u, key.size()); const uint64_t entry_hash = simple_util::GetEntryHashKey(key); @@ -419,22 +433,22 @@ net::Error SimpleBackendImpl::CreateEntry(const std::string& key, // If that doesn't work either, retry this once doom is done. if (!simple_entry) { - base::OnceCallback<net::Error(CompletionOnceCallback)> operation = + base::OnceCallback<EntryResult(EntryResultCallback)> operation = base::BindOnce(&SimpleBackendImpl::CreateEntry, base::Unretained(this), - key, request_priority, entry); - post_doom->emplace_back(base::BindOnce( - &RunOperationAndCallback, std::move(operation), std::move(callback))); - return net::ERR_IO_PENDING; + key, request_priority); + post_doom->emplace_back(base::BindOnce(&RunEntryResultOperationAndCallback, + std::move(operation), + std::move(callback))); + return EntryResult::MakeError(net::ERR_IO_PENDING); } - return simple_entry->CreateEntry(entry, std::move(callback)); + return simple_entry->CreateEntry(std::move(callback)); } -net::Error SimpleBackendImpl::OpenOrCreateEntry( +EntryResult SimpleBackendImpl::OpenOrCreateEntry( const std::string& key, net::RequestPriority request_priority, - EntryWithOpened* entry_struct, - CompletionOnceCallback callback) { + EntryResultCallback callback) { DCHECK_LT(0u, key.size()); const uint64_t entry_hash = simple_util::GetEntryHashKey(key); @@ -448,22 +462,20 @@ net::Error SimpleBackendImpl::OpenOrCreateEntry( simple_entry = MaybeOptimisticCreateForPostDoom( entry_hash, key, request_priority, post_doom); if (simple_entry) { - entry_struct->opened = false; - return simple_entry->CreateEntry(&entry_struct->entry, - std::move(callback)); + return simple_entry->CreateEntry(std::move(callback)); } else { // If that doesn't work either, retry this once doom is done. - base::OnceCallback<net::Error(CompletionOnceCallback)> operation = + base::OnceCallback<EntryResult(EntryResultCallback)> operation = base::BindOnce(&SimpleBackendImpl::OpenOrCreateEntry, - base::Unretained(this), key, request_priority, - entry_struct); - post_doom->emplace_back(base::BindOnce( - &RunOperationAndCallback, std::move(operation), std::move(callback))); - return net::ERR_IO_PENDING; + base::Unretained(this), key, request_priority); + post_doom->emplace_back( + base::BindOnce(&RunEntryResultOperationAndCallback, + std::move(operation), std::move(callback))); + return EntryResult::MakeError(net::ERR_IO_PENDING); } } - return simple_entry->OpenOrCreateEntry(entry_struct, std::move(callback)); + return simple_entry->OpenOrCreateEntry(std::move(callback)); } scoped_refptr<SimpleEntryImpl> @@ -528,9 +540,10 @@ net::Error SimpleBackendImpl::DoomEntriesBetween( const Time initial_time, const Time end_time, CompletionOnceCallback callback) { - return index_->ExecuteWhenReady( - base::BindOnce(&SimpleBackendImpl::IndexReadyForDoom, AsWeakPtr(), - initial_time, end_time, std::move(callback))); + index_->ExecuteWhenReady(base::BindOnce(&SimpleBackendImpl::IndexReadyForDoom, + AsWeakPtr(), initial_time, end_time, + std::move(callback))); + return net::ERR_IO_PENDING; } net::Error SimpleBackendImpl::DoomEntriesSince( @@ -541,18 +554,20 @@ net::Error SimpleBackendImpl::DoomEntriesSince( int64_t SimpleBackendImpl::CalculateSizeOfAllEntries( Int64CompletionOnceCallback callback) { - return index_->ExecuteWhenReady( + index_->ExecuteWhenReady( base::BindOnce(&SimpleBackendImpl::IndexReadyForSizeCalculation, AsWeakPtr(), std::move(callback))); + return net::ERR_IO_PENDING; } int64_t SimpleBackendImpl::CalculateSizeOfEntriesBetween( base::Time initial_time, base::Time end_time, Int64CompletionOnceCallback callback) { - return index_->ExecuteWhenReady( + index_->ExecuteWhenReady( base::BindOnce(&SimpleBackendImpl::IndexReadyForSizeBetweenCalculation, AsWeakPtr(), initial_time, end_time, std::move(callback))); + return net::ERR_IO_PENDING; } class SimpleBackendImpl::SimpleIterator final : public Iterator { @@ -561,25 +576,25 @@ class SimpleBackendImpl::SimpleIterator final : public Iterator { : backend_(backend) {} // From Backend::Iterator: - net::Error OpenNextEntry(Entry** next_entry, - CompletionOnceCallback callback) override { + EntryResult OpenNextEntry(EntryResultCallback callback) override { if (!backend_) - return net::ERR_FAILED; - CompletionOnceCallback open_next_entry_impl = base::BindOnce( - &SimpleIterator::OpenNextEntryImpl, weak_factory_.GetWeakPtr(), - next_entry, std::move(callback)); - return backend_->index_->ExecuteWhenReady(std::move(open_next_entry_impl)); + return EntryResult::MakeError(net::ERR_FAILED); + CompletionOnceCallback open_next_entry_impl = + base::BindOnce(&SimpleIterator::OpenNextEntryImpl, + weak_factory_.GetWeakPtr(), std::move(callback)); + backend_->index_->ExecuteWhenReady(std::move(open_next_entry_impl)); + return EntryResult::MakeError(net::ERR_IO_PENDING); } - void OpenNextEntryImpl(Entry** next_entry, - CompletionOnceCallback callback, + void OpenNextEntryImpl(EntryResultCallback callback, int index_initialization_error_code) { if (!backend_) { - std::move(callback).Run(net::ERR_FAILED); + std::move(callback).Run(EntryResult::MakeError(net::ERR_FAILED)); return; } if (index_initialization_error_code != net::OK) { - std::move(callback).Run(index_initialization_error_code); + std::move(callback).Run(EntryResult::MakeError( + static_cast<net::Error>(index_initialization_error_code))); return; } if (!hashes_to_enumerate_) @@ -592,31 +607,29 @@ class SimpleBackendImpl::SimpleIterator final : public Iterator { uint64_t entry_hash = hashes_to_enumerate_->back(); hashes_to_enumerate_->pop_back(); if (backend_->index()->Has(entry_hash)) { - *next_entry = nullptr; - CompletionOnceCallback continue_iteration = base::BindOnce( - &SimpleIterator::CheckIterationReturnValue, - weak_factory_.GetWeakPtr(), next_entry, copyable_callback); - int error_code_open = backend_->OpenEntryFromHash( - entry_hash, next_entry, std::move(continue_iteration)); - if (error_code_open == net::ERR_IO_PENDING) + EntryResultCallback continue_iteration = + base::BindOnce(&SimpleIterator::CheckIterationReturnValue, + weak_factory_.GetWeakPtr(), copyable_callback); + EntryResult open_result = backend_->OpenEntryFromHash( + entry_hash, std::move(continue_iteration)); + if (open_result.net_error() == net::ERR_IO_PENDING) return; - if (error_code_open != net::ERR_FAILED) { - copyable_callback.Run(error_code_open); + if (open_result.net_error() != net::ERR_FAILED) { + copyable_callback.Run(std::move(open_result)); return; } } } - copyable_callback.Run(net::ERR_FAILED); + copyable_callback.Run(EntryResult::MakeError(net::ERR_FAILED)); } - void CheckIterationReturnValue(Entry** entry, - CompletionOnceCallback callback, - int error_code) { - if (error_code == net::ERR_FAILED) { - OpenNextEntry(entry, std::move(callback)); + void CheckIterationReturnValue(EntryResultCallback callback, + EntryResult result) { + if (result.net_error() == net::ERR_FAILED) { + OpenNextEntry(std::move(callback)); return; } - std::move(callback).Run(error_code); + std::move(callback).Run(std::move(result)); } private: @@ -836,23 +849,22 @@ SimpleBackendImpl::CreateOrFindActiveOrDoomedEntry( return base::WrapRefCounted(it->second); } -net::Error SimpleBackendImpl::OpenEntryFromHash( - uint64_t entry_hash, - Entry** entry, - CompletionOnceCallback callback) { +EntryResult SimpleBackendImpl::OpenEntryFromHash(uint64_t entry_hash, + EntryResultCallback callback) { auto it = entries_pending_doom_.find(entry_hash); if (it != entries_pending_doom_.end()) { - base::OnceCallback<net::Error(CompletionOnceCallback)> operation = + base::OnceCallback<EntryResult(EntryResultCallback)> operation = base::BindOnce(&SimpleBackendImpl::OpenEntryFromHash, - base::Unretained(this), entry_hash, entry); - it->second.emplace_back(base::BindOnce( - &RunOperationAndCallback, std::move(operation), std::move(callback))); - return net::ERR_IO_PENDING; + base::Unretained(this), entry_hash); + it->second.emplace_back(base::BindOnce(&RunEntryResultOperationAndCallback, + std::move(operation), + std::move(callback))); + return EntryResult::MakeError(net::ERR_IO_PENDING); } auto has_active = active_entries_.find(entry_hash); if (has_active != active_entries_.end()) { - return OpenEntry(has_active->second->key(), net::HIGHEST, entry, + return OpenEntry(has_active->second->key(), net::HIGHEST, std::move(callback)); } @@ -860,10 +872,10 @@ net::Error SimpleBackendImpl::OpenEntryFromHash( GetCacheType(), path_, cleanup_tracker_.get(), entry_hash, entry_operations_mode_, this, file_tracker_, net_log_, GetNewEntryPriority(net::HIGHEST)); - CompletionOnceCallback backend_callback = + EntryResultCallback backend_callback = base::BindOnce(&SimpleBackendImpl::OnEntryOpenedFromHash, AsWeakPtr(), - entry_hash, entry, simple_entry, std::move(callback)); - return simple_entry->OpenEntry(entry, std::move(backend_callback)); + entry_hash, simple_entry, std::move(callback)); + return simple_entry->OpenEntry(std::move(backend_callback)); } net::Error SimpleBackendImpl::DoomEntryFromHash( @@ -896,15 +908,14 @@ net::Error SimpleBackendImpl::DoomEntryFromHash( void SimpleBackendImpl::OnEntryOpenedFromHash( uint64_t hash, - Entry** entry, const scoped_refptr<SimpleEntryImpl>& simple_entry, - CompletionOnceCallback callback, - int error_code) { - if (error_code != net::OK) { - std::move(callback).Run(error_code); + EntryResultCallback callback, + EntryResult result) { + if (result.net_error() != net::OK) { + std::move(callback).Run(std::move(result)); return; } - DCHECK(*entry); + std::pair<EntryMap::iterator, bool> insert_result = active_entries_.insert(EntryMap::value_type(hash, simple_entry.get())); EntryMap::iterator& it = insert_result.first; @@ -914,13 +925,16 @@ void SimpleBackendImpl::OnEntryOpenedFromHash( // the entry opened from hash in the |active_entries_|. We now provide the // proxy object to the entry. it->second->SetActiveEntryProxy(ActiveEntryProxy::Create(hash, this)); - std::move(callback).Run(net::OK); + std::move(callback).Run(std::move(result)); } else { // The entry was made active while we waiting for the open from hash to // finish. The entry created from hash needs to be closed, and the one // in |active_entries_| can be returned to the caller. + Entry* entry_from_result = result.ReleaseEntry(); + DCHECK_EQ(entry_from_result, simple_entry.get()); simple_entry->Close(); - it->second->OpenEntry(entry, std::move(callback)); + EntryResult reopen_result = it->second->OpenEntry(std::move(callback)); + DCHECK_EQ(reopen_result.net_error(), net::ERR_IO_PENDING); } } diff --git a/chromium/net/disk_cache/simple/simple_backend_impl.h b/chromium/net/disk_cache/simple/simple_backend_impl.h index ccf99434050..e2dc4fbab49 100644 --- a/chromium/net/disk_cache/simple/simple_backend_impl.h +++ b/chromium/net/disk_cache/simple/simple_backend_impl.h @@ -106,18 +106,15 @@ class NET_EXPORT_PRIVATE SimpleBackendImpl : public Backend, // Backend: int32_t GetEntryCount() const override; - net::Error OpenEntry(const std::string& key, - net::RequestPriority request_priority, - Entry** entry, - CompletionOnceCallback callback) override; - net::Error CreateEntry(const std::string& key, - net::RequestPriority request_priority, - Entry** entry, - CompletionOnceCallback callback) override; - net::Error OpenOrCreateEntry(const std::string& key, - net::RequestPriority priority, - EntryWithOpened* entry_struct, - CompletionOnceCallback callback) override; + EntryResult OpenEntry(const std::string& key, + net::RequestPriority request_priority, + EntryResultCallback callback) override; + EntryResult CreateEntry(const std::string& key, + net::RequestPriority request_priority, + EntryResultCallback callback) override; + EntryResult OpenOrCreateEntry(const std::string& key, + net::RequestPriority priority, + EntryResultCallback callback) override; net::Error DoomEntry(const std::string& key, net::RequestPriority priority, CompletionOnceCallback callback) override; @@ -240,9 +237,8 @@ class NET_EXPORT_PRIVATE SimpleBackendImpl : public Backend, // corresponding to |hash| in the map of active entries, opens it. Otherwise, // a new empty Entry will be created, opened and filled with information from // the disk. - net::Error OpenEntryFromHash(uint64_t entry_hash, - Entry** entry, - CompletionOnceCallback callback); + EntryResult OpenEntryFromHash(uint64_t entry_hash, + EntryResultCallback callback); // Doom the entry corresponding to |entry_hash|, if it's active or currently // pending doom. This function does not block if there is an active entry, @@ -255,10 +251,9 @@ class NET_EXPORT_PRIVATE SimpleBackendImpl : public Backend, // hash alone - this checks that a duplicate active entry was not created // using a key in the meantime. void OnEntryOpenedFromHash(uint64_t hash, - Entry** entry, const scoped_refptr<SimpleEntryImpl>& simple_entry, - CompletionOnceCallback callback, - int error_code); + EntryResultCallback callback, + EntryResult result); // Called when we tried to open an entry from key. When the entry has been // opened, a check for key mismatch is performed. diff --git a/chromium/net/disk_cache/simple/simple_entry_impl.cc b/chromium/net/disk_cache/simple/simple_entry_impl.cc index c147a4bdb3b..9618066a2d3 100644 --- a/chromium/net/disk_cache/simple/simple_entry_impl.cc +++ b/chromium/net/disk_cache/simple/simple_entry_impl.cc @@ -95,6 +95,16 @@ void InvokeCallbackIfBackendIsAlive( std::move(completion_callback).Run(result); } +void InvokeEntryResultCallbackIfBackendIsAlive( + const base::WeakPtr<SimpleBackendImpl>& backend, + EntryResultCallback completion_callback, + EntryResult result) { + DCHECK(!completion_callback.is_null()); + if (!backend.get()) + return; + std::move(completion_callback).Run(std::move(result)); +} + // If |sync_possible| is false, and callback is available, posts rv to it and // return net::ERR_IO_PENDING; otherwise just passes through rv. int PostToCallbackIfNeeded(bool sync_possible, @@ -190,8 +200,7 @@ void SimpleEntryImpl::SetActiveEntryProxy( active_entry_proxy_ = std::move(active_entry_proxy); } -net::Error SimpleEntryImpl::OpenEntry(Entry** out_entry, - net::CompletionOnceCallback callback) { +EntryResult SimpleEntryImpl::OpenEntry(EntryResultCallback callback) { DCHECK(backend_.get()); net_log_.AddEvent(net::NetLogEventType::SIMPLE_CACHE_ENTRY_OPEN_CALL); @@ -204,32 +213,32 @@ net::Error SimpleEntryImpl::OpenEntry(Entry** out_entry, if (index_state == INDEX_MISS) { net_log_.AddEventWithNetErrorCode( net::NetLogEventType::SIMPLE_CACHE_ENTRY_OPEN_END, net::ERR_FAILED); - return net::ERR_FAILED; + return EntryResult::MakeError(net::ERR_FAILED); } pending_operations_.push(SimpleEntryOperation::OpenOperation( - this, std::move(callback), out_entry)); + this, SimpleEntryOperation::ENTRY_NEEDS_CALLBACK, std::move(callback))); RunNextOperationIfNeeded(); - return net::ERR_IO_PENDING; + return EntryResult::MakeError(net::ERR_IO_PENDING); } -net::Error SimpleEntryImpl::CreateEntry(Entry** out_entry, - net::CompletionOnceCallback callback) { +EntryResult SimpleEntryImpl::CreateEntry(EntryResultCallback callback) { DCHECK(backend_.get()); DCHECK_EQ(entry_hash_, simple_util::GetEntryHashKey(key_)); net_log_.AddEvent(net::NetLogEventType::SIMPLE_CACHE_ENTRY_CREATE_CALL); - net::Error ret_value = net::ERR_FAILED; + EntryResult result = EntryResult::MakeError(net::ERR_IO_PENDING); if (use_optimistic_operations_ && state_ == STATE_UNINITIALIZED && pending_operations_.size() == 0) { net_log_.AddEvent( net::NetLogEventType::SIMPLE_CACHE_ENTRY_CREATE_OPTIMISTIC); - ReturnEntryToCaller(out_entry); + ReturnEntryToCaller(); + result = EntryResult::MakeCreated(this); pending_operations_.push(SimpleEntryOperation::CreateOperation( - this, CompletionOnceCallback(), nullptr)); - ret_value = net::OK; + this, SimpleEntryOperation::ENTRY_ALREADY_RETURNED, + EntryResultCallback())); // If we are optimistically returning before a preceeding doom, we need to // wait for that IO, about which we will be notified externally. @@ -240,8 +249,7 @@ net::Error SimpleEntryImpl::CreateEntry(Entry** out_entry, } } else { pending_operations_.push(SimpleEntryOperation::CreateOperation( - this, std::move(callback), out_entry)); - ret_value = net::ERR_IO_PENDING; + this, SimpleEntryOperation::ENTRY_NEEDS_CALLBACK, std::move(callback))); } // We insert the entry in the index before creating the entry files in the @@ -252,40 +260,38 @@ net::Error SimpleEntryImpl::CreateEntry(Entry** out_entry, backend_->index()->Insert(entry_hash_); RunNextOperationIfNeeded(); - return ret_value; + return result; } -net::Error SimpleEntryImpl::OpenOrCreateEntry( - EntryWithOpened* entry_struct, - net::CompletionOnceCallback callback) { +EntryResult SimpleEntryImpl::OpenOrCreateEntry(EntryResultCallback callback) { DCHECK(backend_.get()); DCHECK_EQ(entry_hash_, simple_util::GetEntryHashKey(key_)); net_log_.AddEvent( net::NetLogEventType::SIMPLE_CACHE_ENTRY_OPEN_OR_CREATE_CALL); - net::Error ret_value = net::ERR_FAILED; OpenEntryIndexEnum index_state = ComputeIndexState(backend_.get(), entry_hash_); RecordOpenEntryIndexState(cache_type_, index_state); + EntryResult result = EntryResult::MakeError(net::ERR_IO_PENDING); if (index_state == INDEX_MISS && use_optimistic_operations_ && state_ == STATE_UNINITIALIZED && pending_operations_.size() == 0) { net_log_.AddEvent( net::NetLogEventType::SIMPLE_CACHE_ENTRY_CREATE_OPTIMISTIC); - entry_struct->opened = false; // Creating. - ReturnEntryToCaller(&entry_struct->entry); + ReturnEntryToCaller(); + result = EntryResult::MakeCreated(this); pending_operations_.push(SimpleEntryOperation::OpenOrCreateOperation( - this, index_state, CompletionOnceCallback(), nullptr)); - ret_value = net::OK; + this, index_state, SimpleEntryOperation::ENTRY_ALREADY_RETURNED, + EntryResultCallback())); // The post-doom stuff should go through CreateEntry, not here. DCHECK_EQ(CREATE_NORMAL, optimistic_create_pending_doom_state_); } else { pending_operations_.push(SimpleEntryOperation::OpenOrCreateOperation( - this, index_state, std::move(callback), entry_struct)); - ret_value = net::ERR_IO_PENDING; + this, index_state, SimpleEntryOperation::ENTRY_NEEDS_CALLBACK, + std::move(callback))); } // We insert the entry in the index before creating the entry files in the @@ -296,7 +302,7 @@ net::Error SimpleEntryImpl::OpenOrCreateEntry( backend_->index()->Insert(entry_hash_); RunNextOperationIfNeeded(); - return ret_value; + return result; } net::Error SimpleEntryImpl::DoomEntry(net::CompletionOnceCallback callback) { @@ -671,6 +677,18 @@ void SimpleEntryImpl::PostClientCallback(net::CompletionOnceCallback callback, std::move(callback), result)); } +void SimpleEntryImpl::PostClientCallback(EntryResultCallback callback, + EntryResult result) { + if (callback.is_null()) + return; + // Note that the callback is posted rather than directly invoked to avoid + // reentrancy issues. + base::SequencedTaskRunnerHandle::Get()->PostTask( + FROM_HERE, + base::BindOnce(&InvokeEntryResultCallbackIfBackendIsAlive, backend_, + std::move(callback), std::move(result))); +} + void SimpleEntryImpl::ResetEntry() { // If we're doomed, we can't really do anything else with the entry, since // we no longer own the name and are disconnected from the active entry table. @@ -685,21 +703,15 @@ void SimpleEntryImpl::ResetEntry() { } } -void SimpleEntryImpl::ReturnEntryToCaller(Entry** out_entry) { +void SimpleEntryImpl::ReturnEntryToCaller() { DCHECK(backend_); - DCHECK(out_entry); ++open_count_; AddRef(); // Balanced in Close() - *out_entry = this; } -void SimpleEntryImpl::ReturnEntryToCallerAsync( - Entry** out_entry, - bool* out_opened, - bool opened, - CompletionOnceCallback callback) { +void SimpleEntryImpl::ReturnEntryToCallerAsync(bool is_open, + EntryResultCallback callback) { DCHECK(!callback.is_null()); - DCHECK(out_entry); // |open_count_| must be incremented immediately, so that a Close on an alias // doesn't try to wrap things up. @@ -710,14 +722,12 @@ void SimpleEntryImpl::ReturnEntryToCallerAsync( base::SequencedTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(&SimpleEntryImpl::FinishReturnEntryToCallerAsync, this, - out_entry, out_opened, opened, std::move(callback))); + is_open, std::move(callback))); } void SimpleEntryImpl::FinishReturnEntryToCallerAsync( - Entry** out_entry, - bool* out_opened, - bool opened, - CompletionOnceCallback callback) { + bool is_open, + EntryResultCallback callback) { AddRef(); // Balanced in Close() if (!backend_.get()) { // With backend dead, Open/Create operations are responsible for cleaning up @@ -727,11 +737,8 @@ void SimpleEntryImpl::FinishReturnEntryToCallerAsync( return; } - *out_entry = this; - if (out_opened) - *out_opened = opened; - - std::move(callback).Run(net::OK); + std::move(callback).Run(is_open ? EntryResult::MakeOpened(this) + : EntryResult::MakeCreated(this)); } void SimpleEntryImpl::MarkAsDoomed(DoomState new_state) { @@ -750,15 +757,17 @@ void SimpleEntryImpl::RunNextOperationIfNeeded() { pending_operations_.pop(); switch (operation.type()) { case SimpleEntryOperation::TYPE_OPEN: - OpenEntryInternal(operation.ReleaseCallback(), operation.out_entry()); + OpenEntryInternal(operation.entry_result_state(), + operation.ReleaseEntryResultCallback()); break; case SimpleEntryOperation::TYPE_CREATE: - CreateEntryInternal(operation.ReleaseCallback(), operation.out_entry()); + CreateEntryInternal(operation.entry_result_state(), + operation.ReleaseEntryResultCallback()); break; case SimpleEntryOperation::TYPE_OPEN_OR_CREATE: OpenOrCreateEntryInternal(operation.index_state(), - operation.ReleaseCallback(), - operation.entry_struct()); + operation.entry_result_state(), + operation.ReleaseEntryResultCallback()); break; case SimpleEntryOperation::TYPE_CLOSE: CloseInternal(); @@ -797,22 +806,26 @@ void SimpleEntryImpl::RunNextOperationIfNeeded() { } } -void SimpleEntryImpl::OpenEntryInternal(net::CompletionOnceCallback callback, - Entry** out_entry) { +void SimpleEntryImpl::OpenEntryInternal( + SimpleEntryOperation::EntryResultState result_state, + EntryResultCallback callback) { ScopedOperationRunner operation_runner(this); net_log_.AddEvent(net::NetLogEventType::SIMPLE_CACHE_ENTRY_OPEN_BEGIN); + // No optimistic sync return possible on open. + DCHECK_EQ(SimpleEntryOperation::ENTRY_NEEDS_CALLBACK, result_state); + if (state_ == STATE_READY) { - ReturnEntryToCallerAsync(out_entry, /* out_opened = */ nullptr, - /* opened = */ true, std::move(callback)); + ReturnEntryToCallerAsync(/* is_open = */ true, std::move(callback)); NetLogSimpleEntryCreation(net_log_, net::NetLogEventType::SIMPLE_CACHE_ENTRY_OPEN_END, net::NetLogEventPhase::NONE, this, net::OK); return; } if (state_ == STATE_FAILURE) { - PostClientCallback(std::move(callback), net::ERR_FAILED); + PostClientCallback(std::move(callback), + EntryResult::MakeError(net::ERR_FAILED)); NetLogSimpleEntryCreation( net_log_, net::NetLogEventType::SIMPLE_CACHE_ENTRY_OPEN_END, net::NetLogEventPhase::NONE, this, net::ERR_FAILED); @@ -843,17 +856,17 @@ void SimpleEntryImpl::OpenEntryInternal(net::CompletionOnceCallback callback, start_time, file_tracker_, trailer_prefetch_size, results.get()); base::OnceClosure reply = base::BindOnce( - &SimpleEntryImpl::CreationOperationComplete, this, std::move(callback), - start_time, last_used_time, base::Passed(&results), out_entry, - nullptr /* out_opened */, + &SimpleEntryImpl::CreationOperationComplete, this, result_state, + std::move(callback), start_time, last_used_time, base::Passed(&results), net::NetLogEventType::SIMPLE_CACHE_ENTRY_OPEN_END); prioritized_task_runner_->PostTaskAndReply(FROM_HERE, std::move(task), std::move(reply), entry_priority_); } -void SimpleEntryImpl::CreateEntryInternal(net::CompletionOnceCallback callback, - Entry** out_entry) { +void SimpleEntryImpl::CreateEntryInternal( + SimpleEntryOperation::EntryResultState result_state, + EntryResultCallback callback) { ScopedOperationRunner operation_runner(this); net_log_.AddEvent(net::NetLogEventType::SIMPLE_CACHE_ENTRY_CREATE_BEGIN); @@ -863,7 +876,11 @@ void SimpleEntryImpl::CreateEntryInternal(net::CompletionOnceCallback callback, NetLogSimpleEntryCreation( net_log_, net::NetLogEventType::SIMPLE_CACHE_ENTRY_CREATE_END, net::NetLogEventPhase::NONE, this, net::ERR_FAILED); - PostClientCallback(std::move(callback), net::ERR_FAILED); + // If we have optimistically returned an entry, we would be the first entry + // in queue with state_ == STATE_UNINITIALIZED. + DCHECK_EQ(SimpleEntryOperation::ENTRY_NEEDS_CALLBACK, result_state); + PostClientCallback(std::move(callback), + EntryResult::MakeError(net::ERR_FAILED)); return; } DCHECK_EQ(STATE_UNINITIALIZED, state_); @@ -884,9 +901,8 @@ void SimpleEntryImpl::CreateEntryInternal(net::CompletionOnceCallback callback, cache_type_, path_, key_, entry_hash_, start_time, file_tracker_, results.get()); OnceClosure reply = base::BindOnce( - &SimpleEntryImpl::CreationOperationComplete, this, std::move(callback), - start_time, base::Time(), base::Passed(&results), out_entry, - nullptr, /* out_opened */ + &SimpleEntryImpl::CreationOperationComplete, this, result_state, + std::move(callback), start_time, base::Time(), base::Passed(&results), net::NetLogEventType::SIMPLE_CACHE_ENTRY_CREATE_END); prioritized_task_runner_->PostTaskAndReply(FROM_HERE, std::move(task), std::move(reply), entry_priority_); @@ -894,27 +910,29 @@ void SimpleEntryImpl::CreateEntryInternal(net::CompletionOnceCallback callback, void SimpleEntryImpl::OpenOrCreateEntryInternal( OpenEntryIndexEnum index_state, - net::CompletionOnceCallback callback, - EntryWithOpened* entry_struct) { + SimpleEntryOperation::EntryResultState result_state, + EntryResultCallback callback) { ScopedOperationRunner operation_runner(this); net_log_.AddEvent( net::NetLogEventType::SIMPLE_CACHE_ENTRY_OPEN_OR_CREATE_BEGIN); - // entry_struct may be null if an optimistic create is being performed, - // which must be in STATE_UNINITIALIZED. - DCHECK(entry_struct != nullptr || state_ == STATE_UNINITIALIZED); + // result_state may be ENTRY_ALREADY_RETURNED only if an optimistic create is + // being performed, which must be in STATE_UNINITIALIZED. + bool optimistic_create = + (result_state == SimpleEntryOperation::ENTRY_ALREADY_RETURNED); + DCHECK(!optimistic_create || state_ == STATE_UNINITIALIZED); if (state_ == STATE_READY) { - ReturnEntryToCallerAsync(&entry_struct->entry, &entry_struct->opened, - /* opened = */ true, std::move(callback)); + ReturnEntryToCallerAsync(/* is_open = */ true, std::move(callback)); NetLogSimpleEntryCreation( net_log_, net::NetLogEventType::SIMPLE_CACHE_ENTRY_OPEN_OR_CREATE_END, net::NetLogEventPhase::NONE, this, net::OK); return; } if (state_ == STATE_FAILURE) { - PostClientCallback(std::move(callback), net::ERR_FAILED); + PostClientCallback(std::move(callback), + EntryResult::MakeError(net::ERR_FAILED)); NetLogSimpleEntryCreation( net_log_, net::NetLogEventType::SIMPLE_CACHE_ENTRY_OPEN_OR_CREATE_END, net::NetLogEventPhase::NONE, this, net::ERR_FAILED); @@ -940,17 +958,14 @@ void SimpleEntryImpl::OpenOrCreateEntryInternal( } } - bool optimistic_create = (entry_struct == nullptr); base::OnceClosure task = base::BindOnce( &SimpleSynchronousEntry::OpenOrCreateEntry, cache_type_, path_, key_, entry_hash_, index_state, optimistic_create, start_time, file_tracker_, trailer_prefetch_size, results.get()); base::OnceClosure reply = base::BindOnce( - &SimpleEntryImpl::CreationOperationComplete, this, std::move(callback), - start_time, last_used_time, base::Passed(&results), - entry_struct ? &entry_struct->entry : nullptr, - entry_struct ? &entry_struct->opened : nullptr, + &SimpleEntryImpl::CreationOperationComplete, this, result_state, + std::move(callback), start_time, last_used_time, base::Passed(&results), net::NetLogEventType::SIMPLE_CACHE_ENTRY_OPEN_OR_CREATE_END); prioritized_task_runner_->PostTaskAndReply(FROM_HERE, std::move(task), @@ -1425,12 +1440,11 @@ void SimpleEntryImpl::DoomEntryInternal(net::CompletionOnceCallback callback) { } void SimpleEntryImpl::CreationOperationComplete( - net::CompletionOnceCallback completion_callback, + SimpleEntryOperation::EntryResultState result_state, + EntryResultCallback completion_callback, const base::TimeTicks& start_time, const base::Time index_last_used_time, std::unique_ptr<SimpleEntryCreationResults> in_results, - Entry** out_entry, - bool* out_opened, net::NetLogEventType end_event_type) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_EQ(state_, STATE_IO_PENDING); @@ -1452,7 +1466,8 @@ void SimpleEntryImpl::CreationOperationComplete( } net_log_.AddEventWithNetErrorCode(end_event_type, net::ERR_FAILED); - PostClientCallback(std::move(completion_callback), net::ERR_FAILED); + PostClientCallback(std::move(completion_callback), + EntryResult::MakeError(net::ERR_FAILED)); ResetEntry(); return; } @@ -1516,12 +1531,8 @@ void SimpleEntryImpl::CreationOperationComplete( net_log_.AddEvent(end_event_type); - // The entry was either returned optimistically already, in which case - // out_entry is nullptr and there is no callback, or should be returned - // to out_entry with callback invoked. - DCHECK_EQ(out_entry == nullptr, completion_callback.is_null()); - if (out_entry) { - ReturnEntryToCallerAsync(out_entry, out_opened, !in_results->created, + if (result_state == SimpleEntryOperation::ENTRY_NEEDS_CALLBACK) { + ReturnEntryToCallerAsync(!in_results->created, std::move(completion_callback)); } } diff --git a/chromium/net/disk_cache/simple/simple_entry_impl.h b/chromium/net/disk_cache/simple/simple_entry_impl.h index 271746cbd12..b6d991c06e2 100644 --- a/chromium/net/disk_cache/simple/simple_entry_impl.h +++ b/chromium/net/disk_cache/simple/simple_entry_impl.h @@ -77,18 +77,14 @@ class NET_EXPORT_PRIVATE SimpleEntryImpl : public Entry, void SetActiveEntryProxy( std::unique_ptr<ActiveEntryProxy> active_entry_proxy); - // Adds another reader/writer to this entry, if possible, returning |this| to - // |entry|. - net::Error OpenEntry(Entry** entry, CompletionOnceCallback callback); + // Adds another reader/writer to this entry, if possible. + EntryResult OpenEntry(EntryResultCallback callback); - // Creates this entry, if possible. Returns |this| to |entry|. - net::Error CreateEntry(Entry** entry, CompletionOnceCallback callback); + // Creates this entry, if possible. + EntryResult CreateEntry(EntryResultCallback callback); - // Opens an existing entry or creates a new one. Returns |this| to - // |entry_struct->entry|, and sets |entry_struct->opened| based on what op was - // actually performed. - net::Error OpenOrCreateEntry(EntryWithOpened* entry_struct, - CompletionOnceCallback callback); + // Opens an existing entry or creates a new one. + EntryResult OpenOrCreateEntry(EntryResultCallback callback); // Identical to Backend::Doom() except that it accepts a // CompletionOnceCallback. @@ -203,6 +199,7 @@ class NET_EXPORT_PRIVATE SimpleEntryImpl : public Entry, // clients don't get notified after they deleted the backend (which they would // not expect). void PostClientCallback(CompletionOnceCallback callback, int result); + void PostClientCallback(EntryResultCallback callback, EntryResult result); // Clears entry state enough to prepare it for re-use. This will generally // put it back into STATE_UNINITIALIZED, except if the entry is doomed and @@ -210,25 +207,18 @@ class NET_EXPORT_PRIVATE SimpleEntryImpl : public Entry, // case it will be put into STATE_FAILURE. void ResetEntry(); - // Return this entry to a user of the API in |out_entry|. Increments the user - // count. - void ReturnEntryToCaller(Entry** out_entry); + // Adjust ownership before return of this entry to a user of the API. + // Increments the user count. + void ReturnEntryToCaller(); // Like above, but for asynchronous return after the event loop runs again, // also invoking the callback per the usual net convention. // The return is cancelled if the backend is deleted in the interim. - // - // |out_opened| may be null. - void ReturnEntryToCallerAsync(Entry** out_entry, - bool* out_opened, - bool opened, - CompletionOnceCallback callback); + void ReturnEntryToCallerAsync(bool is_open, EntryResultCallback callback); // Portion of the above that runs off the event loop. - void FinishReturnEntryToCallerAsync(Entry** out_entry, - bool* out_opened, - bool opened, - CompletionOnceCallback callback); + void FinishReturnEntryToCallerAsync(bool is_open, + EntryResultCallback callback); // Remove |this| from the Backend and the index, either because // SimpleSynchronousEntry has detected an error or because we are about to @@ -242,13 +232,16 @@ class NET_EXPORT_PRIVATE SimpleEntryImpl : public Entry, // the last reference. void RunNextOperationIfNeeded(); - void OpenEntryInternal(CompletionOnceCallback callback, Entry** out_entry); + void OpenEntryInternal(SimpleEntryOperation::EntryResultState result_state, + EntryResultCallback callback); - void CreateEntryInternal(CompletionOnceCallback callback, Entry** out_entry); + void CreateEntryInternal(SimpleEntryOperation::EntryResultState result_state, + EntryResultCallback callback); - void OpenOrCreateEntryInternal(OpenEntryIndexEnum index_state, - CompletionOnceCallback callback, - EntryWithOpened* entry_struct); + void OpenOrCreateEntryInternal( + OpenEntryIndexEnum index_state, + SimpleEntryOperation::EntryResultState result_state, + EntryResultCallback callback); void CloseInternal(); @@ -284,16 +277,14 @@ class NET_EXPORT_PRIVATE SimpleEntryImpl : public Entry, void DoomEntryInternal(CompletionOnceCallback callback); // Called after a SimpleSynchronousEntry has completed CreateEntry() or - // OpenEntry(). If |in_sync_entry| is non-NULL, creation is successful and we - // can return |this| SimpleEntryImpl to |*out_entry|. Runs - // |completion_callback|. + // OpenEntry(). If |in_results| is used to denote whether that was successful, + // Posts either the produced entry or an error code to |completion_callback|. void CreationOperationComplete( - CompletionOnceCallback completion_callback, + SimpleEntryOperation::EntryResultState result_state, + EntryResultCallback completion_callback, const base::TimeTicks& start_time, const base::Time index_last_used_time, std::unique_ptr<SimpleEntryCreationResults> in_results, - Entry** out_entry, - bool* out_opened, net::NetLogEventType end_event_type); // Called after we've closed and written the EOF record to our entry. Until diff --git a/chromium/net/disk_cache/simple/simple_entry_operation.cc b/chromium/net/disk_cache/simple/simple_entry_operation.cc index 6ddb3fb20d0..70a65564654 100644 --- a/chromium/net/disk_cache/simple/simple_entry_operation.cc +++ b/chromium/net/disk_cache/simple/simple_entry_operation.cc @@ -21,40 +21,47 @@ SimpleEntryOperation::~SimpleEntryOperation() = default; // static SimpleEntryOperation SimpleEntryOperation::OpenOperation( SimpleEntryImpl* entry, - net::CompletionOnceCallback callback, - Entry** out_entry) { - return SimpleEntryOperation(entry, nullptr, std::move(callback), out_entry, - nullptr, 0, 0, 0, nullptr, TYPE_OPEN, - INDEX_NOEXIST, 0, false, false); + EntryResultState result_state, + EntryResultCallback callback) { + SimpleEntryOperation op(entry, nullptr, CompletionOnceCallback(), 0, 0, 0, + nullptr, TYPE_OPEN, INDEX_NOEXIST, 0, false, false); + op.entry_callback_ = std::move(callback); + op.entry_result_state_ = result_state; + return op; } // static SimpleEntryOperation SimpleEntryOperation::CreateOperation( SimpleEntryImpl* entry, - net::CompletionOnceCallback callback, - Entry** out_entry) { - return SimpleEntryOperation(entry, nullptr, std::move(callback), out_entry, - nullptr, 0, 0, 0, nullptr, TYPE_CREATE, - INDEX_NOEXIST, 0, false, false); + EntryResultState result_state, + EntryResultCallback callback) { + SimpleEntryOperation op(entry, nullptr, CompletionOnceCallback(), 0, 0, 0, + nullptr, TYPE_CREATE, INDEX_NOEXIST, 0, false, false); + op.entry_callback_ = std::move(callback); + op.entry_result_state_ = result_state; + return op; } // static SimpleEntryOperation SimpleEntryOperation::OpenOrCreateOperation( SimpleEntryImpl* entry, OpenEntryIndexEnum index_state, - net::CompletionOnceCallback callback, - EntryWithOpened* entry_struct) { - return SimpleEntryOperation( - entry, nullptr, std::move(callback), nullptr, entry_struct, 0, 0, 0, - nullptr, TYPE_OPEN_OR_CREATE, index_state, 0, false, false); + EntryResultState result_state, + EntryResultCallback callback) { + SimpleEntryOperation op(entry, nullptr, CompletionOnceCallback(), 0, 0, 0, + nullptr, TYPE_OPEN_OR_CREATE, index_state, 0, false, + false); + op.entry_callback_ = std::move(callback); + op.entry_result_state_ = result_state; + return op; } // static SimpleEntryOperation SimpleEntryOperation::CloseOperation( SimpleEntryImpl* entry) { - return SimpleEntryOperation(entry, nullptr, CompletionOnceCallback(), nullptr, - nullptr, 0, 0, 0, nullptr, TYPE_CLOSE, - INDEX_NOEXIST, 0, false, false); + return SimpleEntryOperation(entry, nullptr, CompletionOnceCallback(), 0, 0, 0, + nullptr, TYPE_CLOSE, INDEX_NOEXIST, 0, false, + false); } // static @@ -65,9 +72,9 @@ SimpleEntryOperation SimpleEntryOperation::ReadOperation( int length, net::IOBuffer* buf, CompletionOnceCallback callback) { - return SimpleEntryOperation(entry, buf, std::move(callback), nullptr, nullptr, - offset, 0, length, nullptr, TYPE_READ, - INDEX_NOEXIST, index, false, false); + return SimpleEntryOperation(entry, buf, std::move(callback), offset, 0, + length, nullptr, TYPE_READ, INDEX_NOEXIST, index, + false, false); } // static @@ -80,9 +87,9 @@ SimpleEntryOperation SimpleEntryOperation::WriteOperation( bool truncate, bool optimistic, CompletionOnceCallback callback) { - return SimpleEntryOperation(entry, buf, std::move(callback), nullptr, nullptr, - offset, 0, length, nullptr, TYPE_WRITE, - INDEX_NOEXIST, index, truncate, optimistic); + return SimpleEntryOperation(entry, buf, std::move(callback), offset, 0, + length, nullptr, TYPE_WRITE, INDEX_NOEXIST, index, + truncate, optimistic); } // static @@ -92,9 +99,9 @@ SimpleEntryOperation SimpleEntryOperation::ReadSparseOperation( int length, net::IOBuffer* buf, CompletionOnceCallback callback) { - return SimpleEntryOperation(entry, buf, std::move(callback), nullptr, nullptr, - 0, sparse_offset, length, nullptr, - TYPE_READ_SPARSE, INDEX_NOEXIST, 0, false, false); + return SimpleEntryOperation(entry, buf, std::move(callback), 0, sparse_offset, + length, nullptr, TYPE_READ_SPARSE, INDEX_NOEXIST, + 0, false, false); } // static @@ -104,9 +111,9 @@ SimpleEntryOperation SimpleEntryOperation::WriteSparseOperation( int length, net::IOBuffer* buf, CompletionOnceCallback callback) { - return SimpleEntryOperation( - entry, buf, std::move(callback), nullptr, nullptr, 0, sparse_offset, - length, nullptr, TYPE_WRITE_SPARSE, INDEX_NOEXIST, 0, false, false); + return SimpleEntryOperation(entry, buf, std::move(callback), 0, sparse_offset, + length, nullptr, TYPE_WRITE_SPARSE, INDEX_NOEXIST, + 0, false, false); } // static @@ -116,10 +123,9 @@ SimpleEntryOperation SimpleEntryOperation::GetAvailableRangeOperation( int length, int64_t* out_start, CompletionOnceCallback callback) { - return SimpleEntryOperation(entry, nullptr, std::move(callback), nullptr, - nullptr, 0, sparse_offset, length, out_start, - TYPE_GET_AVAILABLE_RANGE, INDEX_NOEXIST, 0, false, - false); + return SimpleEntryOperation( + entry, nullptr, std::move(callback), 0, sparse_offset, length, out_start, + TYPE_GET_AVAILABLE_RANGE, INDEX_NOEXIST, 0, false, false); } // static @@ -127,8 +133,6 @@ SimpleEntryOperation SimpleEntryOperation::DoomOperation( SimpleEntryImpl* entry, net::CompletionOnceCallback callback) { net::IOBuffer* const buf = nullptr; - Entry** const out_entry = nullptr; - EntryWithOpened* out_entry_struct = nullptr; const int offset = 0; const int64_t sparse_offset = 0; const int length = 0; @@ -137,17 +141,14 @@ SimpleEntryOperation SimpleEntryOperation::DoomOperation( const int index = 0; const bool truncate = false; const bool optimistic = false; - return SimpleEntryOperation(entry, buf, std::move(callback), out_entry, - out_entry_struct, offset, sparse_offset, length, - out_start, TYPE_DOOM, index_state, index, - truncate, optimistic); + return SimpleEntryOperation(entry, buf, std::move(callback), offset, + sparse_offset, length, out_start, TYPE_DOOM, + index_state, index, truncate, optimistic); } SimpleEntryOperation::SimpleEntryOperation(SimpleEntryImpl* entry, net::IOBuffer* buf, net::CompletionOnceCallback callback, - Entry** out_entry, - EntryWithOpened* entry_struct, int offset, int64_t sparse_offset, int length, @@ -160,8 +161,6 @@ SimpleEntryOperation::SimpleEntryOperation(SimpleEntryImpl* entry, : entry_(entry), buf_(buf), callback_(std::move(callback)), - out_entry_(out_entry), - entry_struct_(entry_struct), offset_(offset), sparse_offset_(sparse_offset), length_(length), diff --git a/chromium/net/disk_cache/simple/simple_entry_operation.h b/chromium/net/disk_cache/simple/simple_entry_operation.h index ed47a0fc1b0..c5989449f8c 100644 --- a/chromium/net/disk_cache/simple/simple_entry_operation.h +++ b/chromium/net/disk_cache/simple/simple_entry_operation.h @@ -18,7 +18,6 @@ class IOBuffer; namespace disk_cache { -class Entry; class SimpleEntryImpl; // SimpleEntryOperation stores the information regarding operations in @@ -41,20 +40,27 @@ class SimpleEntryOperation { TYPE_DOOM = 9, }; + // Whether an open/create method has returned an entry (optimistically) + // already, or if it still needs to be delivered via a callback. + enum EntryResultState { + ENTRY_ALREADY_RETURNED = 0, + ENTRY_NEEDS_CALLBACK = 1, + }; + SimpleEntryOperation(SimpleEntryOperation&& other); ~SimpleEntryOperation(); static SimpleEntryOperation OpenOperation(SimpleEntryImpl* entry, - CompletionOnceCallback, - Entry** out_entry); + EntryResultState result_state, + EntryResultCallback); static SimpleEntryOperation CreateOperation(SimpleEntryImpl* entry, - CompletionOnceCallback callback, - Entry** out_entry); + EntryResultState result_state, + EntryResultCallback); static SimpleEntryOperation OpenOrCreateOperation( SimpleEntryImpl* entry, OpenEntryIndexEnum index_state, - CompletionOnceCallback callback, - EntryWithOpened* entry_struct); + EntryResultState result_state, + EntryResultCallback); static SimpleEntryOperation CloseOperation(SimpleEntryImpl* entry); static SimpleEntryOperation ReadOperation(SimpleEntryImpl* entry, int index, @@ -95,9 +101,12 @@ class SimpleEntryOperation { return static_cast<EntryOperationType>(type_); } CompletionOnceCallback ReleaseCallback() { return std::move(callback_); } + EntryResultCallback ReleaseEntryResultCallback() { + return std::move(entry_callback_); + } + + EntryResultState entry_result_state() { return entry_result_state_; } - Entry** out_entry() { return out_entry_; } - EntryWithOpened* entry_struct() { return entry_struct_; } OpenEntryIndexEnum index_state() const { return index_state_; } int index() const { return index_; } int offset() const { return offset_; } @@ -112,8 +121,6 @@ class SimpleEntryOperation { SimpleEntryOperation(SimpleEntryImpl* entry, net::IOBuffer* buf, CompletionOnceCallback callback, - Entry** out_entry, - EntryWithOpened* entry_struct, int offset, int64_t sparse_offset, int length, @@ -130,9 +137,8 @@ class SimpleEntryOperation { CompletionOnceCallback callback_; // Used in open and create operations. - Entry** out_entry_; - // Used in the combined OpenOrCreateOperation. - EntryWithOpened* entry_struct_; + EntryResultCallback entry_callback_; + EntryResultState entry_result_state_; // Used in write and read operations. const int offset_; diff --git a/chromium/net/disk_cache/simple/simple_index.cc b/chromium/net/disk_cache/simple/simple_index.cc index a4ee6f7f27d..0db2b990ba6 100644 --- a/chromium/net/disk_cache/simple/simple_index.cc +++ b/chromium/net/disk_cache/simple/simple_index.cc @@ -237,13 +237,12 @@ void SimpleIndex::SetMaxSize(uint64_t max_bytes) { } } -net::Error SimpleIndex::ExecuteWhenReady(net::CompletionOnceCallback task) { +void SimpleIndex::ExecuteWhenReady(net::CompletionOnceCallback task) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (initialized_) task_runner_->PostTask(FROM_HERE, base::BindOnce(std::move(task), net::OK)); else to_run_when_initialized_.push_back(std::move(task)); - return net::ERR_IO_PENDING; } std::unique_ptr<SimpleIndex::HashList> SimpleIndex::GetEntriesBetween( diff --git a/chromium/net/disk_cache/simple/simple_index.h b/chromium/net/disk_cache/simple/simple_index.h index f021cf1e382..645ca177409 100644 --- a/chromium/net/disk_cache/simple/simple_index.h +++ b/chromium/net/disk_cache/simple/simple_index.h @@ -185,7 +185,8 @@ class NET_EXPORT_PRIVATE SimpleIndex const EntryMetadata& entry_metadata); // Executes the |callback| when the index is ready. Allows multiple callbacks. - net::Error ExecuteWhenReady(net::CompletionOnceCallback callback); + // Never synchronous. + void ExecuteWhenReady(net::CompletionOnceCallback callback); // Returns entries from the index that have last accessed time matching the // range between |initial_time| and |end_time| where open intervals are diff --git a/chromium/net/disk_cache/simple/simple_index_file_unittest.cc b/chromium/net/disk_cache/simple/simple_index_file_unittest.cc index b8c4d57788f..0b59cb088dc 100644 --- a/chromium/net/disk_cache/simple/simple_index_file_unittest.cc +++ b/chromium/net/disk_cache/simple/simple_index_file_unittest.cc @@ -30,7 +30,7 @@ #include "net/disk_cache/simple/simple_util.h" #include "net/disk_cache/simple/simple_version_upgrade.h" #include "net/test/gtest_util.h" -#include "net/test/test_with_scoped_task_environment.h" +#include "net/test/test_with_task_environment.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -176,7 +176,7 @@ class WrappedSimpleIndexFile : public SimpleIndexFile { } }; -class SimpleIndexFileTest : public net::TestWithScopedTaskEnvironment { +class SimpleIndexFileTest : public net::TestWithTaskEnvironment { public: bool CompareTwoEntryMetadata(const EntryMetadata& a, const EntryMetadata& b) { return a.last_used_time_seconds_since_epoch_ == @@ -591,8 +591,9 @@ TEST_F(SimpleIndexFileTest, SimpleCacheUpgrade) { net::TestCompletionCallback cb; int rv = simple_cache->Init(cb.callback()); EXPECT_THAT(cb.GetResult(rv), IsOk()); - rv = simple_cache->index()->ExecuteWhenReady(cb.callback()); - EXPECT_THAT(cb.GetResult(rv), IsOk()); + simple_cache->index()->ExecuteWhenReady(cb.callback()); + rv = cb.WaitForResult(); + EXPECT_THAT(rv, IsOk()); delete simple_cache; cleanup_tracker = nullptr; diff --git a/chromium/net/disk_cache/simple/simple_index_unittest.cc b/chromium/net/disk_cache/simple/simple_index_unittest.cc index 375ce7da91c..889ff747aa9 100644 --- a/chromium/net/disk_cache/simple/simple_index_unittest.cc +++ b/chromium/net/disk_cache/simple/simple_index_unittest.cc @@ -28,7 +28,7 @@ #include "net/disk_cache/simple/simple_index_file.h" #include "net/disk_cache/simple/simple_test_util.h" #include "net/disk_cache/simple/simple_util.h" -#include "net/test/test_with_scoped_task_environment.h" +#include "net/test/test_with_task_environment.h" #include "testing/gtest/include/gtest/gtest.h" namespace disk_cache { @@ -105,7 +105,7 @@ class MockSimpleIndexFile : public SimpleIndexFile, SimpleIndex::EntrySet disk_write_entry_set_; }; -class SimpleIndexTest : public net::TestWithScopedTaskEnvironment, +class SimpleIndexTest : public net::TestWithTaskEnvironment, public SimpleIndexDelegate { protected: SimpleIndexTest() : hashes_(base::BindRepeating(&HashesInitializer)) {} |