Cache Backend Proxy to intercept all cache events from the IO thread.
[chromium-blink-merge.git] / net / disk_cache / cache_creator.cc
blobc2c901f5f61e76507dcd97b8953c0c475e83b666
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"
14 #ifdef USE_TRACING_CACHE_BACKEND
15 #include "net/disk_cache/tracing_cache_backend.h"
16 #endif
18 namespace {
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, bool force, int max_bytes,
26 net::CacheType type, uint32 flags,
27 base::MessageLoopProxy* thread, net::NetLog* net_log,
28 disk_cache::Backend** backend,
29 const net::CompletionCallback& callback);
31 // Creates the backend.
32 int Run();
34 private:
35 ~CacheCreator();
37 void DoCallback(int result);
39 void OnIOComplete(int result);
41 const base::FilePath& path_;
42 bool force_;
43 bool retry_;
44 int max_bytes_;
45 net::CacheType type_;
46 uint32 flags_;
47 scoped_refptr<base::MessageLoopProxy> thread_;
48 disk_cache::Backend** backend_;
49 net::CompletionCallback callback_;
50 disk_cache::Backend* created_cache_;
51 net::NetLog* net_log_;
53 DISALLOW_COPY_AND_ASSIGN(CacheCreator);
56 CacheCreator::CacheCreator(
57 const base::FilePath& path, bool force, int max_bytes,
58 net::CacheType type, uint32 flags,
59 base::MessageLoopProxy* thread, net::NetLog* net_log,
60 disk_cache::Backend** backend,
61 const net::CompletionCallback& callback)
62 : path_(path),
63 force_(force),
64 retry_(false),
65 max_bytes_(max_bytes),
66 type_(type),
67 flags_(flags),
68 thread_(thread),
69 backend_(backend),
70 callback_(callback),
71 created_cache_(NULL),
72 net_log_(net_log) {
75 CacheCreator::~CacheCreator() {
78 int CacheCreator::Run() {
79 // TODO(pasko): The two caches should never coexist on disk. Each individual
80 // cache backend should fail to initialize if it observes the index that does
81 // not belong to it.
82 if (base::FieldTrialList::FindFullName("SimpleCacheTrial") == "Yes") {
83 // TODO(gavinp,pasko): While simple backend development proceeds, we're only
84 // testing it against net::DISK_CACHE. Turn it on for more cache types as
85 // appropriate.
86 if (type_ == net::DISK_CACHE) {
87 disk_cache::SimpleBackendImpl* simple_cache =
88 new disk_cache::SimpleBackendImpl(path_, max_bytes_, type_, thread_,
89 net_log_);
90 created_cache_ = simple_cache;
91 return simple_cache->Init(
92 base::Bind(&CacheCreator::OnIOComplete, base::Unretained(this)));
95 disk_cache::BackendImpl* new_cache =
96 new disk_cache::BackendImpl(path_, thread_, net_log_);
97 created_cache_ = new_cache;
98 new_cache->SetMaxSize(max_bytes_);
99 new_cache->SetType(type_);
100 new_cache->SetFlags(flags_);
101 int rv = new_cache->Init(
102 base::Bind(&CacheCreator::OnIOComplete, base::Unretained(this)));
103 DCHECK_EQ(net::ERR_IO_PENDING, rv);
104 return rv;
107 void CacheCreator::DoCallback(int result) {
108 DCHECK_NE(net::ERR_IO_PENDING, result);
109 if (result == net::OK) {
110 #ifndef USE_TRACING_CACHE_BACKEND
111 *backend_ = created_cache_;
112 #else
113 *backend_ = new disk_cache::TracingCacheBackend(created_cache_);
114 #endif
115 } else {
116 LOG(ERROR) << "Unable to create cache";
117 *backend_ = NULL;
118 delete created_cache_;
120 callback_.Run(result);
121 delete this;
124 // If the initialization of the cache fails, and |force| is true, we will
125 // discard the whole cache and create a new one.
126 void CacheCreator::OnIOComplete(int result) {
127 if (result == net::OK || !force_ || retry_)
128 return DoCallback(result);
130 // This is a failure and we are supposed to try again, so delete the object,
131 // delete all the files, and try again.
132 retry_ = true;
133 delete created_cache_;
134 created_cache_ = NULL;
135 if (!disk_cache::DelayedCacheCleanup(path_))
136 return DoCallback(result);
138 // The worker thread will start deleting files soon, but the original folder
139 // is not there anymore... let's create a new set of files.
140 int rv = Run();
141 DCHECK_EQ(net::ERR_IO_PENDING, rv);
144 } // namespace
146 namespace disk_cache {
148 int CreateCacheBackend(net::CacheType type, const base::FilePath& path,
149 int max_bytes,
150 bool force, base::MessageLoopProxy* thread,
151 net::NetLog* net_log, 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;
158 DCHECK(thread);
159 CacheCreator* creator = new CacheCreator(path, force, max_bytes, type, kNone,
160 thread, net_log, backend, callback);
161 return creator->Run();
164 } // namespace disk_cache