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"
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
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.
33 void DoCallback(int result
);
35 void OnIOComplete(int result
);
37 const base::FilePath
& path_
;
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
)
61 max_bytes_(max_bytes
),
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
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
82 if (type_
== net::DISK_CACHE
) {
83 disk_cache::SimpleBackendImpl
* simple_cache
=
84 new disk_cache::SimpleBackendImpl(path_
, max_bytes_
, type_
, thread_
,
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
);
103 void CacheCreator::DoCallback(int result
) {
104 DCHECK_NE(net::ERR_IO_PENDING
, result
);
105 if (result
== net::OK
)
106 *backend_
= created_cache_
;
108 LOG(ERROR
) << "Unable to create cache";
110 delete created_cache_
;
112 callback_
.Run(result
);
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.
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.
133 DCHECK_EQ(net::ERR_IO_PENDING
, rv
);
138 namespace disk_cache
{
140 int CreateCacheBackend(net::CacheType type
, const base::FilePath
& path
,
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
;
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