Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: base/path_service.cc

Issue 10909228: Add PathService::RemoveOverride to clear path overrides. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Made the tests even more OS independent. Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/path_service.h ('k') | base/path_service_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/path_service.h" 5 #include "base/path_service.h"
6 6
7 #ifdef OS_WIN 7 #ifdef OS_WIN
8 #include <windows.h> 8 #include <windows.h>
9 #include <shellapi.h> 9 #include <shellapi.h>
10 #include <shlobj.h> 10 #include <shlobj.h>
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
133 } 133 }
134 } 134 }
135 }; 135 };
136 136
137 static base::LazyInstance<PathData> g_path_data = LAZY_INSTANCE_INITIALIZER; 137 static base::LazyInstance<PathData> g_path_data = LAZY_INSTANCE_INITIALIZER;
138 138
139 static PathData* GetPathData() { 139 static PathData* GetPathData() {
140 return g_path_data.Pointer(); 140 return g_path_data.Pointer();
141 } 141 }
142 142
143 } // namespace 143 // Tries to find |key| in the cache. |path_data| should be locked by the caller!
144 144 bool LockedGetFromCache(int key, const PathData* path_data, FilePath* result) {
145
146 // static
147 bool PathService::GetFromCache(int key, FilePath* result) {
148 PathData* path_data = GetPathData();
149 base::AutoLock scoped_lock(path_data->lock);
150
151 // check for a cached version 145 // check for a cached version
152 PathMap::const_iterator it = path_data->cache.find(key); 146 PathMap::const_iterator it = path_data->cache.find(key);
153 if (it != path_data->cache.end()) { 147 if (it != path_data->cache.end()) {
154 *result = it->second; 148 *result = it->second;
155 return true; 149 return true;
156 } 150 }
157 return false; 151 return false;
158 } 152 }
159 153
160 // static 154 // Tries to find |key| in the overrides map. |path_data| should be locked by the
161 bool PathService::GetFromOverrides(int key, FilePath* result) { 155 // caller!
162 PathData* path_data = GetPathData(); 156 bool LockedGetFromOverrides(int key, PathData* path_data, FilePath* result) {
163 base::AutoLock scoped_lock(path_data->lock);
164
165 // check for an overridden version. 157 // check for an overridden version.
166 PathMap::const_iterator it = path_data->overrides.find(key); 158 PathMap::const_iterator it = path_data->overrides.find(key);
167 if (it != path_data->overrides.end()) { 159 if (it != path_data->overrides.end()) {
160 path_data->cache[key] = it->second;
168 *result = it->second; 161 *result = it->second;
169 return true; 162 return true;
170 } 163 }
171 return false; 164 return false;
172 } 165 }
173 166
174 // static 167 } // namespace
175 void PathService::AddToCache(int key, const FilePath& path) {
176 PathData* path_data = GetPathData();
177 base::AutoLock scoped_lock(path_data->lock);
178 // Save the computed path in our cache.
179 path_data->cache[key] = path;
180 }
181 168
182 // TODO(brettw): this function does not handle long paths (filename > MAX_PATH) 169 // TODO(brettw): this function does not handle long paths (filename > MAX_PATH)
183 // characters). This isn't supported very well by Windows right now, so it is 170 // characters). This isn't supported very well by Windows right now, so it is
184 // moot, but we should keep this in mind for the future. 171 // moot, but we should keep this in mind for the future.
185 // static 172 // static
186 bool PathService::Get(int key, FilePath* result) { 173 bool PathService::Get(int key, FilePath* result) {
187 PathData* path_data = GetPathData(); 174 PathData* path_data = GetPathData();
188 DCHECK(path_data); 175 DCHECK(path_data);
189 DCHECK(result); 176 DCHECK(result);
190 DCHECK_GE(key, base::DIR_CURRENT); 177 DCHECK_GE(key, base::DIR_CURRENT);
191 178
179 Provider* provider = NULL;
jar (doing other things) 2012/09/20 01:51:19 nit: move to in front of line 184, closest to firs
pastarmovj 2012/09/20 09:32:19 Done.
192 // special case the current directory because it can never be cached 180 // special case the current directory because it can never be cached
193 if (key == base::DIR_CURRENT) 181 if (key == base::DIR_CURRENT)
194 return file_util::GetCurrentDirectory(result); 182 return file_util::GetCurrentDirectory(result);
195 183
196 if (GetFromCache(key, result)) 184 {
197 return true; 185 base::AutoLock scoped_lock(path_data->lock);
186 if (LockedGetFromCache(key, path_data, result))
187 return true;
198 188
199 if (GetFromOverrides(key, result)) 189 if (LockedGetFromOverrides(key, path_data, result))
200 return true; 190 return true;
191
192 // Get the beginning of the list while it is still locked.
193 provider = path_data->providers;
194 }
201 195
202 FilePath path; 196 FilePath path;
203 197
204 // search providers for the requested path 198 // search providers for the requested path
jar (doing other things) 2012/09/20 01:51:19 nit: Probably delete this, but you could put it ne
pastarmovj 2012/09/20 09:32:19 Done.
205 // NOTE: it should be safe to iterate here without the lock 199 // NOTE: it should be safe to iterate here without the lock
jar (doing other things) 2012/09/20 01:51:19 Delete the outdated comments on line 199 and 200.
pastarmovj 2012/09/20 09:32:19 I think it is good to have a comment why this is n
jar (doing other things) 2012/09/20 16:30:32 Good point. I'm fine with that.
206 // since RegisterProvider always prepends. 200 // since RegisterProvider always prepends.
207 Provider* provider = path_data->providers;
208 while (provider) { 201 while (provider) {
209 if (provider->func(key, &path)) 202 if (provider->func(key, &path))
210 break; 203 break;
211 DCHECK(path.empty()) << "provider should not have modified path"; 204 DCHECK(path.empty()) << "provider should not have modified path";
212 provider = provider->next; 205 provider = provider->next;
213 } 206 }
214 207
215 if (path.empty()) 208 if (path.empty())
216 return false; 209 return false;
217 210
218 AddToCache(key, path); 211 *result = path;
219 212
220 *result = path; 213 base::AutoLock scoped_lock(path_data->lock);
214 path_data->cache[key] = path;
215
221 return true; 216 return true;
222 } 217 }
223 218
219 // static
224 bool PathService::Override(int key, const FilePath& path) { 220 bool PathService::Override(int key, const FilePath& path) {
225 // Just call the full function with true for the value of |create|. 221 // Just call the full function with true for the value of |create|.
226 return OverrideAndCreateIfNeeded(key, path, true); 222 return OverrideAndCreateIfNeeded(key, path, true);
227 } 223 }
228 224
225 // static
229 bool PathService::OverrideAndCreateIfNeeded(int key, 226 bool PathService::OverrideAndCreateIfNeeded(int key,
230 const FilePath& path, 227 const FilePath& path,
231 bool create) { 228 bool create) {
232 PathData* path_data = GetPathData(); 229 PathData* path_data = GetPathData();
233 DCHECK(path_data); 230 DCHECK(path_data);
234 DCHECK_GT(key, base::DIR_CURRENT) << "invalid path key"; 231 DCHECK_GT(key, base::DIR_CURRENT) << "invalid path key";
235 232
236 FilePath file_path = path; 233 FilePath file_path = path;
237 234
238 // For some locations this will fail if called from inside the sandbox there- 235 // For some locations this will fail if called from inside the sandbox there-
(...skipping 12 matching lines...) Expand all
251 // relative path. 248 // relative path.
252 if (!file_util::AbsolutePath(&file_path)) 249 if (!file_util::AbsolutePath(&file_path))
253 return false; 250 return false;
254 251
255 base::AutoLock scoped_lock(path_data->lock); 252 base::AutoLock scoped_lock(path_data->lock);
256 253
257 // Clear the cache now. Some of its entries could have depended 254 // Clear the cache now. Some of its entries could have depended
258 // on the value we are overriding, and are now out of sync with reality. 255 // on the value we are overriding, and are now out of sync with reality.
259 path_data->cache.clear(); 256 path_data->cache.clear();
260 257
261 path_data->cache[key] = file_path;
262 path_data->overrides[key] = file_path; 258 path_data->overrides[key] = file_path;
263 259
264 return true; 260 return true;
265 } 261 }
266 262
263 // static
264 bool PathService::RemoveOverride(int key) {
265 PathData* path_data = GetPathData();
266 DCHECK(path_data);
267
268 base::AutoLock scoped_lock(path_data->lock);
269
270 if (path_data->overrides.find(key) == path_data->overrides.end())
271 return false;
272
273 // Clear the cache now. Some of its entries could have depended on the value
274 // we are going to remove, and are now out of sync.
275 path_data->cache.clear();
276
277 path_data->overrides.erase(key);
278
279 return true;
280 }
281
282 // static
267 void PathService::RegisterProvider(ProviderFunc func, int key_start, 283 void PathService::RegisterProvider(ProviderFunc func, int key_start,
268 int key_end) { 284 int key_end) {
269 PathData* path_data = GetPathData(); 285 PathData* path_data = GetPathData();
270 DCHECK(path_data); 286 DCHECK(path_data);
271 DCHECK_GT(key_end, key_start); 287 DCHECK_GT(key_end, key_start);
272 288
273 base::AutoLock scoped_lock(path_data->lock);
274
275 Provider* p; 289 Provider* p;
276 290
277 #ifndef NDEBUG
278 p = path_data->providers;
279 while (p) {
280 DCHECK(key_start >= p->key_end || key_end <= p->key_start) <<
281 "path provider collision";
282 p = p->next;
283 }
284 #endif
285
286 p = new Provider; 291 p = new Provider;
287 p->is_static = false; 292 p->is_static = false;
288 p->func = func; 293 p->func = func;
289 p->next = path_data->providers;
290 #ifndef NDEBUG 294 #ifndef NDEBUG
291 p->key_start = key_start; 295 p->key_start = key_start;
292 p->key_end = key_end; 296 p->key_end = key_end;
293 #endif 297 #endif
298
299 base::AutoLock scoped_lock(path_data->lock);
300
301 #ifndef NDEBUG
302 Provider *iter = path_data->providers;
303 while (iter) {
304 DCHECK(key_start >= iter->key_end || key_end <= iter->key_start) <<
305 "path provider collision";
306 iter = iter->next;
307 }
308 #endif
309
310 p->next = path_data->providers;
294 path_data->providers = p; 311 path_data->providers = p;
295 } 312 }
OLDNEW
« no previous file with comments | « base/path_service.h ('k') | base/path_service_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698