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/profiler/scoped_profile.h"
8 #include "base/single_thread_task_runner.h"
9 #include "base/strings/stringprintf.h"
10 #include "net/base/cache_type.h"
11 #include "net/base/net_errors.h"
12 #include "net/disk_cache/blockfile/backend_impl.h"
13 #include "net/disk_cache/cache_util.h"
14 #include "net/disk_cache/disk_cache.h"
15 #include "net/disk_cache/memory/mem_backend_impl.h"
16 #include "net/disk_cache/simple/simple_backend_impl.h"
20 // Builds an instance of the backend depending on platform, type, experiments
21 // etc. Takes care of the retry state. This object will self-destroy when
25 CacheCreator(const base::FilePath
& path
,
29 net::BackendType backend_type
,
31 const scoped_refptr
<base::SingleThreadTaskRunner
>& thread
,
33 scoped_ptr
<disk_cache::Backend
>* backend
,
34 const net::CompletionCallback
& callback
);
36 // Creates the backend.
42 void DoCallback(int result
);
44 void OnIOComplete(int result
);
46 const base::FilePath path_
;
51 net::BackendType backend_type_
;
53 scoped_refptr
<base::SingleThreadTaskRunner
> thread_
;
54 scoped_ptr
<disk_cache::Backend
>* backend_
;
55 net::CompletionCallback callback_
;
56 scoped_ptr
<disk_cache::Backend
> created_cache_
;
57 net::NetLog
* net_log_
;
59 DISALLOW_COPY_AND_ASSIGN(CacheCreator
);
62 CacheCreator::CacheCreator(
63 const base::FilePath
& path
,
67 net::BackendType backend_type
,
69 const scoped_refptr
<base::SingleThreadTaskRunner
>& thread
,
71 scoped_ptr
<disk_cache::Backend
>* backend
,
72 const net::CompletionCallback
& callback
)
76 max_bytes_(max_bytes
),
78 backend_type_(backend_type
),
86 CacheCreator::~CacheCreator() {
89 int CacheCreator::Run() {
90 #if defined(OS_ANDROID)
91 static const bool kSimpleBackendIsDefault
= true;
93 static const bool kSimpleBackendIsDefault
= false;
95 if (backend_type_
== net::CACHE_BACKEND_SIMPLE
||
96 (backend_type_
== net::CACHE_BACKEND_DEFAULT
&&
97 kSimpleBackendIsDefault
)) {
98 disk_cache::SimpleBackendImpl
* simple_cache
=
99 new disk_cache::SimpleBackendImpl(
100 path_
, max_bytes_
, type_
, thread_
, net_log_
);
101 created_cache_
.reset(simple_cache
);
102 return simple_cache
->Init(
103 base::Bind(&CacheCreator::OnIOComplete
, base::Unretained(this)));
106 // Avoid references to blockfile functions on Android to reduce binary size.
107 #if defined(OS_ANDROID)
108 return net::ERR_FAILED
;
110 disk_cache::BackendImpl
* new_cache
=
111 new disk_cache::BackendImpl(path_
, thread_
, net_log_
);
112 created_cache_
.reset(new_cache
);
113 new_cache
->SetMaxSize(max_bytes_
);
114 new_cache
->SetType(type_
);
115 new_cache
->SetFlags(flags_
);
116 int rv
= new_cache
->Init(
117 base::Bind(&CacheCreator::OnIOComplete
, base::Unretained(this)));
118 DCHECK_EQ(net::ERR_IO_PENDING
, rv
);
123 void CacheCreator::DoCallback(int result
) {
124 DCHECK_NE(net::ERR_IO_PENDING
, result
);
125 if (result
== net::OK
) {
126 #ifndef USE_TRACING_CACHE_BACKEND
127 *backend_
= created_cache_
.Pass();
130 new disk_cache::TracingCacheBackend(created_cache_
.Pass()));
133 LOG(ERROR
) << "Unable to create cache";
134 created_cache_
.reset();
136 callback_
.Run(result
);
140 // If the initialization of the cache fails, and |force| is true, we will
141 // discard the whole cache and create a new one.
142 void CacheCreator::OnIOComplete(int result
) {
143 // TODO(vadimt): Remove ScopedProfile below once crbug.com/422516 is fixed.
144 tracked_objects::ScopedProfile
tracking_profile(
145 FROM_HERE_WITH_EXPLICIT_FUNCTION("422516 CacheCreator::OnIOComplete"));
147 if (result
== net::OK
|| !force_
|| retry_
)
148 return DoCallback(result
);
150 // This is a failure and we are supposed to try again, so delete the object,
151 // delete all the files, and try again.
153 created_cache_
.reset();
154 if (!disk_cache::DelayedCacheCleanup(path_
))
155 return DoCallback(result
);
157 // The worker thread will start deleting files soon, but the original folder
158 // is not there anymore... let's create a new set of files.
160 DCHECK_EQ(net::ERR_IO_PENDING
, rv
);
165 namespace disk_cache
{
167 int CreateCacheBackend(
169 net::BackendType backend_type
,
170 const base::FilePath
& path
,
173 const scoped_refptr
<base::SingleThreadTaskRunner
>& thread
,
174 net::NetLog
* net_log
,
175 scoped_ptr
<Backend
>* backend
,
176 const net::CompletionCallback
& callback
) {
177 DCHECK(!callback
.is_null());
178 if (type
== net::MEMORY_CACHE
) {
179 *backend
= disk_cache::MemBackendImpl::CreateBackend(max_bytes
, net_log
);
180 return *backend
? net::OK
: net::ERR_FAILED
;
182 DCHECK(thread
.get());
183 CacheCreator
* creator
= new CacheCreator(path
,
193 return creator
->Run();
196 } // namespace disk_cache