OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2013 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 | |
rvargas (doing something else)
2013/03/13 19:36:01
Could you copy this file from backend_impl.cc? (sv
pasko-google - do not use
2013/03/18 15:47:07
Done.
| |
5 #include "base/command_line.h" | |
6 #include "base/file_util.h" | |
7 #include "base/stringprintf.h" | |
8 #include "base/string_util.h" | |
9 #include "base/threading/thread_restrictions.h" | |
10 #include "base/threading/worker_pool.h" | |
11 #include "net/base/net_errors.h" | |
12 #include "net/disk_cache/backend_impl.h" | |
13 #include "net/disk_cache/cache_util.h" | |
14 #include "net/disk_cache/disk_cache.h" | |
15 #include "net/disk_cache/mem_backend_impl.h" | |
16 #include "net/disk_cache/simple/simple_backend_impl.h" | |
17 | |
18 namespace { | |
19 | |
20 const int kMaxOldFolders = 100; | |
21 const char kUseSimpleCacheBackend[] = "use-simple-cache-backend"; | |
gavinp
2013/03/13 18:36:12
I'm a bit uncomfortable with the command line opti
pasko-google - do not use
2013/03/18 15:47:07
Switches are committed in the previous CL, about:f
| |
22 | |
23 // Returns a fully qualified name from path and name, using a given name prefix | |
24 // and index number. For instance, if the arguments are "/foo", "bar" and 5, it | |
25 // will return "/foo/old_bar_005". | |
26 base::FilePath GetPrefixedName(const base::FilePath& path, | |
27 const std::string& name, | |
28 int index) { | |
29 std::string tmp = base::StringPrintf("%s%s_%03d", "old_", | |
30 name.c_str(), index); | |
31 return path.AppendASCII(tmp); | |
32 } | |
33 | |
34 // This is a simple callback to cleanup old caches. | |
35 void CleanupCallback(const base::FilePath& path, const std::string& name) { | |
36 for (int i = 0; i < kMaxOldFolders; i++) { | |
37 base::FilePath to_delete = GetPrefixedName(path, name, i); | |
38 disk_cache::DeleteCache(to_delete, true); | |
39 } | |
40 } | |
41 | |
42 base::FilePath GetTempCacheName(const base::FilePath& path, | |
gavinp
2013/03/13 18:36:12
The comment for this function has been orphaned ov
pasko-google - do not use
2013/03/18 15:47:07
Oops. Done.
| |
43 const std::string& name) { | |
44 // We'll attempt to have up to kMaxOldFolders directories for deletion. | |
45 for (int i = 0; i < kMaxOldFolders; i++) { | |
46 base::FilePath to_delete = GetPrefixedName(path, name, i); | |
47 if (!file_util::PathExists(to_delete)) | |
48 return to_delete; | |
49 } | |
50 return base::FilePath(); | |
51 } | |
52 | |
53 // Builds the instance of the backend depending on command-line option. Takes | |
gavinp
2013/03/13 18:36:12
"Builds an instance of the backend depending on co
pasko-google - do not use
2013/03/18 15:47:07
Done.
| |
54 // care of the retry state. This object will self-destroy when finished. | |
55 class CacheCreator { | |
56 public: | |
57 CacheCreator(const base::FilePath& path, bool force, int max_bytes, | |
gavinp
2013/03/13 18:36:12
This declaration is formally a violation of our co
pasko-google - do not use
2013/03/18 15:47:07
Can you be more specific about the violation?
| |
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 | |
63 // Creates the backend. | |
64 int Run(); | |
65 | |
66 private: | |
67 ~CacheCreator(); | |
68 | |
69 void DoCallback(int result); | |
70 | |
71 // Callback implementation. | |
72 void OnIOComplete(int result); | |
73 | |
74 const base::FilePath& path_; | |
75 bool force_; | |
76 bool retry_; | |
77 int max_bytes_; | |
78 net::CacheType type_; | |
79 uint32 flags_; | |
80 scoped_refptr<base::MessageLoopProxy> thread_; | |
81 disk_cache::Backend** backend_; | |
82 net::CompletionCallback callback_; | |
83 disk_cache::Backend* created_cache_; | |
84 net::NetLog* net_log_; | |
85 | |
86 DISALLOW_COPY_AND_ASSIGN(CacheCreator); | |
87 }; | |
88 | |
89 CacheCreator::CacheCreator( | |
90 const base::FilePath& path, bool force, int max_bytes, | |
91 net::CacheType type, uint32 flags, | |
92 base::MessageLoopProxy* thread, net::NetLog* net_log, | |
93 disk_cache::Backend** backend, | |
94 const net::CompletionCallback& callback) | |
95 : path_(path), | |
96 force_(force), | |
97 retry_(false), | |
98 max_bytes_(max_bytes), | |
99 type_(type), | |
100 flags_(flags), | |
101 thread_(thread), | |
102 backend_(backend), | |
103 callback_(callback), | |
104 created_cache_(NULL), | |
105 net_log_(net_log) { | |
106 } | |
107 | |
108 CacheCreator::~CacheCreator() { | |
109 } | |
110 | |
111 int CacheCreator::Run() { | |
112 if (type_ == net::MEMORY_CACHE) { | |
113 *backend_ = disk_cache::MemBackendImpl::CreateBackend(max_bytes_, net_log_); | |
114 return *backend_ ? net::OK : net::ERR_FAILED; | |
115 } | |
116 #if defined(USE_SIMPLE_CACHE_BACKEND) | |
gavinp
2013/03/13 18:36:12
This #define probably needs to be renamed now to B
pasko-google - do not use
2013/03/18 15:47:07
Removed altogether as per other discussions.
| |
117 if (CommandLine::ForCurrentProcess()->HasSwitch(kUseSimpleCacheBackend)) { | |
118 // TODO(gavinp,pasko): While simple backend development proceeds, we're only | |
119 // testing it against net::DISK_CACHE. Turn it on for more cache types as | |
120 // appropriate. | |
121 if (type_ == net::DISK_CACHE) { | |
122 VLOG(1) << "Using the Simple Cache Backend."; | |
123 return disk_cache::SimpleBackendImpl::CreateBackend(path_, max_bytes_, | |
124 type_, disk_cache::kNone, thread_, net_log_, backend_, callback_); | |
125 } | |
126 } | |
127 #endif | |
128 disk_cache::BackendImpl* new_cache = new disk_cache::BackendImpl( | |
gavinp
2013/03/13 18:36:12
Why the automatic? Why not:
created_cache_ = new
pasko-google - do not use
2013/03/18 15:47:07
We use a few methods that are not present in Backe
| |
129 path_, thread_, net_log_); | |
130 created_cache_ = new_cache; | |
131 new_cache->SetMaxSize(max_bytes_); | |
132 new_cache->SetType(type_); | |
133 new_cache->SetFlags(flags_); | |
134 int rv = new_cache->Init( | |
135 base::Bind(&CacheCreator::OnIOComplete, base::Unretained(this))); | |
136 DCHECK_EQ(net::ERR_IO_PENDING, rv); | |
137 return rv; | |
138 } | |
139 | |
140 void CacheCreator::DoCallback(int result) { | |
141 DCHECK_NE(net::ERR_IO_PENDING, result); | |
142 if (result == net::OK) { | |
143 *backend_ = created_cache_; | |
144 } else { | |
145 LOG(ERROR) << "Unable to create cache"; | |
146 *backend_ = NULL; | |
147 delete created_cache_; | |
148 } | |
149 callback_.Run(result); | |
150 delete this; | |
151 } | |
152 | |
153 void CacheCreator::OnIOComplete(int result) { | |
154 if (result == net::OK || !force_ || retry_) | |
155 return DoCallback(result); | |
156 | |
157 // This is a failure and we are supposed to try again, so delete the object, | |
158 // delete all the files, and try again. | |
159 retry_ = true; | |
160 delete created_cache_; | |
161 created_cache_ = NULL; | |
162 if (!disk_cache::DelayedCacheCleanup(path_)) | |
163 return DoCallback(result); | |
164 | |
165 // The worker thread will start deleting files soon, but the original | |
166 // directory is not there anymore... let's create a new set of files. | |
167 int rv = Run(); | |
168 DCHECK_EQ(net::ERR_IO_PENDING, rv); | |
169 } | |
170 | |
171 } // namespace | |
172 | |
173 namespace disk_cache { | |
174 | |
175 // If the initialization of the cache fails, and |force| is true, we will | |
176 // discard the whole cache and create a new one. In order to process a | |
177 // potentially large number of files, we'll rename the cache directory to old_ + | |
178 // original_name + number, (located on the same parent directory), and spawn a | |
179 // worker thread to delete all the files on all the stale cache directories. The | |
180 // whole process can still fail if we are not able to rename the cache directory | |
181 // (for instance due to a sharing violation), and in that case a cache for this | |
182 // profile (on the desired path) cannot be created. | |
183 int CreateCacheBackendWithFlags(net::CacheType type, const base::FilePath& path, | |
184 int max_bytes, bool force, uint32 flags, base::MessageLoopProxy* thread, | |
185 net::NetLog* net_log, Backend** backend, | |
186 const net::CompletionCallback& callback) { | |
187 DCHECK(!callback.is_null()); | |
188 DCHECK(thread || type == net::MEMORY_CACHE); | |
189 CacheCreator* creator = new CacheCreator(path, force, max_bytes, type, flags, | |
190 thread, net_log, backend, callback); | |
191 return creator->Run(); | |
192 } | |
193 | |
194 int CreateCacheBackend(net::CacheType type, const base::FilePath& path, | |
195 int max_bytes, bool force, base::MessageLoopProxy* thread, | |
196 net::NetLog* net_log, Backend** backend, | |
197 const net::CompletionCallback& callback) { | |
198 return CreateCacheBackendWithFlags(type, path, max_bytes, force, kNone, | |
199 thread, net_log, backend, callback); | |
200 } | |
201 | |
202 // Moves the cache files to a new directory and creates a task to delete them. | |
203 bool DelayedCacheCleanup(const base::FilePath& full_path) { | |
204 // GetTempCacheName() and MoveCache() use synchronous file | |
205 // operations. | |
206 base::ThreadRestrictions::ScopedAllowIO allow_io; | |
207 | |
208 base::FilePath current_path = full_path.StripTrailingSeparators(); | |
209 | |
210 base::FilePath path = current_path.DirName(); | |
211 base::FilePath name = current_path.BaseName(); | |
212 #if defined(OS_POSIX) | |
213 std::string name_str = name.value(); | |
214 #elif defined(OS_WIN) | |
215 // We created this file so it should only contain ASCII. | |
216 std::string name_str = WideToASCII(name.value()); | |
217 #endif | |
218 | |
219 base::FilePath to_delete = GetTempCacheName(path, name_str); | |
220 if (to_delete.empty()) { | |
221 LOG(ERROR) << "Unable to get another cache folder"; | |
222 return false; | |
223 } | |
224 | |
225 if (!disk_cache::MoveCache(full_path, to_delete)) { | |
226 LOG(ERROR) << "Unable to move cache folder " << full_path.value() << " to " | |
227 << to_delete.value(); | |
228 return false; | |
229 } | |
230 | |
231 base::WorkerPool::PostTask( | |
232 FROM_HERE, base::Bind(&CleanupCallback, path, name_str), true); | |
233 return true; | |
234 } | |
235 | |
236 } // namespace disk_cache | |
OLD | NEW |