summaryrefslogtreecommitdiff
path: root/chromium/net/disk_cache
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2020-01-20 13:40:20 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2020-01-22 12:41:23 +0000
commit7961cea6d1041e3e454dae6a1da660b453efd238 (patch)
treec0eeb4a9ff9ba32986289c1653d9608e53ccb444 /chromium/net/disk_cache
parentb7034d0803538058e5c9d904ef03cf5eab34f6ef (diff)
downloadqtwebengine-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')
-rw-r--r--chromium/net/disk_cache/backend_cleanup_tracker_unittest.cc4
-rw-r--r--chromium/net/disk_cache/backend_unittest.cc255
-rw-r--r--chromium/net/disk_cache/blockfile/backend_impl.cc48
-rw-r--r--chromium/net/disk_cache/blockfile/backend_impl.h21
-rw-r--r--chromium/net/disk_cache/blockfile/entry_impl.cc14
-rw-r--r--chromium/net/disk_cache/blockfile/file_ios.cc16
-rw-r--r--chromium/net/disk_cache/blockfile/file_posix.cc12
-rw-r--r--chromium/net/disk_cache/blockfile/in_flight_backend_io.cc106
-rw-r--r--chromium/net/disk_cache/blockfile/in_flight_backend_io.h45
-rw-r--r--chromium/net/disk_cache/cache_util.cc9
-rw-r--r--chromium/net/disk_cache/disk_cache.cc69
-rw-r--r--chromium/net/disk_cache/disk_cache.h148
-rw-r--r--chromium/net/disk_cache/disk_cache_fuzzer.cc200
-rw-r--r--chromium/net/disk_cache/disk_cache_perftest.cc67
-rw-r--r--chromium/net/disk_cache/disk_cache_test_base.cc57
-rw-r--r--chromium/net/disk_cache/disk_cache_test_base.h16
-rw-r--r--chromium/net/disk_cache/disk_cache_test_util.cc19
-rw-r--r--chromium/net/disk_cache/disk_cache_test_util.h32
-rw-r--r--chromium/net/disk_cache/entry_unittest.cc308
-rw-r--r--chromium/net/disk_cache/memory/mem_backend_impl.cc57
-rw-r--r--chromium/net/disk_cache/memory/mem_backend_impl.h21
-rw-r--r--chromium/net/disk_cache/memory/mem_entry_impl.cc4
-rw-r--r--chromium/net/disk_cache/memory/mem_entry_impl.h2
-rw-r--r--chromium/net/disk_cache/simple/simple_backend_impl.cc198
-rw-r--r--chromium/net/disk_cache/simple/simple_backend_impl.h31
-rw-r--r--chromium/net/disk_cache/simple/simple_entry_impl.cc181
-rw-r--r--chromium/net/disk_cache/simple/simple_entry_impl.h59
-rw-r--r--chromium/net/disk_cache/simple/simple_entry_operation.cc87
-rw-r--r--chromium/net/disk_cache/simple/simple_entry_operation.h34
-rw-r--r--chromium/net/disk_cache/simple/simple_index.cc3
-rw-r--r--chromium/net/disk_cache/simple/simple_index.h3
-rw-r--r--chromium/net/disk_cache/simple/simple_index_file_unittest.cc9
-rw-r--r--chromium/net/disk_cache/simple/simple_index_unittest.cc4
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)) {}