summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-15 19:31:51 +0000
committerrvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-15 19:31:51 +0000
commitec44a9a1abaf8ffdc001182b0345295081c6b714 (patch)
treea14fa1aa0cdee98b8257b5845499bf33e5a36394
parenteb69ca8e12e0d7a7d42ea328a4597475d5198bc7 (diff)
downloadchromium_src-ec44a9a1abaf8ffdc001182b0345295081c6b714.zip
chromium_src-ec44a9a1abaf8ffdc001182b0345295081c6b714.tar.gz
chromium_src-ec44a9a1abaf8ffdc001182b0345295081c6b714.tar.bz2
Disk cache: Update the disk cache tools and tests to use
the new interface (provide a cache thread and callback). BUG=26730 TEST=unit tests Review URL: http://codereview.chromium.org/2739007 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@49819 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--net/disk_cache/backend_impl.cc54
-rw-r--r--net/disk_cache/backend_impl.h14
-rw-r--r--net/disk_cache/backend_unittest.cc125
-rw-r--r--net/disk_cache/disk_cache.h21
-rw-r--r--net/disk_cache/disk_cache_perftest.cc26
-rw-r--r--net/disk_cache/disk_cache_test_base.cc25
-rw-r--r--net/disk_cache/disk_cache_test_base.h8
-rw-r--r--net/disk_cache/disk_cache_test_util.cc6
-rw-r--r--net/disk_cache/mem_backend_impl.cc7
-rw-r--r--net/disk_cache/mem_backend_impl.h7
-rw-r--r--net/disk_cache/stress_cache.cc34
-rw-r--r--net/tools/crash_cache/crash_cache.cc114
-rw-r--r--net/tools/dump_cache/cache_dumper.cc30
-rw-r--r--net/tools/dump_cache/cache_dumper.h33
-rw-r--r--net/tools/dump_cache/upgrade.cc101
15 files changed, 414 insertions, 191 deletions
diff --git a/net/disk_cache/backend_impl.cc b/net/disk_cache/backend_impl.cc
index edd5c59..8fa56f0 100644
--- a/net/disk_cache/backend_impl.cc
+++ b/net/disk_cache/backend_impl.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2006-2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -20,6 +20,7 @@
#include "net/disk_cache/errors.h"
#include "net/disk_cache/hash.h"
#include "net/disk_cache/file.h"
+#include "net/disk_cache/mem_backend_impl.h"
// This has to be defined before including histogram_macros.h from this file.
#define NET_DISK_CACHE_BACKEND_IMPL_CC_
@@ -167,20 +168,18 @@ void SetFieldTrialInfo(int size_group) {
namespace disk_cache {
-Backend* CreateCacheBackend(const FilePath& full_path, bool force,
- int max_bytes, net::CacheType type) {
- // Create a backend without extra flags.
- return BackendImpl::CreateBackend(full_path, force, max_bytes, type, kNone);
-}
-
int CreateCacheBackend(net::CacheType type, const FilePath& path, int max_bytes,
bool force, base::MessageLoopProxy* thread,
Backend** backend, CompletionCallback* callback) {
- if (type == net::MEMORY_CACHE)
- *backend = CreateInMemoryCacheBackend(max_bytes);
- else
- *backend = BackendImpl::CreateBackend(path, force, max_bytes, type, kNone);
- return *backend ? net::OK : net::ERR_FAILED;
+ DCHECK(callback);
+ if (type == net::MEMORY_CACHE) {
+ *backend = MemBackendImpl::CreateBackend(max_bytes);
+ return *backend ? net::OK : net::ERR_FAILED;
+ }
+ DCHECK(thread);
+
+ return BackendImpl::CreateBackend(path, force, max_bytes, type, kNone, thread,
+ backend, callback);
}
// Returns the preferred maximum number of bytes for the cache given the
@@ -224,35 +223,42 @@ int PreferedCacheSize(int64 available) {
// desired path) cannot be created.
//
// Static.
-Backend* BackendImpl::CreateBackend(const FilePath& full_path, bool force,
- int max_bytes, net::CacheType type,
- BackendFlags flags) {
- BackendImpl* cache = new BackendImpl(full_path);
+int BackendImpl::CreateBackend(const FilePath& full_path, bool force,
+ int max_bytes, net::CacheType type,
+ uint32 flags, base::MessageLoopProxy* thread,
+ Backend** backend,
+ CompletionCallback* callback) {
+ BackendImpl* cache = new BackendImpl(full_path, thread);
cache->SetMaxSize(max_bytes);
cache->SetType(type);
cache->SetFlags(flags);
- if (cache->Init())
- return cache;
+ if (cache->Init()) {
+ *backend = cache;
+ return net::OK;
+ }
+ *backend = NULL;
delete cache;
if (!force)
- return NULL;
+ return net::ERR_FAILED;
if (!DelayedCacheCleanup(full_path))
- return NULL;
+ return net::ERR_FAILED;
// The worker thread will start deleting files soon, but the original folder
// is not there anymore... let's create a new set of files.
- cache = new BackendImpl(full_path);
+ cache = new BackendImpl(full_path, thread);
cache->SetMaxSize(max_bytes);
cache->SetType(type);
cache->SetFlags(flags);
- if (cache->Init())
- return cache;
+ if (cache->Init()) {
+ *backend = cache;
+ return net::OK;
+ }
delete cache;
LOG(ERROR) << "Unable to create cache";
- return NULL;
+ return net::ERR_FAILED;
}
bool BackendImpl::Init() {
diff --git a/net/disk_cache/backend_impl.h b/net/disk_cache/backend_impl.h
index 58d81eb..aa87a63 100644
--- a/net/disk_cache/backend_impl.h
+++ b/net/disk_cache/backend_impl.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2006-2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -35,14 +35,15 @@ enum BackendFlags {
class BackendImpl : public Backend {
friend class Eviction;
public:
- explicit BackendImpl(const FilePath& path)
+ BackendImpl(const FilePath& path, base::MessageLoopProxy* cache_thread)
: path_(path), block_files_(path), mask_(0), max_size_(0),
cache_type_(net::DISK_CACHE), uma_report_(0), user_flags_(0),
init_(false), restarted_(false), unit_test_(false), read_only_(false),
new_eviction_(false), first_timer_(true),
ALLOW_THIS_IN_INITIALIZER_LIST(factory_(this)) {}
// mask can be used to limit the usable size of the hash table, for testing.
- BackendImpl(const FilePath& path, uint32 mask)
+ BackendImpl(const FilePath& path, uint32 mask,
+ base::MessageLoopProxy* cache_thread)
: path_(path), block_files_(path), mask_(mask), max_size_(0),
cache_type_(net::DISK_CACHE), uma_report_(0), user_flags_(kMask),
init_(false), restarted_(false), unit_test_(false), read_only_(false),
@@ -52,9 +53,10 @@ class BackendImpl : public Backend {
// Returns a new backend with the desired flags. See the declaration of
// CreateCacheBackend().
- static Backend* CreateBackend(const FilePath& full_path, bool force,
- int max_bytes, net::CacheType type,
- BackendFlags flags);
+ static int CreateBackend(const FilePath& full_path, bool force,
+ int max_bytes, net::CacheType type,
+ uint32 flags, base::MessageLoopProxy* thread,
+ Backend** backend, CompletionCallback* callback);
// Performs general initialization for this current instance of the cache.
bool Init();
diff --git a/net/disk_cache/backend_unittest.cc b/net/disk_cache/backend_unittest.cc
index 41c8069..c659088 100644
--- a/net/disk_cache/backend_unittest.cc
+++ b/net/disk_cache/backend_unittest.cc
@@ -7,6 +7,7 @@
#include "base/path_service.h"
#include "base/platform_thread.h"
#include "base/string_util.h"
+#include "base/thread.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "net/base/test_completion_callback.h"
@@ -15,6 +16,7 @@
#include "net/disk_cache/disk_cache_test_util.h"
#include "net/disk_cache/histogram_macros.h"
#include "net/disk_cache/mapped_file.h"
+#include "net/disk_cache/mem_backend_impl.h"
#include "testing/gtest/include/gtest/gtest.h"
using base::Time;
@@ -187,6 +189,49 @@ TEST_F(DiskCacheBackendTest, MemoryOnlyKeying) {
BackendKeying();
}
+TEST_F(DiskCacheTest, CreateBackend) {
+ TestCompletionCallback cb;
+
+ {
+ FilePath path = GetCacheFilePath();
+ ASSERT_TRUE(DeleteCache(path));
+ base::Thread cache_thread("CacheThread");
+ ASSERT_TRUE(cache_thread.StartWithOptions(
+ base::Thread::Options(MessageLoop::TYPE_IO, 0)));
+
+ // Test the private factory methods.
+ disk_cache::Backend* cache = NULL;
+ int rv = disk_cache::BackendImpl::CreateBackend(
+ path, false, 0, net::DISK_CACHE, disk_cache::kNoRandom,
+ cache_thread.message_loop_proxy(), &cache, &cb);
+ ASSERT_EQ(net::OK, cb.GetResult(rv));
+ ASSERT_TRUE(cache);
+ delete cache;
+
+ cache = disk_cache::MemBackendImpl::CreateBackend(0);
+ ASSERT_TRUE(cache);
+ delete cache;
+ cache = NULL;
+
+ // Now test the public API.
+ rv = disk_cache::CreateCacheBackend(net::DISK_CACHE, path, 0, false,
+ cache_thread.message_loop_proxy(),
+ &cache, &cb);
+ ASSERT_EQ(net::OK, cb.GetResult(rv));
+ ASSERT_TRUE(cache);
+ delete cache;
+ cache = NULL;
+
+ rv = disk_cache::CreateCacheBackend(net::MEMORY_CACHE, FilePath(), 0, false,
+ NULL, &cache, &cb);
+ ASSERT_EQ(net::OK, cb.GetResult(rv));
+ ASSERT_TRUE(cache);
+ delete cache;
+ }
+
+ MessageLoop::current()->RunAllPending();
+}
+
TEST_F(DiskCacheBackendTest, ExternalFiles) {
InitCache();
// First, lets create a file on the folder.
@@ -215,12 +260,19 @@ TEST_F(DiskCacheTest, ShutdownWithPendingIO) {
{
FilePath path = GetCacheFilePath();
ASSERT_TRUE(DeleteCache(path));
+ base::Thread cache_thread("CacheThread");
+ ASSERT_TRUE(cache_thread.StartWithOptions(
+ base::Thread::Options(MessageLoop::TYPE_IO, 0)));
- disk_cache::Backend* cache =
- disk_cache::CreateCacheBackend(path, false, 0, net::DISK_CACHE);
+ disk_cache::Backend* cache;
+ int rv = disk_cache::BackendImpl::CreateBackend(
+ path, false, 0, net::DISK_CACHE, disk_cache::kNoRandom,
+ cache_thread.message_loop_proxy(), &cache, &callback);
+ ASSERT_EQ(net::OK, callback.GetResult(rv));
disk_cache::Entry* entry;
- ASSERT_TRUE(cache->CreateEntry("some key", &entry));
+ rv = cache->CreateEntry("some key", &entry, &callback);
+ ASSERT_EQ(net::OK, callback.GetResult(rv));
const int kSize = 25000;
scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(kSize);
@@ -247,11 +299,20 @@ TEST_F(DiskCacheTest, TruncatedIndex) {
ASSERT_TRUE(DeleteCache(path));
FilePath index = path.AppendASCII("index");
ASSERT_EQ(5, file_util::WriteFile(index, "hello", 5));
- scoped_ptr<disk_cache::Backend> backend;
- backend.reset(disk_cache::BackendImpl::CreateBackend(path, false, 0,
- net::DISK_CACHE,
- disk_cache::kNone));
- ASSERT_TRUE(backend.get() == NULL);
+
+ base::Thread cache_thread("CacheThread");
+ ASSERT_TRUE(cache_thread.StartWithOptions(
+ base::Thread::Options(MessageLoop::TYPE_IO, 0)));
+ TestCompletionCallback cb;
+
+ disk_cache::Backend* backend = NULL;
+ int rv = disk_cache::BackendImpl::CreateBackend(
+ path, false, 0, net::DISK_CACHE, disk_cache::kNone,
+ cache_thread.message_loop_proxy(), &backend, &cb);
+ ASSERT_NE(net::OK, cb.GetResult(rv));
+
+ ASSERT_TRUE(backend == NULL);
+ delete backend;
}
void DiskCacheBackendTest::BackendSetSize() {
@@ -1088,20 +1149,26 @@ TEST_F(DiskCacheBackendTest, NewEvictionRecoverRemove) {
}
// Tests dealing with cache files that cannot be recovered.
-TEST_F(DiskCacheTest, Backend_DeleteOld) {
+TEST_F(DiskCacheTest, DeleteOld) {
ASSERT_TRUE(CopyTestCache(L"wrong_version"));
FilePath path = GetCacheFilePath();
- scoped_ptr<disk_cache::Backend> cache;
- cache.reset(disk_cache::CreateCacheBackend(path, true, 0, net::DISK_CACHE));
+ base::Thread cache_thread("CacheThread");
+ ASSERT_TRUE(cache_thread.StartWithOptions(
+ base::Thread::Options(MessageLoop::TYPE_IO, 0)));
+ TestCompletionCallback cb;
+
+ disk_cache::Backend* cache;
+ int rv = disk_cache::BackendImpl::CreateBackend(
+ path, true, 0, net::DISK_CACHE, disk_cache::kNoRandom,
+ cache_thread.message_loop_proxy(), &cache, &cb);
+ ASSERT_EQ(net::OK, cb.GetResult(rv));
MessageLoopHelper helper;
- ASSERT_TRUE(NULL != cache.get());
+ ASSERT_TRUE(NULL != cache);
ASSERT_EQ(0, cache->GetEntryCount());
- // Wait for a callback that never comes... about 2 secs :). The message loop
- // has to run to allow destruction of the cleaner thread.
- helper.WaitUntilCacheIoFinished(1);
+ delete cache;
}
// We want to be able to deal with messed up entries on disk.
@@ -1443,7 +1510,8 @@ TEST_F(DiskCacheTest, Backend_UsageStats) {
FilePath path = GetCacheFilePath();
ASSERT_TRUE(DeleteCache(path));
scoped_ptr<disk_cache::BackendImpl> cache;
- cache.reset(new disk_cache::BackendImpl(path));
+ cache.reset(new disk_cache::BackendImpl(
+ path, base::MessageLoopProxy::CreateForCurrentThread()));
ASSERT_TRUE(NULL != cache.get());
cache->SetUnitTestMode();
ASSERT_TRUE(cache->Init());
@@ -1546,23 +1614,34 @@ TEST_F(DiskCacheTest, MultipleInstances) {
ScopedTestCache store1;
ScopedTestCache store2("cache_test2");
ScopedTestCache store3("cache_test3");
+ base::Thread cache_thread("CacheThread");
+ ASSERT_TRUE(cache_thread.StartWithOptions(
+ base::Thread::Options(MessageLoop::TYPE_IO, 0)));
+ TestCompletionCallback cb;
const int kNumberOfCaches = 2;
- scoped_ptr<disk_cache::Backend> cache[kNumberOfCaches];
+ disk_cache::Backend* cache[kNumberOfCaches];
- cache[0].reset(disk_cache::CreateCacheBackend(store1.path(), false, 0,
- net::DISK_CACHE));
- cache[1].reset(disk_cache::CreateCacheBackend(store2.path(), false, 0,
- net::MEDIA_CACHE));
+ int rv = disk_cache::BackendImpl::CreateBackend(
+ store1.path(), false, 0, net::DISK_CACHE, disk_cache::kNone,
+ cache_thread.message_loop_proxy(), &cache[0], &cb);
+ ASSERT_EQ(net::OK, cb.GetResult(rv));
+ rv = disk_cache::BackendImpl::CreateBackend(
+ store2.path(), false, 0, net::MEDIA_CACHE, disk_cache::kNone,
+ cache_thread.message_loop_proxy(), &cache[1], &cb);
+ ASSERT_EQ(net::OK, cb.GetResult(rv));
- ASSERT_TRUE(cache[0].get() != NULL && cache[1].get() != NULL);
+ ASSERT_TRUE(cache[0] != NULL && cache[1] != NULL);
std::string key("the first key");
disk_cache::Entry* entry;
for (int i = 0; i < kNumberOfCaches; i++) {
- ASSERT_TRUE(cache[i]->CreateEntry(key, &entry));
+ rv = cache[i]->CreateEntry(key, &entry, &cb);
+ ASSERT_EQ(net::OK, cb.GetResult(rv));
entry->Close();
}
+ delete cache[0];
+ delete cache[1];
}
// Test the six regions of the curve that determines the max cache size.
diff --git a/net/disk_cache/disk_cache.h b/net/disk_cache/disk_cache.h
index 36151ad..2cddf6f 100644
--- a/net/disk_cache/disk_cache.h
+++ b/net/disk_cache/disk_cache.h
@@ -32,27 +32,6 @@ class Entry;
class Backend;
typedef net::CompletionCallback CompletionCallback;
-// Returns an instance of the Backend. path points to a folder where
-// the cached data will be stored. This cache instance must be the only object
-// that will be reading or writing files to that folder. The returned object
-// should be deleted when not needed anymore. If force is true, and there is
-// a problem with the cache initialization, the files will be deleted and a
-// new set will be created. max_bytes is the maximum size the cache can grow to.
-// If zero is passed in as max_bytes, the cache will determine the value to use
-// based on the available disk space. The returned pointer can be NULL if a
-// fatal error is found.
-// Note: This function is deprecated.
-Backend* CreateCacheBackend(const FilePath& path, bool force,
- int max_bytes, net::CacheType type);
-
-// Returns an instance of a Backend implemented only in memory. The returned
-// object should be deleted when not needed anymore. max_bytes is the maximum
-// size the cache can grow to. If zero is passed in as max_bytes, the cache will
-// determine the value to use based on the available memory. The returned
-// pointer can be NULL if a fatal error is found.
-// Note: This function is deprecated.
-Backend* CreateInMemoryCacheBackend(int max_bytes);
-
// 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
// instance must be the only object that will be reading or writing files to
diff --git a/net/disk_cache/disk_cache_perftest.cc b/net/disk_cache/disk_cache_perftest.cc
index 4064341..6e0ca8a 100644
--- a/net/disk_cache/disk_cache_perftest.cc
+++ b/net/disk_cache/disk_cache_perftest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2006-2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -9,10 +9,12 @@
#include "base/file_util.h"
#include "base/perftimer.h"
#include "base/string_util.h"
+#include "base/thread.h"
#include "base/test/test_file_util.h"
#include "base/timer.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
+#include "net/base/test_completion_callback.h"
#include "net/disk_cache/block_files.h"
#include "net/disk_cache/disk_cache.h"
#include "net/disk_cache/disk_cache_test_util.h"
@@ -154,11 +156,18 @@ TEST_F(DiskCacheTest, Hash) {
TEST_F(DiskCacheTest, CacheBackendPerformance) {
MessageLoopForIO message_loop;
+ base::Thread cache_thread("CacheThread");
+ ASSERT_TRUE(cache_thread.StartWithOptions(
+ base::Thread::Options(MessageLoop::TYPE_IO, 0)));
+
ScopedTestCache test_cache;
- disk_cache::Backend* cache =
- disk_cache::CreateCacheBackend(test_cache.path(), false, 0,
- net::DISK_CACHE);
- ASSERT_TRUE(NULL != cache);
+ TestCompletionCallback cb;
+ disk_cache::Backend* cache;
+ int rv = disk_cache::CreateCacheBackend(
+ net::DISK_CACHE, test_cache.path(), 0, false,
+ cache_thread.message_loop_proxy(), &cache, &cb);
+
+ ASSERT_EQ(net::OK, cb.GetResult(rv));
int seed = static_cast<int>(Time::Now().ToInternalValue());
srand(seed);
@@ -183,9 +192,10 @@ TEST_F(DiskCacheTest, CacheBackendPerformance) {
ASSERT_TRUE(file_util::EvictFileFromSystemCache(
test_cache.path().AppendASCII("data_3")));
- cache = disk_cache::CreateCacheBackend(test_cache.path(), false, 0,
- net::DISK_CACHE);
- ASSERT_TRUE(NULL != cache);
+ rv = disk_cache::CreateCacheBackend(net::DISK_CACHE, test_cache.path(), 0,
+ false, cache_thread.message_loop_proxy(),
+ &cache, &cb);
+ ASSERT_EQ(net::OK, cb.GetResult(rv));
ret = TimeRead(num_entries, cache, entries, true);
EXPECT_EQ(ret, g_cache_tests_received);
diff --git a/net/disk_cache/disk_cache_test_base.cc b/net/disk_cache/disk_cache_test_base.cc
index 2738674..7b0cc8e 100644
--- a/net/disk_cache/disk_cache_test_base.cc
+++ b/net/disk_cache/disk_cache_test_base.cc
@@ -38,7 +38,7 @@ void DiskCacheTestWithCache::InitCache() {
void DiskCacheTestWithCache::InitMemoryCache() {
if (!implementation_) {
- cache_ = disk_cache::CreateInMemoryCacheBackend(size_);
+ cache_ = disk_cache::MemBackendImpl::CreateBackend(size_);
return;
}
@@ -57,19 +57,30 @@ void DiskCacheTestWithCache::InitDiskCache() {
if (first_cleanup_)
ASSERT_TRUE(DeleteCache(path));
+ if (!cache_thread_.IsRunning()) {
+ EXPECT_TRUE(cache_thread_.StartWithOptions(
+ base::Thread::Options(MessageLoop::TYPE_IO, 0)));
+ }
+ ASSERT_TRUE(cache_thread_.message_loop() != NULL);
+
if (implementation_)
return InitDiskCacheImpl(path);
- cache_ = disk_cache::BackendImpl::CreateBackend(path, force_creation_, size_,
- net::DISK_CACHE,
- disk_cache::kNoRandom);
+ TestCompletionCallback cb;
+ int rv = disk_cache::BackendImpl::CreateBackend(
+ path, force_creation_, size_, net::DISK_CACHE,
+ disk_cache::kNoRandom, cache_thread_.message_loop_proxy(),
+ &cache_, &cb);
+ ASSERT_EQ(net::OK, cb.GetResult(rv));
}
void DiskCacheTestWithCache::InitDiskCacheImpl(const FilePath& path) {
if (mask_)
- cache_impl_ = new disk_cache::BackendImpl(path, mask_);
+ cache_impl_ = new disk_cache::BackendImpl(
+ path, mask_, cache_thread_.message_loop_proxy());
else
- cache_impl_ = new disk_cache::BackendImpl(path);
+ cache_impl_ = new disk_cache::BackendImpl(
+ path, cache_thread_.message_loop_proxy());
cache_ = cache_impl_;
ASSERT_TRUE(NULL != cache_);
@@ -87,6 +98,8 @@ void DiskCacheTestWithCache::InitDiskCacheImpl(const FilePath& path) {
void DiskCacheTestWithCache::TearDown() {
MessageLoop::current()->RunAllPending();
delete cache_;
+ if (cache_thread_.IsRunning())
+ cache_thread_.Stop();
if (!memory_only_ && integrity_) {
FilePath path = GetCacheFilePath();
diff --git a/net/disk_cache/disk_cache_test_base.h b/net/disk_cache/disk_cache_test_base.h
index 0878a38..f3c8040 100644
--- a/net/disk_cache/disk_cache_test_base.h
+++ b/net/disk_cache/disk_cache_test_base.h
@@ -6,7 +6,7 @@
#define NET_DISK_CACHE_DISK_CACHE_TEST_BASE_H_
#include "base/basictypes.h"
-#include "base/time.h"
+#include "base/thread.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"
@@ -35,7 +35,8 @@ class DiskCacheTestWithCache : public DiskCacheTest {
DiskCacheTestWithCache()
: cache_(NULL), cache_impl_(NULL), mem_cache_(NULL), mask_(0), size_(0),
memory_only_(false), implementation_(false), force_creation_(false),
- new_eviction_(false), first_cleanup_(true), integrity_(true) {}
+ new_eviction_(false), first_cleanup_(true), integrity_(true),
+ cache_thread_("CacheThread") {}
void InitCache();
virtual void TearDown();
@@ -105,6 +106,9 @@ class DiskCacheTestWithCache : public DiskCacheTest {
void InitMemoryCache();
void InitDiskCache();
void InitDiskCacheImpl(const FilePath& path);
+
+ base::Thread cache_thread_;
+ DISALLOW_COPY_AND_ASSIGN(DiskCacheTestWithCache);
};
#endif // NET_DISK_CACHE_DISK_CACHE_TEST_BASE_H_
diff --git a/net/disk_cache/disk_cache_test_util.cc b/net/disk_cache/disk_cache_test_util.cc
index 36d28d2..480ba1d 100644
--- a/net/disk_cache/disk_cache_test_util.cc
+++ b/net/disk_cache/disk_cache_test_util.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2006-2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -6,6 +6,7 @@
#include "base/logging.h"
#include "base/file_util.h"
+#include "base/message_loop_proxy.h"
#include "base/path_service.h"
#include "net/disk_cache/backend_impl.h"
#include "net/disk_cache/cache_util.h"
@@ -77,7 +78,8 @@ bool DeleteCache(const FilePath& path) {
}
bool CheckCacheIntegrity(const FilePath& path, bool new_eviction) {
- scoped_ptr<disk_cache::BackendImpl> cache(new disk_cache::BackendImpl(path));
+ scoped_ptr<disk_cache::BackendImpl> cache(new disk_cache::BackendImpl(
+ path, base::MessageLoopProxy::CreateForCurrentThread()));
if (!cache.get())
return false;
if (new_eviction)
diff --git a/net/disk_cache/mem_backend_impl.cc b/net/disk_cache/mem_backend_impl.cc
index 875efdc..fe57d7d 100644
--- a/net/disk_cache/mem_backend_impl.cc
+++ b/net/disk_cache/mem_backend_impl.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2006-2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -28,7 +28,8 @@ int LowWaterAdjust(int high_water) {
namespace disk_cache {
-Backend* CreateInMemoryCacheBackend(int max_bytes) {
+// Static.
+Backend* MemBackendImpl::CreateBackend(int max_bytes) {
MemBackendImpl* cache = new MemBackendImpl();
cache->SetMaxSize(max_bytes);
if (cache->Init())
@@ -39,8 +40,6 @@ Backend* CreateInMemoryCacheBackend(int max_bytes) {
return NULL;
}
-// ------------------------------------------------------------------------
-
bool MemBackendImpl::Init() {
if (max_size_)
return true;
diff --git a/net/disk_cache/mem_backend_impl.h b/net/disk_cache/mem_backend_impl.h
index e687410..2072a56 100644
--- a/net/disk_cache/mem_backend_impl.h
+++ b/net/disk_cache/mem_backend_impl.h
@@ -23,6 +23,13 @@ class MemBackendImpl : public Backend {
MemBackendImpl() : max_size_(0), current_size_(0) {}
~MemBackendImpl();
+ // Returns an instance of a Backend implemented only in memory. The returned
+ // object should be deleted when not needed anymore. max_bytes is the maximum
+ // size the cache can grow to. If zero is passed in as max_bytes, the cache
+ // will determine the value to use based on the available memory. The returned
+ // pointer can be NULL if a fatal error is found.
+ static Backend* CreateBackend(int max_bytes);
+
// Performs general initialization for this current instance of the cache.
bool Init();
diff --git a/net/disk_cache/stress_cache.cc b/net/disk_cache/stress_cache.cc
index 3619a5f..f5c7880 100644
--- a/net/disk_cache/stress_cache.cc
+++ b/net/disk_cache/stress_cache.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2006-2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -24,6 +24,8 @@
#include "base/process_util.h"
#include "base/string_util.h"
#include "base/thread.h"
+#include "net/base/net_errors.h"
+#include "net/base/test_completion_callback.h"
#include "net/base/io_buffer.h"
#include "net/disk_cache/backend_impl.h"
#include "net/disk_cache/disk_cache.h"
@@ -77,11 +79,20 @@ int MasterCode() {
void StressTheCache(int iteration) {
int cache_size = 0x800000; // 8MB
FilePath path = GetCacheFilePath().AppendASCII("_stress");
- disk_cache::BackendImpl* cache = new disk_cache::BackendImpl(path);
- cache->SetFlags(disk_cache::kNoLoadProtection | disk_cache::kNoRandom);
- cache->SetMaxSize(cache_size);
- cache->SetType(net::DISK_CACHE);
- if (!cache->Init()) {
+
+ base::Thread cache_thread("CacheThread");
+ if (!cache_thread.StartWithOptions(
+ base::Thread::Options(MessageLoop::TYPE_IO, 0)))
+ return;
+
+ TestCompletionCallback cb;
+ disk_cache::Backend* cache;
+ int rv = disk_cache::BackendImpl::CreateBackend(
+ path, false, cache_size, net::DISK_CACHE,
+ disk_cache::kNoLoadProtection | disk_cache::kNoRandom,
+ cache_thread.message_loop_proxy(), &cache, &cb);
+
+ if (cb.GetResult(rv) != net::OK) {
printf("Unable to initialize cache.\n");
return;
}
@@ -111,12 +122,15 @@ void StressTheCache(int iteration) {
if (entries[slot])
entries[slot]->Close();
- if (!cache->OpenEntry(keys[key], &entries[slot]))
- CHECK(cache->CreateEntry(keys[key], &entries[slot]));
+ rv = cache->OpenEntry(keys[key], &entries[slot], &cb);
+ if (cb.GetResult(rv) != net::OK) {
+ rv = cache->CreateEntry(keys[key], &entries[slot], &cb);
+ CHECK_EQ(net::OK, cb.GetResult(rv));
+ }
base::snprintf(buffer->data(), kSize, "%d %d", iteration, i);
- CHECK_EQ(kSize,
- entries[slot]->WriteData(0, 0, buffer, kSize, NULL, false));
+ rv = entries[slot]->WriteData(0, 0, buffer, kSize, &cb, false);
+ CHECK_EQ(kSize, cb.GetResult(rv));
if (rand() % 100 > 80) {
key = rand() % kNumKeys;
diff --git a/net/tools/crash_cache/crash_cache.cc b/net/tools/crash_cache/crash_cache.cc
index 4686d13..a26c873 100644
--- a/net/tools/crash_cache/crash_cache.cc
+++ b/net/tools/crash_cache/crash_cache.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2006-2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -17,7 +17,9 @@
#include "base/path_service.h"
#include "base/process_util.h"
#include "base/string_util.h"
-
+#include "base/thread.h"
+#include "net/base/net_errors.h"
+#include "net/base/test_completion_callback.h"
#include "net/disk_cache/backend_impl.h"
#include "net/disk_cache/disk_cache.h"
#include "net/disk_cache/disk_cache_test_util.h"
@@ -117,10 +119,14 @@ bool CreateTargetFolder(const FilePath& path, RankCrashes action,
}
// Generates the files for an empty and one item cache.
-int SimpleInsert(const FilePath& path, RankCrashes action) {
- disk_cache::Backend* cache = disk_cache::CreateCacheBackend(path, false, 0,
- net::DISK_CACHE);
- if (!cache || cache->GetEntryCount())
+int SimpleInsert(const FilePath& path, RankCrashes action,
+ base::Thread* cache_thread) {
+ TestCompletionCallback cb;
+ disk_cache::Backend* cache;
+ int rv = disk_cache::CreateCacheBackend(net::DISK_CACHE, path, 0, false,
+ cache_thread->message_loop_proxy(),
+ &cache, &cb);
+ if (cb.GetResult(rv) != net::OK || cache->GetEntryCount())
return GENERIC;
const char* test_name = "some other key";
@@ -131,7 +137,8 @@ int SimpleInsert(const FilePath& path, RankCrashes action) {
}
disk_cache::Entry* entry;
- if (!cache->CreateEntry(test_name, &entry))
+ rv = cache->CreateEntry(test_name, &entry, &cb);
+ if (cb.GetResult(rv) != net::OK)
return GENERIC;
entry->Close();
@@ -140,36 +147,44 @@ int SimpleInsert(const FilePath& path, RankCrashes action) {
g_rankings_crash = action;
test_name = kCrashEntryName;
- if (!cache->CreateEntry(test_name, &entry))
+ rv = cache->CreateEntry(test_name, &entry, &cb);
+ if (cb.GetResult(rv) != net::OK)
return GENERIC;
return NOT_REACHED;
}
// Generates the files for a one item cache, and removing the head.
-int SimpleRemove(const FilePath& path, RankCrashes action) {
+int SimpleRemove(const FilePath& path, RankCrashes action,
+ base::Thread* cache_thread) {
DCHECK(action >= disk_cache::REMOVE_ONE_1);
DCHECK(action <= disk_cache::REMOVE_TAIL_3);
- disk_cache::Backend* cache = disk_cache::CreateCacheBackend(path, false, 0,
- net::DISK_CACHE);
- if (!cache || cache->GetEntryCount())
+ TestCompletionCallback cb;
+ disk_cache::Backend* cache;
+ int rv = disk_cache::CreateCacheBackend(net::DISK_CACHE, path, 0, false,
+ cache_thread->message_loop_proxy(),
+ &cache, &cb);
+ if (cb.GetResult(rv) != net::OK || cache->GetEntryCount())
return GENERIC;
disk_cache::Entry* entry;
- if (!cache->CreateEntry(kCrashEntryName, &entry))
+ rv = cache->CreateEntry(kCrashEntryName, &entry, &cb);
+ if (cb.GetResult(rv) != net::OK)
return GENERIC;
entry->Close();
if (action >= disk_cache::REMOVE_TAIL_1) {
- if (!cache->CreateEntry("some other key", &entry))
+ rv = cache->CreateEntry("some other key", &entry, &cb);
+ if (cb.GetResult(rv) != net::OK)
return GENERIC;
entry->Close();
}
- if (!cache->OpenEntry(kCrashEntryName, &entry))
+ rv = cache->OpenEntry(kCrashEntryName, &entry, &cb);
+ if (cb.GetResult(rv) != net::OK)
return GENERIC;
g_rankings_crash = action;
@@ -179,26 +194,33 @@ int SimpleRemove(const FilePath& path, RankCrashes action) {
return NOT_REACHED;
}
-int HeadRemove(const FilePath& path, RankCrashes action) {
+int HeadRemove(const FilePath& path, RankCrashes action,
+ base::Thread* cache_thread) {
DCHECK(action >= disk_cache::REMOVE_HEAD_1);
DCHECK(action <= disk_cache::REMOVE_HEAD_4);
- disk_cache::Backend* cache = disk_cache::CreateCacheBackend(path, false, 0,
- net::DISK_CACHE);
- if (!cache || cache->GetEntryCount())
+ TestCompletionCallback cb;
+ disk_cache::Backend* cache;
+ int rv = disk_cache::CreateCacheBackend(net::DISK_CACHE, path, 0, false,
+ cache_thread->message_loop_proxy(),
+ &cache, &cb);
+ if (cb.GetResult(rv) != net::OK || cache->GetEntryCount())
return GENERIC;
disk_cache::Entry* entry;
- if (!cache->CreateEntry("some other key", &entry))
+ rv = cache->CreateEntry("some other key", &entry, &cb);
+ if (cb.GetResult(rv) != net::OK)
return GENERIC;
entry->Close();
- if (!cache->CreateEntry(kCrashEntryName, &entry))
+ rv = cache->CreateEntry(kCrashEntryName, &entry, &cb);
+ if (cb.GetResult(rv) != net::OK)
return GENERIC;
entry->Close();
- if (!cache->OpenEntry(kCrashEntryName, &entry))
+ rv = cache->OpenEntry(kCrashEntryName, &entry, &cb);
+ if (cb.GetResult(rv) != net::OK)
return GENERIC;
g_rankings_crash = action;
@@ -209,27 +231,34 @@ int HeadRemove(const FilePath& path, RankCrashes action) {
}
// Generates the files for insertion and removals on heavy loaded caches.
-int LoadOperations(const FilePath& path, RankCrashes action) {
+int LoadOperations(const FilePath& path, RankCrashes action,
+ base::Thread* cache_thread) {
DCHECK(action >= disk_cache::INSERT_LOAD_1);
- // Work with a tiny index table (16 entries)
- disk_cache::BackendImpl* cache =
- new disk_cache::BackendImpl(path, 0xf);
- if (!cache || !cache->SetMaxSize(0x100000) || !cache->Init() ||
- cache->GetEntryCount())
+ // Work with a tiny index table (16 entries).
+ disk_cache::BackendImpl* cache = new disk_cache::BackendImpl(
+ path, 0xf, cache_thread->message_loop_proxy());
+ if (!cache || !cache->SetMaxSize(0x100000))
+ return GENERIC;
+
+ if (!cache->Init() || cache->GetEntryCount())
return GENERIC;
int seed = static_cast<int>(Time::Now().ToInternalValue());
srand(seed);
+ TestCompletionCallback cb;
+ int rv;
disk_cache::Entry* entry;
for (int i = 0; i < 100; i++) {
std::string key = GenerateKey(true);
- if (!cache->CreateEntry(key, &entry))
+ rv = cache->CreateEntry(key, &entry, &cb);
+ if (cb.GetResult(rv) != net::OK)
return GENERIC;
entry->Close();
if (50 == i && action >= disk_cache::REMOVE_LOAD_1) {
- if (!cache->CreateEntry(kCrashEntryName, &entry))
+ rv = cache->CreateEntry(kCrashEntryName, &entry, &cb);
+ if (cb.GetResult(rv) != net::OK)
return GENERIC;
entry->Close();
}
@@ -238,11 +267,13 @@ int LoadOperations(const FilePath& path, RankCrashes action) {
if (action <= disk_cache::INSERT_LOAD_2) {
g_rankings_crash = action;
- if (!cache->CreateEntry(kCrashEntryName, &entry))
+ rv = cache->CreateEntry(kCrashEntryName, &entry, &cb);
+ if (cb.GetResult(rv) != net::OK)
return GENERIC;
}
- if (!cache->OpenEntry(kCrashEntryName, &entry))
+ rv = cache->OpenEntry(kCrashEntryName, &entry, &cb);
+ if (cb.GetResult(rv) != net::OK)
return GENERIC;
g_rankings_crash = action;
@@ -255,7 +286,7 @@ int LoadOperations(const FilePath& path, RankCrashes action) {
// Main function on the child process.
int SlaveCode(const FilePath& path, RankCrashes action) {
- MessageLoop message_loop;
+ MessageLoopForIO message_loop;
FilePath full_path;
if (!CreateTargetFolder(path, action, &full_path)) {
@@ -263,23 +294,28 @@ int SlaveCode(const FilePath& path, RankCrashes action) {
return CRASH_OVERWRITE;
}
+ base::Thread cache_thread("CacheThread");
+ if (!cache_thread.StartWithOptions(
+ base::Thread::Options(MessageLoop::TYPE_IO, 0)))
+ return GENERIC;
+
if (action <= disk_cache::INSERT_ONE_3)
- return SimpleInsert(full_path, action);
+ return SimpleInsert(full_path, action, &cache_thread);
if (action <= disk_cache::INSERT_LOAD_2)
- return LoadOperations(full_path, action);
+ return LoadOperations(full_path, action, &cache_thread);
if (action <= disk_cache::REMOVE_ONE_4)
- return SimpleRemove(full_path, action);
+ return SimpleRemove(full_path, action, &cache_thread);
if (action <= disk_cache::REMOVE_HEAD_4)
- return HeadRemove(full_path, action);
+ return HeadRemove(full_path, action, &cache_thread);
if (action <= disk_cache::REMOVE_TAIL_3)
- return SimpleRemove(full_path, action);
+ return SimpleRemove(full_path, action, &cache_thread);
if (action <= disk_cache::REMOVE_LOAD_3)
- return LoadOperations(full_path, action);
+ return LoadOperations(full_path, action, &cache_thread);
return NOT_REACHED;
}
diff --git a/net/tools/dump_cache/cache_dumper.cc b/net/tools/dump_cache/cache_dumper.cc
index 74f1482..71720af 100644
--- a/net/tools/dump_cache/cache_dumper.cc
+++ b/net/tools/dump_cache/cache_dumper.cc
@@ -16,10 +16,10 @@ bool CacheDumper::CreateEntry(const std::string& key,
return cache_->CreateEntry(key, entry);
}
-bool CacheDumper::WriteEntry(disk_cache::Entry* entry, int index, int offset,
- net::IOBuffer* buf, int buf_len) {
- int written = entry->WriteData(index, offset, buf, buf_len, NULL, false);
- return written == buf_len;
+int CacheDumper::WriteEntry(disk_cache::Entry* entry, int index, int offset,
+ net::IOBuffer* buf, int buf_len,
+ net::CompletionCallback* callback) {
+ return entry->WriteData(index, offset, buf, buf_len, callback, false);
}
void CacheDumper::CloseEntry(disk_cache::Entry* entry, base::Time last_used,
@@ -48,7 +48,7 @@ bool SafeCreateDirectory(const std::wstring& path) {
pos = 4;
// Create the subdirectories individually
- while((pos = path.find(backslash, pos)) != std::wstring::npos) {
+ while ((pos = path.find(backslash, pos)) != std::wstring::npos) {
std::wstring subdir = path.substr(0, pos);
CreateDirectoryW(subdir.c_str(), NULL);
// we keep going even if directory creation failed.
@@ -141,10 +141,11 @@ void GetNormalizedHeaders(const net::HttpResponseInfo& info,
output->append("\r\n");
}
-bool DiskDumper::WriteEntry(disk_cache::Entry* entry, int index, int offset,
- net::IOBuffer* buf, int buf_len) {
+int DiskDumper::WriteEntry(disk_cache::Entry* entry, int index, int offset,
+ net::IOBuffer* buf, int buf_len,
+ net::CompletionCallback* callback) {
if (!entry_)
- return false;
+ return 0;
std::string headers;
const char *data;
@@ -154,11 +155,11 @@ bool DiskDumper::WriteEntry(disk_cache::Entry* entry, int index, int offset,
bool truncated;
if (!net::HttpCache::ParseResponseInfo(buf->data(), buf_len,
&response_info, &truncated))
- return false;
+ return 0;
// Skip this entry if it was truncated (results in an empty file).
if (truncated)
- return true;
+ return buf_len;
// Remove the size headers.
response_info.headers->RemoveHeader("transfer-encoding");
@@ -188,11 +189,12 @@ bool DiskDumper::WriteEntry(disk_cache::Entry* entry, int index, int offset,
}
#ifdef WIN32_LARGE_FILENAME_SUPPORT
DWORD bytes;
- DWORD rv = WriteFile(entry_, data, len, &bytes, 0);
- return rv == TRUE && bytes == static_cast<DWORD>(len);
+ if (!WriteFile(entry_, data, len, &bytes, 0))
+ return 0;
+
+ return bytes;
#else
- int bytes = fwrite(data, 1, len, entry_);
- return bytes == len;
+ return fwrite(data, 1, len, entry_);
#endif
}
diff --git a/net/tools/dump_cache/cache_dumper.h b/net/tools/dump_cache/cache_dumper.h
index 916b1b4..1af8573 100644
--- a/net/tools/dump_cache/cache_dumper.h
+++ b/net/tools/dump_cache/cache_dumper.h
@@ -1,9 +1,9 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef NET_TOOLS_DUMP_CACHE_DUMPER_H_
-#define NET_TOOLS_DUMP_CACHE_DUMPER_H_
+#ifndef NET_TOOLS_DUMP_CACHE_CACHE_DUMPER_H_
+#define NET_TOOLS_DUMP_CACHE_CACHE_DUMPER_H_
#include <string>
#include "base/file_path.h"
@@ -22,6 +22,8 @@
// An abstract class for writing cache dump data.
class CacheDumpWriter {
public:
+ virtual ~CacheDumpWriter() {}
+
// Creates an entry to be written.
// On success, populates the |entry|.
// Returns true on success, false otherwise.
@@ -30,8 +32,9 @@ class CacheDumpWriter {
// Write to the current entry.
// Returns true on success, false otherwise.
- virtual bool WriteEntry(disk_cache::Entry* entry, int stream, int offset,
- net::IOBuffer* buf, int buf_len) = 0;
+ virtual int WriteEntry(disk_cache::Entry* entry, int stream, int offset,
+ net::IOBuffer* buf, int buf_len,
+ net::CompletionCallback* callback) = 0;
// Close the current entry.
virtual void CloseEntry(disk_cache::Entry* entry, base::Time last_used,
@@ -41,27 +44,29 @@ class CacheDumpWriter {
// Writes data to a cache.
class CacheDumper : public CacheDumpWriter {
public:
- CacheDumper(disk_cache::BackendImpl* cache) : cache_(cache) {};
+ explicit CacheDumper(disk_cache::Backend* cache) : cache_(cache) {}
virtual bool CreateEntry(const std::string& key, disk_cache::Entry** entry);
- virtual bool WriteEntry(disk_cache::Entry* entry, int stream, int offset,
- net::IOBuffer* buf, int buf_len);
+ virtual int WriteEntry(disk_cache::Entry* entry, int stream, int offset,
+ net::IOBuffer* buf, int buf_len,
+ net::CompletionCallback* callback);
virtual void CloseEntry(disk_cache::Entry* entry, base::Time last_used,
base::Time last_modified);
private:
- disk_cache::BackendImpl* cache_;
+ disk_cache::Backend* cache_;
};
// Writes data to a disk.
class DiskDumper : public CacheDumpWriter {
public:
- DiskDumper(const std::wstring& path) : path_(path), entry_(NULL) {
+ explicit DiskDumper(const std::wstring& path) : path_(path), entry_(NULL) {
file_util::CreateDirectory(FilePath(path));
- };
+ }
virtual bool CreateEntry(const std::string& key, disk_cache::Entry** entry);
- virtual bool WriteEntry(disk_cache::Entry* entry, int stream, int offset,
- net::IOBuffer* buf, int buf_len);
+ virtual int WriteEntry(disk_cache::Entry* entry, int stream, int offset,
+ net::IOBuffer* buf, int buf_len,
+ net::CompletionCallback* callback);
virtual void CloseEntry(disk_cache::Entry* entry, base::Time last_used,
base::Time last_modified);
@@ -79,4 +84,4 @@ class DiskDumper : public CacheDumpWriter {
#endif
};
-#endif // NET_TOOLS_DUMP_CACHE_DUMPER_H_
+#endif // NET_TOOLS_DUMP_CACHE_CACHE_DUMPER_H_
diff --git a/net/tools/dump_cache/upgrade.cc b/net/tools/dump_cache/upgrade.cc
index 71031dc..4f565fe 100644
--- a/net/tools/dump_cache/upgrade.cc
+++ b/net/tools/dump_cache/upgrade.cc
@@ -7,8 +7,10 @@
#include "base/message_loop.h"
#include "base/scoped_ptr.h"
#include "base/string_util.h"
+#include "base/thread.h"
#include "googleurl/src/gurl.h"
#include "net/base/io_buffer.h"
+#include "net/base/test_completion_callback.h"
#include "net/disk_cache/backend_impl.h"
#include "net/disk_cache/entry_impl.h"
#include "net/http/http_cache.h"
@@ -109,7 +111,7 @@ enum {
class BaseSM : public MessageLoopForIO::IOHandler {
public:
- BaseSM(HANDLE channel);
+ explicit BaseSM(HANDLE channel);
virtual ~BaseSM();
protected:
@@ -128,11 +130,14 @@ class BaseSM : public MessageLoopForIO::IOHandler {
scoped_array<char> out_buffer_;
IoBuffer* input_;
IoBuffer* output_;
+ base::Thread cache_thread_;
+
DISALLOW_COPY_AND_ASSIGN(BaseSM);
};
BaseSM::BaseSM(HANDLE channel)
- : entry_(NULL), channel_(channel), state_(0), pending_count_(0) {
+ : entry_(NULL), channel_(channel), state_(0), pending_count_(0),
+ cache_thread_("cache") {
in_buffer_.reset(new char[kChannelSize]);
out_buffer_.reset(new char[kChannelSize]);
input_ = reinterpret_cast<IoBuffer*>(in_buffer_.get());
@@ -143,6 +148,8 @@ BaseSM::BaseSM(HANDLE channel)
in_context_.handler = this;
out_context_.handler = this;
MessageLoopForIO::current()->RegisterIOHandler(channel_, this);
+ CHECK(cache_thread_.StartWithOptions(
+ base::Thread::Options(MessageLoop::TYPE_IO, 0)));
}
BaseSM::~BaseSM() {
@@ -200,8 +207,10 @@ bool BaseSM::IsPending() {
class MasterSM : public BaseSM {
public:
- MasterSM(const std::wstring& path, HANDLE channel, bool dump_to_disk)
- : BaseSM(channel), path_(path), dump_to_disk_(dump_to_disk) {
+ MasterSM(const std::wstring& path, HANDLE channel, bool dump_to_disk)
+ : BaseSM(channel), path_(path), dump_to_disk_(dump_to_disk),
+ ALLOW_THIS_IN_INITIALIZER_LIST(
+ write_callback_(this, &MasterSM::DoReadDataComplete)) {
}
virtual ~MasterSM() {
delete writer_;
@@ -233,6 +242,7 @@ class MasterSM : public BaseSM {
void CloseEntry();
void SendReadData();
void DoReadData(int bytes_read);
+ void DoReadDataComplete(int ret);
void SendQuit();
void DoEnd();
void Fail();
@@ -244,10 +254,12 @@ class MasterSM : public BaseSM {
int bytes_remaining_;
int offset_;
int copied_entries_;
- scoped_ptr<disk_cache::BackendImpl> cache_;
+ int read_size_;
+ scoped_ptr<disk_cache::Backend> cache_;
CacheDumpWriter* writer_;
const std::wstring& path_;
bool dump_to_disk_;
+ net::CompletionCallbackImpl<MasterSM> write_callback_;
};
void MasterSM::OnIOCompleted(MessageLoopForIO::IOContext* context,
@@ -302,11 +314,18 @@ bool MasterSM::DoInit() {
if (dump_to_disk_) {
writer_ = new DiskDumper(path_);
} else {
- cache_.reset(new disk_cache::BackendImpl(FilePath::FromWStringHack(path_)));
- if (!cache_->Init()) {
+ disk_cache::Backend* cache;
+ TestCompletionCallback cb;
+ int rv = disk_cache::CreateCacheBackend(net::DISK_CACHE,
+ FilePath::FromWStringHack(path_), 0,
+ false,
+ cache_thread_.message_loop_proxy(),
+ &cache, &cb);
+ if (cb.GetResult(rv) != net::OK) {
printf("Unable to initialize new files\n");
return false;
}
+ cache_.reset(cache);
writer_ = new CacheDumper(cache_.get());
}
if (!writer_)
@@ -474,7 +493,15 @@ void MasterSM::DoReadData(int bytes_read) {
scoped_refptr<net::WrappedIOBuffer> buf =
new net::WrappedIOBuffer(input_->buffer);
- if (!writer_->WriteEntry(entry_, stream_, offset_, buf, read_size))
+ int rv = writer_->WriteEntry(entry_, stream_, offset_, buf, read_size,
+ &write_callback_);
+ if (rv == net::ERR_IO_PENDING) {
+ // We'll continue in DoReadDataComplete.
+ read_size_ = read_size;
+ return;
+ }
+
+ if (rv <= 0)
return Fail();
offset_ += read_size;
@@ -483,6 +510,16 @@ void MasterSM::DoReadData(int bytes_read) {
SendReadData();
}
+void MasterSM::DoReadDataComplete(int ret) {
+ if (ret != read_size_)
+ return Fail();
+
+ offset_ += ret;
+ bytes_remaining_ -= ret;
+ // Read some more.
+ SendReadData();
+}
+
void MasterSM::SendQuit() {
DEBUGMSG("Master SendQuit\n");
state_ = MASTER_END;
@@ -508,15 +545,7 @@ void MasterSM::Fail() {
class SlaveSM : public BaseSM {
public:
- SlaveSM(const std::wstring& path, HANDLE channel)
- : BaseSM(channel), iterator_(NULL) {
- cache_.reset(new disk_cache::BackendImpl(FilePath::FromWStringHack(path)));
- if (!cache_->Init()) {
- printf("Unable to open cache files\n");
- return;
- }
- cache_->SetUpgradeMode();
- }
+ SlaveSM(const std::wstring& path, HANDLE channel);
virtual ~SlaveSM();
bool DoInit();
@@ -538,14 +567,36 @@ class SlaveSM : public BaseSM {
void DoGetUseTimes();
void DoGetDataSize();
void DoReadData();
+ void DoReadDataComplete(int ret);
void DoEnd();
void Fail();
void* iterator_;
+ Message msg_; // Only used for DoReadDataComplete.
+ net::CompletionCallbackImpl<SlaveSM> read_callback_;
scoped_ptr<disk_cache::BackendImpl> cache_;
};
+SlaveSM::SlaveSM(const std::wstring& path, HANDLE channel)
+ : BaseSM(channel), iterator_(NULL),
+ ALLOW_THIS_IN_INITIALIZER_LIST(
+ read_callback_(this, &SlaveSM::DoReadDataComplete)) {
+ disk_cache::Backend* cache;
+ TestCompletionCallback cb;
+ int rv = disk_cache::CreateCacheBackend(net::DISK_CACHE,
+ FilePath::FromWStringHack(path), 0,
+ false,
+ cache_thread_.message_loop_proxy(),
+ &cache, &cb);
+ if (cb.GetResult(rv) != net::OK) {
+ printf("Unable to open cache files\n");
+ return;
+ }
+ cache_.reset(reinterpret_cast<disk_cache::BackendImpl*>(cache));
+ cache_->SetUpgradeMode();
+}
+
SlaveSM::~SlaveSM() {
if (iterator_)
cache_->EndEnumeration(&iterator_);
@@ -753,7 +804,13 @@ void SlaveSM::DoReadData() {
} else {
scoped_refptr<net::WrappedIOBuffer> buf =
new net::WrappedIOBuffer(output_->buffer);
- int ret = entry_->ReadData(stream, input_->msg.arg3, buf, size, NULL);
+ int ret = entry_->ReadData(stream, input_->msg.arg3, buf, size,
+ &read_callback_);
+ if (ret == net::ERR_IO_PENDING) {
+ // Save the message so we can continue were we left.
+ msg_ = msg;
+ return;
+ }
msg.buffer_bytes = (ret < 0) ? 0 : ret;
msg.result = RESULT_OK;
@@ -761,6 +818,14 @@ void SlaveSM::DoReadData() {
SendMsg(msg);
}
+void SlaveSM::DoReadDataComplete(int ret) {
+ DEBUGMSG("\t\t\tSlave DoReadDataComplete\n");
+ DCHECK_EQ(READ_DATA, msg_.command);
+ msg_.buffer_bytes = (ret < 0) ? 0 : ret;
+ msg_.result = RESULT_OK;
+ SendMsg(msg_);
+}
+
void SlaveSM::DoEnd() {
DEBUGMSG("\t\t\tSlave DoEnd\n");
MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask());