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/strings/stringprintf.h"
8 #include "net/base/cache_type.h"
9 #include "net/base/net_errors.h"
10 #include "net/disk_cache/backend_impl.h"
11 #include "net/disk_cache/cache_util.h"
12 #include "net/disk_cache/disk_cache.h"
13 #include "net/disk_cache/mem_backend_impl.h"
14 #include "net/disk_cache/simple/simple_backend_impl.h"
16 #ifdef USE_TRACING_CACHE_BACKEND
17 #include "net/disk_cache/tracing_cache_backend.h"
22 // Builds an instance of the backend depending on platform, type, experiments
23 // etc. Takes care of the retry state. This object will self-destroy when
27 CacheCreator(const base::FilePath
& path
, bool force
, int max_bytes
,
28 net::CacheType type
, net::BackendType backend_type
, uint32 flags
,
29 base::MessageLoopProxy
* thread
, net::NetLog
* net_log
,
30 scoped_ptr
<disk_cache::Backend
>* backend
,
31 const net::CompletionCallback
& callback
);
33 // Creates the backend.
39 void DoCallback(int result
);
41 void OnIOComplete(int result
);
43 const base::FilePath path_
;
48 net::BackendType backend_type_
;
50 scoped_refptr
<base::MessageLoopProxy
> thread_
;
51 scoped_ptr
<disk_cache::Backend
>* backend_
;
52 net::CompletionCallback callback_
;
53 scoped_ptr
<disk_cache::Backend
> created_cache_
;
54 net::NetLog
* net_log_
;
56 DISALLOW_COPY_AND_ASSIGN(CacheCreator
);
59 CacheCreator::CacheCreator(
60 const base::FilePath
& path
, bool force
, int max_bytes
,
61 net::CacheType type
, net::BackendType backend_type
, uint32 flags
,
62 base::MessageLoopProxy
* thread
, net::NetLog
* net_log
,
63 scoped_ptr
<disk_cache::Backend
>* backend
,
64 const net::CompletionCallback
& callback
)
68 max_bytes_(max_bytes
),
70 backend_type_(backend_type
),
78 CacheCreator::~CacheCreator() {
81 int CacheCreator::Run() {
82 // TODO(gavinp,pasko): Turn Simple Cache on for more cache types as
84 if (backend_type_
== net::CACHE_BACKEND_SIMPLE
&&
85 (type_
== net::DISK_CACHE
|| type_
== net::APP_CACHE
||
86 type_
== net::MEDIA_CACHE
)) {
87 disk_cache::SimpleBackendImpl
* simple_cache
=
88 new disk_cache::SimpleBackendImpl(path_
, max_bytes_
, type_
,
89 thread_
.get(), net_log_
);
90 created_cache_
.reset(simple_cache
);
91 return simple_cache
->Init(
92 base::Bind(&CacheCreator::OnIOComplete
, base::Unretained(this)));
94 disk_cache::BackendImpl
* new_cache
=
95 new disk_cache::BackendImpl(path_
, thread_
.get(), net_log_
);
96 created_cache_
.reset(new_cache
);
97 new_cache
->SetMaxSize(max_bytes_
);
98 new_cache
->SetType(type_
);
99 new_cache
->SetFlags(flags_
);
100 int rv
= new_cache
->Init(
101 base::Bind(&CacheCreator::OnIOComplete
, base::Unretained(this)));
102 DCHECK_EQ(net::ERR_IO_PENDING
, rv
);
106 void CacheCreator::DoCallback(int result
) {
107 DCHECK_NE(net::ERR_IO_PENDING
, result
);
108 if (result
== net::OK
) {
109 #ifndef USE_TRACING_CACHE_BACKEND
110 *backend_
= created_cache_
.Pass();
113 new disk_cache::TracingCacheBackend(created_cache_
.Pass()));
116 LOG(ERROR
) << "Unable to create cache";
117 created_cache_
.reset();
119 callback_
.Run(result
);
123 // If the initialization of the cache fails, and |force| is true, we will
124 // discard the whole cache and create a new one.
125 void CacheCreator::OnIOComplete(int result
) {
126 if (result
== net::OK
|| !force_
|| retry_
)
127 return DoCallback(result
);
129 // This is a failure and we are supposed to try again, so delete the object,
130 // delete all the files, and try again.
132 created_cache_
.reset();
133 if (!disk_cache::DelayedCacheCleanup(path_
))
134 return DoCallback(result
);
136 // The worker thread will start deleting files soon, but the original folder
137 // is not there anymore... let's create a new set of files.
139 DCHECK_EQ(net::ERR_IO_PENDING
, rv
);
144 namespace disk_cache
{
146 int CreateCacheBackend(net::CacheType type
,
147 net::BackendType backend_type
,
148 const base::FilePath
& path
,
150 bool force
, base::MessageLoopProxy
* thread
,
151 net::NetLog
* net_log
, scoped_ptr
<Backend
>* backend
,
152 const net::CompletionCallback
& callback
) {
153 DCHECK(!callback
.is_null());
154 if (type
== net::MEMORY_CACHE
) {
155 *backend
= disk_cache::MemBackendImpl::CreateBackend(max_bytes
, net_log
);
156 return *backend
? net::OK
: net::ERR_FAILED
;
159 CacheCreator
* creator
= new CacheCreator(path
, force
, max_bytes
, type
,
161 thread
, net_log
, backend
, callback
);
162 return creator
->Run();
165 } // namespace disk_cache