Fix recording of "Time to error histograms".
[chromium-blink-merge.git] / net / disk_cache / cache_creator.cc
blob8c4400c2f23c7b48ccc15897da80f42e5e91f51e
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/files/file_path.h"
6 #include "base/metrics/field_trial.h"
7 #include "base/single_thread_task_runner.h"
8 #include "base/strings/stringprintf.h"
9 #include "net/base/cache_type.h"
10 #include "net/base/net_errors.h"
11 #include "net/disk_cache/blockfile/backend_impl.h"
12 #include "net/disk_cache/cache_util.h"
13 #include "net/disk_cache/disk_cache.h"
14 #include "net/disk_cache/memory/mem_backend_impl.h"
15 #include "net/disk_cache/simple/simple_backend_impl.h"
17 namespace {
19 // Builds an instance of the backend depending on platform, type, experiments
20 // etc. Takes care of the retry state. This object will self-destroy when
21 // finished.
22 class CacheCreator {
23 public:
24 CacheCreator(const base::FilePath& path,
25 bool force,
26 int max_bytes,
27 net::CacheType type,
28 net::BackendType backend_type,
29 uint32 flags,
30 const scoped_refptr<base::SingleThreadTaskRunner>& thread,
31 net::NetLog* net_log,
32 scoped_ptr<disk_cache::Backend>* backend,
33 const net::CompletionCallback& callback);
35 // Creates the backend.
36 int Run();
38 private:
39 ~CacheCreator();
41 void DoCallback(int result);
43 void OnIOComplete(int result);
45 const base::FilePath path_;
46 bool force_;
47 bool retry_;
48 int max_bytes_;
49 net::CacheType type_;
50 net::BackendType backend_type_;
51 uint32 flags_;
52 scoped_refptr<base::SingleThreadTaskRunner> thread_;
53 scoped_ptr<disk_cache::Backend>* backend_;
54 net::CompletionCallback callback_;
55 scoped_ptr<disk_cache::Backend> created_cache_;
56 net::NetLog* net_log_;
58 DISALLOW_COPY_AND_ASSIGN(CacheCreator);
61 CacheCreator::CacheCreator(
62 const base::FilePath& path,
63 bool force,
64 int max_bytes,
65 net::CacheType type,
66 net::BackendType backend_type,
67 uint32 flags,
68 const scoped_refptr<base::SingleThreadTaskRunner>& thread,
69 net::NetLog* net_log,
70 scoped_ptr<disk_cache::Backend>* backend,
71 const net::CompletionCallback& callback)
72 : path_(path),
73 force_(force),
74 retry_(false),
75 max_bytes_(max_bytes),
76 type_(type),
77 backend_type_(backend_type),
78 flags_(flags),
79 thread_(thread),
80 backend_(backend),
81 callback_(callback),
82 net_log_(net_log) {
85 CacheCreator::~CacheCreator() {
88 int CacheCreator::Run() {
89 #if defined(OS_ANDROID)
90 static const bool kSimpleBackendIsDefault = true;
91 #else
92 static const bool kSimpleBackendIsDefault = false;
93 #endif
94 if (backend_type_ == net::CACHE_BACKEND_SIMPLE ||
95 (backend_type_ == net::CACHE_BACKEND_DEFAULT &&
96 kSimpleBackendIsDefault)) {
97 disk_cache::SimpleBackendImpl* simple_cache =
98 new disk_cache::SimpleBackendImpl(
99 path_, max_bytes_, type_, thread_, net_log_);
100 created_cache_.reset(simple_cache);
101 return simple_cache->Init(
102 base::Bind(&CacheCreator::OnIOComplete, base::Unretained(this)));
105 // Avoid references to blockfile functions on Android to reduce binary size.
106 #if defined(OS_ANDROID)
107 return net::ERR_FAILED;
108 #else
109 disk_cache::BackendImpl* new_cache =
110 new disk_cache::BackendImpl(path_, thread_, net_log_);
111 created_cache_.reset(new_cache);
112 new_cache->SetMaxSize(max_bytes_);
113 new_cache->SetType(type_);
114 new_cache->SetFlags(flags_);
115 int rv = new_cache->Init(
116 base::Bind(&CacheCreator::OnIOComplete, base::Unretained(this)));
117 DCHECK_EQ(net::ERR_IO_PENDING, rv);
118 return rv;
119 #endif
122 void CacheCreator::DoCallback(int result) {
123 DCHECK_NE(net::ERR_IO_PENDING, result);
124 if (result == net::OK) {
125 #ifndef USE_TRACING_CACHE_BACKEND
126 *backend_ = created_cache_.Pass();
127 #else
128 *backend_.reset(
129 new disk_cache::TracingCacheBackend(created_cache_.Pass()));
130 #endif
131 } else {
132 LOG(ERROR) << "Unable to create cache";
133 created_cache_.reset();
135 callback_.Run(result);
136 delete this;
139 // If the initialization of the cache fails, and |force| is true, we will
140 // discard the whole cache and create a new one.
141 void CacheCreator::OnIOComplete(int result) {
142 if (result == net::OK || !force_ || retry_)
143 return DoCallback(result);
145 // This is a failure and we are supposed to try again, so delete the object,
146 // delete all the files, and try again.
147 retry_ = true;
148 created_cache_.reset();
149 if (!disk_cache::DelayedCacheCleanup(path_))
150 return DoCallback(result);
152 // The worker thread will start deleting files soon, but the original folder
153 // is not there anymore... let's create a new set of files.
154 int rv = Run();
155 DCHECK_EQ(net::ERR_IO_PENDING, rv);
158 } // namespace
160 namespace disk_cache {
162 int CreateCacheBackend(
163 net::CacheType type,
164 net::BackendType backend_type,
165 const base::FilePath& path,
166 int max_bytes,
167 bool force,
168 const scoped_refptr<base::SingleThreadTaskRunner>& thread,
169 net::NetLog* net_log,
170 scoped_ptr<Backend>* backend,
171 const net::CompletionCallback& callback) {
172 DCHECK(!callback.is_null());
173 if (type == net::MEMORY_CACHE) {
174 *backend = disk_cache::MemBackendImpl::CreateBackend(max_bytes, net_log);
175 return *backend ? net::OK : net::ERR_FAILED;
177 DCHECK(thread.get());
178 CacheCreator* creator = new CacheCreator(path,
179 force,
180 max_bytes,
181 type,
182 backend_type,
183 kNone,
184 thread,
185 net_log,
186 backend,
187 callback);
188 return creator->Run();
191 } // namespace disk_cache