Separate Simple Backend creation from initialization.
[chromium-blink-merge.git] / net / disk_cache / cache_creator.cc
blob9a3a924a7f5a29bde5796597337141310145c061
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/file_util.h"
6 #include "base/metrics/field_trial.h"
7 #include "base/stringprintf.h"
8 #include "net/base/net_errors.h"
9 #include "net/disk_cache/backend_impl.h"
10 #include "net/disk_cache/cache_util.h"
11 #include "net/disk_cache/mem_backend_impl.h"
12 #include "net/disk_cache/simple/simple_backend_impl.h"
14 namespace {
16 // Builds an instance of the backend depending on platform, type, experiments
17 // etc. Takes care of the retry state. This object will self-destroy when
18 // finished.
19 class CacheCreator {
20 public:
21 CacheCreator(const base::FilePath& path, bool force, int max_bytes,
22 net::CacheType type, uint32 flags,
23 base::MessageLoopProxy* thread, net::NetLog* net_log,
24 disk_cache::Backend** backend,
25 const net::CompletionCallback& callback);
27 // Creates the backend.
28 int Run();
30 private:
31 ~CacheCreator();
33 void DoCallback(int result);
35 void OnIOComplete(int result);
37 const base::FilePath& path_;
38 bool force_;
39 bool retry_;
40 int max_bytes_;
41 net::CacheType type_;
42 uint32 flags_;
43 scoped_refptr<base::MessageLoopProxy> thread_;
44 disk_cache::Backend** backend_;
45 net::CompletionCallback callback_;
46 disk_cache::Backend* created_cache_;
47 net::NetLog* net_log_;
49 DISALLOW_COPY_AND_ASSIGN(CacheCreator);
52 CacheCreator::CacheCreator(
53 const base::FilePath& path, bool force, int max_bytes,
54 net::CacheType type, uint32 flags,
55 base::MessageLoopProxy* thread, net::NetLog* net_log,
56 disk_cache::Backend** backend,
57 const net::CompletionCallback& callback)
58 : path_(path),
59 force_(force),
60 retry_(false),
61 max_bytes_(max_bytes),
62 type_(type),
63 flags_(flags),
64 thread_(thread),
65 backend_(backend),
66 callback_(callback),
67 created_cache_(NULL),
68 net_log_(net_log) {
71 CacheCreator::~CacheCreator() {
74 int CacheCreator::Run() {
75 // TODO(pasko): The two caches should never coexist on disk. Each individual
76 // cache backend should fail to initialize if it observes the index that does
77 // not belong to it.
78 if (base::FieldTrialList::FindFullName("SimpleCacheTrial") == "Yes") {
79 // TODO(gavinp,pasko): While simple backend development proceeds, we're only
80 // testing it against net::DISK_CACHE. Turn it on for more cache types as
81 // appropriate.
82 if (type_ == net::DISK_CACHE) {
83 disk_cache::SimpleBackendImpl* simple_cache =
84 new disk_cache::SimpleBackendImpl(path_, max_bytes_, type_, thread_,
85 net_log_);
86 created_cache_ = simple_cache;
87 return simple_cache->Init(
88 base::Bind(&CacheCreator::OnIOComplete, base::Unretained(this)));
91 disk_cache::BackendImpl* new_cache =
92 new disk_cache::BackendImpl(path_, thread_, net_log_);
93 created_cache_ = new_cache;
94 new_cache->SetMaxSize(max_bytes_);
95 new_cache->SetType(type_);
96 new_cache->SetFlags(flags_);
97 int rv = new_cache->Init(
98 base::Bind(&CacheCreator::OnIOComplete, base::Unretained(this)));
99 DCHECK_EQ(net::ERR_IO_PENDING, rv);
100 return rv;
103 void CacheCreator::DoCallback(int result) {
104 DCHECK_NE(net::ERR_IO_PENDING, result);
105 if (result == net::OK)
106 *backend_ = created_cache_;
107 else {
108 LOG(ERROR) << "Unable to create cache";
109 *backend_ = NULL;
110 delete created_cache_;
112 callback_.Run(result);
113 delete this;
116 // If the initialization of the cache fails, and |force| is true, we will
117 // discard the whole cache and create a new one.
118 void CacheCreator::OnIOComplete(int result) {
119 if (result == net::OK || !force_ || retry_)
120 return DoCallback(result);
122 // This is a failure and we are supposed to try again, so delete the object,
123 // delete all the files, and try again.
124 retry_ = true;
125 delete created_cache_;
126 created_cache_ = NULL;
127 if (!disk_cache::DelayedCacheCleanup(path_))
128 return DoCallback(result);
130 // The worker thread will start deleting files soon, but the original folder
131 // is not there anymore... let's create a new set of files.
132 int rv = Run();
133 DCHECK_EQ(net::ERR_IO_PENDING, rv);
136 } // namespace
138 namespace disk_cache {
140 int CreateCacheBackend(net::CacheType type, const base::FilePath& path,
141 int max_bytes,
142 bool force, base::MessageLoopProxy* thread,
143 net::NetLog* net_log, Backend** backend,
144 const net::CompletionCallback& callback) {
145 DCHECK(!callback.is_null());
146 if (type == net::MEMORY_CACHE) {
147 *backend = disk_cache::MemBackendImpl::CreateBackend(max_bytes, net_log);
148 return *backend ? net::OK : net::ERR_FAILED;
150 DCHECK(thread);
151 CacheCreator* creator = new CacheCreator(path, force, max_bytes, type, kNone,
152 thread, net_log, backend, callback);
153 return creator->Run();
156 } // namespace disk_cache