Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / net / disk_cache / cache_creator.cc
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.
4
5 #include "base/files/file_path.h"
6 #include "base/metrics/field_trial.h"
7 #include "base/profiler/scoped_tracker.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"
17
18 namespace {
19
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
22 // finished.
23 class CacheCreator {
24  public:
25   CacheCreator(const base::FilePath& path,
26                bool force,
27                int max_bytes,
28                net::CacheType type,
29                net::BackendType backend_type,
30                uint32 flags,
31                const scoped_refptr<base::SingleThreadTaskRunner>& thread,
32                net::NetLog* net_log,
33                scoped_ptr<disk_cache::Backend>* backend,
34                const net::CompletionCallback& callback);
35
36   // Creates the backend.
37   int Run();
38
39  private:
40   ~CacheCreator();
41
42   void DoCallback(int result);
43
44   void OnIOComplete(int result);
45
46   const base::FilePath path_;
47   bool force_;
48   bool retry_;
49   int max_bytes_;
50   net::CacheType type_;
51   net::BackendType backend_type_;
52   uint32 flags_;
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_;
58
59   DISALLOW_COPY_AND_ASSIGN(CacheCreator);
60 };
61
62 CacheCreator::CacheCreator(
63     const base::FilePath& path,
64     bool force,
65     int max_bytes,
66     net::CacheType type,
67     net::BackendType backend_type,
68     uint32 flags,
69     const scoped_refptr<base::SingleThreadTaskRunner>& thread,
70     net::NetLog* net_log,
71     scoped_ptr<disk_cache::Backend>* backend,
72     const net::CompletionCallback& callback)
73     : path_(path),
74       force_(force),
75       retry_(false),
76       max_bytes_(max_bytes),
77       type_(type),
78       backend_type_(backend_type),
79       flags_(flags),
80       thread_(thread),
81       backend_(backend),
82       callback_(callback),
83       net_log_(net_log) {
84 }
85
86 CacheCreator::~CacheCreator() {
87 }
88
89 int CacheCreator::Run() {
90 #if defined(OS_ANDROID)
91   static const bool kSimpleBackendIsDefault = true;
92 #else
93   static const bool kSimpleBackendIsDefault = false;
94 #endif
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)));
104   }
105
106   // Avoid references to blockfile functions on Android to reduce binary size.
107 #if defined(OS_ANDROID)
108   return net::ERR_FAILED;
109 #else
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);
119   return rv;
120 #endif
121 }
122
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();
128 #else
129     *backend_.reset(
130         new disk_cache::TracingCacheBackend(created_cache_.Pass()));
131 #endif
132   } else {
133     LOG(ERROR) << "Unable to create cache";
134     created_cache_.reset();
135   }
136   callback_.Run(result);
137   delete this;
138 }
139
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 ScopedTracker below once crbug.com/422516 is fixed.
144   tracked_objects::ScopedTracker tracking_profile(
145       FROM_HERE_WITH_EXPLICIT_FUNCTION("422516 CacheCreator::OnIOComplete"));
146
147   if (result == net::OK || !force_ || retry_)
148     return DoCallback(result);
149
150   // This is a failure and we are supposed to try again, so delete the object,
151   // delete all the files, and try again.
152   retry_ = true;
153   created_cache_.reset();
154   if (!disk_cache::DelayedCacheCleanup(path_))
155     return DoCallback(result);
156
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.
159   int rv = Run();
160   DCHECK_EQ(net::ERR_IO_PENDING, rv);
161 }
162
163 }  // namespace
164
165 namespace disk_cache {
166
167 int CreateCacheBackend(
168     net::CacheType type,
169     net::BackendType backend_type,
170     const base::FilePath& path,
171     int max_bytes,
172     bool force,
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;
181   }
182   DCHECK(thread.get());
183   CacheCreator* creator = new CacheCreator(path,
184                                            force,
185                                            max_bytes,
186                                            type,
187                                            backend_type,
188                                            kNone,
189                                            thread,
190                                            net_log,
191                                            backend,
192                                            callback);
193   return creator->Run();
194 }
195
196 }  // namespace disk_cache