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

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: Cleaned up a typo in unit tests file. 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 // Adds a value to the cache map. |path_data| should be locked by the caller!
144 void LockedAddToCache(int key, const FilePath& path, PathData* path_data) {
145 // Save the computed path in our cache.
146 path_data->cache[key] = path;
jar (doing other things) 2012/09/18 16:47:17 This line of code (which is the whole function), s
pastarmovj 2012/09/19 11:24:28 Done.
147 }
144 148
145 149 // Tries to find |key| in the cache. |path_data| should be locked by the caller!
146 // static 150 bool LockedGetFromCache(int key, const PathData* path_data, FilePath* result) {
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 151 // check for a cached version
152 PathMap::const_iterator it = path_data->cache.find(key); 152 PathMap::const_iterator it = path_data->cache.find(key);
153 if (it != path_data->cache.end()) { 153 if (it != path_data->cache.end()) {
154 *result = it->second; 154 *result = it->second;
155 return true; 155 return true;
156 } 156 }
157 return false; 157 return false;
158 } 158 }
159 159
160 // static 160 // Tries to find |key| in the overrides map. |path_data| should be locked by the
161 bool PathService::GetFromOverrides(int key, FilePath* result) { 161 // caller!
162 PathData* path_data = GetPathData(); 162 bool LockedGetFromOverrides(int key, PathData* path_data, FilePath* result) {
163 base::AutoLock scoped_lock(path_data->lock);
164
165 // check for an overridden version. 163 // check for an overridden version.
166 PathMap::const_iterator it = path_data->overrides.find(key); 164 PathMap::const_iterator it = path_data->overrides.find(key);
167 if (it != path_data->overrides.end()) { 165 if (it != path_data->overrides.end()) {
166 LockedAddToCache(key, it->second, path_data);
168 *result = it->second; 167 *result = it->second;
169 return true; 168 return true;
170 } 169 }
171 return false; 170 return false;
172 } 171 }
173 172
174 // static 173 } // 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 174
182 // TODO(brettw): this function does not handle long paths (filename > MAX_PATH) 175 // 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 176 // 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. 177 // moot, but we should keep this in mind for the future.
185 // static 178 // static
186 bool PathService::Get(int key, FilePath* result) { 179 bool PathService::Get(int key, FilePath* result) {
187 PathData* path_data = GetPathData(); 180 PathData* path_data = GetPathData();
188 DCHECK(path_data); 181 DCHECK(path_data);
189 DCHECK(result); 182 DCHECK(result);
190 DCHECK_GE(key, base::DIR_CURRENT); 183 DCHECK_GE(key, base::DIR_CURRENT);
191 184
185 Provider* provider = NULL;
192 // special case the current directory because it can never be cached 186 // special case the current directory because it can never be cached
193 if (key == base::DIR_CURRENT) 187 if (key == base::DIR_CURRENT)
194 return file_util::GetCurrentDirectory(result); 188 return file_util::GetCurrentDirectory(result);
195 189
196 if (GetFromCache(key, result)) 190 {
197 return true; 191 base::AutoLock scoped_lock(path_data->lock);
192 if (LockedGetFromCache(key, path_data, result))
193 return true;
198 194
199 if (GetFromOverrides(key, result)) 195 if (LockedGetFromOverrides(key, path_data, result))
200 return true; 196 return true;
197
198 // Get the beginning of the list while it is still locked.
199 provider = path_data->providers;
200 }
201 201
202 FilePath path; 202 FilePath path;
203 203
204 // search providers for the requested path 204 // search providers for the requested path
205 // NOTE: it should be safe to iterate here without the lock 205 // NOTE: it should be safe to iterate here without the lock
206 // since RegisterProvider always prepends. 206 // since RegisterProvider always prepends.
207 Provider* provider = path_data->providers;
208 while (provider) { 207 while (provider) {
209 if (provider->func(key, &path)) 208 if (provider->func(key, &path))
210 break; 209 break;
211 DCHECK(path.empty()) << "provider should not have modified path"; 210 DCHECK(path.empty()) << "provider should not have modified path";
212 provider = provider->next; 211 provider = provider->next;
213 } 212 }
214 213
215 if (path.empty()) 214 if (path.empty())
216 return false; 215 return false;
217 216
218 AddToCache(key, path); 217 {
218 base::AutoLock scoped_lock(path_data->lock);
219 LockedAddToCache(key, path, path_data);
jar (doing other things) 2012/09/18 16:47:17 nit: Move these two line down to between lines 222
pastarmovj 2012/09/19 11:24:28 Done.
220 }
219 221
220 *result = path; 222 *result = path;
221 return true; 223 return true;
222 } 224 }
223 225
226 // static
224 bool PathService::Override(int key, const FilePath& path) { 227 bool PathService::Override(int key, const FilePath& path) {
225 // Just call the full function with true for the value of |create|. 228 // Just call the full function with true for the value of |create|.
226 return OverrideAndCreateIfNeeded(key, path, true); 229 return OverrideAndCreateIfNeeded(key, path, true);
227 } 230 }
228 231
232 // static
229 bool PathService::OverrideAndCreateIfNeeded(int key, 233 bool PathService::OverrideAndCreateIfNeeded(int key,
230 const FilePath& path, 234 const FilePath& path,
231 bool create) { 235 bool create) {
232 PathData* path_data = GetPathData(); 236 PathData* path_data = GetPathData();
233 DCHECK(path_data); 237 DCHECK(path_data);
234 DCHECK_GT(key, base::DIR_CURRENT) << "invalid path key"; 238 DCHECK_GT(key, base::DIR_CURRENT) << "invalid path key";
235 239
236 FilePath file_path = path; 240 FilePath file_path = path;
237 241
238 // For some locations this will fail if called from inside the sandbox there- 242 // For some locations this will fail if called from inside the sandbox there-
(...skipping 12 matching lines...) Expand all
251 // relative path. 255 // relative path.
252 if (!file_util::AbsolutePath(&file_path)) 256 if (!file_util::AbsolutePath(&file_path))
253 return false; 257 return false;
254 258
255 base::AutoLock scoped_lock(path_data->lock); 259 base::AutoLock scoped_lock(path_data->lock);
256 260
257 // Clear the cache now. Some of its entries could have depended 261 // 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. 262 // on the value we are overriding, and are now out of sync with reality.
259 path_data->cache.clear(); 263 path_data->cache.clear();
260 264
261 path_data->cache[key] = file_path;
262 path_data->overrides[key] = file_path; 265 path_data->overrides[key] = file_path;
263 266
264 return true; 267 return true;
265 } 268 }
266 269
270 // static
271 bool PathService::RemoveOverride(int key) {
272 PathData* path_data = GetPathData();
273 DCHECK(path_data);
274
275 base::AutoLock scoped_lock(path_data->lock);
276
277 if (path_data->overrides.find(key) == path_data->overrides.end())
278 return false;
279
280 // Clear the cache now. Some of its entries could have depended on the value
281 // we are going to remove, and are now out of sync.
282 path_data->cache.clear();
283
284 path_data->overrides.erase(key);
285
286 return true;
287 }
288
289 // static
267 void PathService::RegisterProvider(ProviderFunc func, int key_start, 290 void PathService::RegisterProvider(ProviderFunc func, int key_start,
268 int key_end) { 291 int key_end) {
269 PathData* path_data = GetPathData(); 292 PathData* path_data = GetPathData();
270 DCHECK(path_data); 293 DCHECK(path_data);
271 DCHECK_GT(key_end, key_start); 294 DCHECK_GT(key_end, key_start);
272 295
273 base::AutoLock scoped_lock(path_data->lock);
274
275 Provider* p; 296 Provider* p;
276 297
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; 298 p = new Provider;
287 p->is_static = false; 299 p->is_static = false;
288 p->func = func; 300 p->func = func;
289 p->next = path_data->providers;
290 #ifndef NDEBUG 301 #ifndef NDEBUG
291 p->key_start = key_start; 302 p->key_start = key_start;
292 p->key_end = key_end; 303 p->key_end = key_end;
293 #endif 304 #endif
305
306 base::AutoLock scoped_lock(path_data->lock);
307
308 #ifndef NDEBUG
309 Provider *iter = path_data->providers;
310 while (iter) {
311 DCHECK(key_start >= iter->key_end || key_end <= iter->key_start) <<
312 "path provider collision";
313 iter = iter->next;
314 }
315 #endif
316
317 p->next = path_data->providers;
294 path_data->providers = p; 318 path_data->providers = p;
295 } 319 }
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