Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 158 } | 158 } |
| 159 | 159 |
| 160 // static | 160 // static |
| 161 bool PathService::GetFromOverrides(int key, FilePath* result) { | 161 bool PathService::GetFromOverrides(int key, FilePath* result) { |
| 162 PathData* path_data = GetPathData(); | 162 PathData* path_data = GetPathData(); |
| 163 base::AutoLock scoped_lock(path_data->lock); | 163 base::AutoLock scoped_lock(path_data->lock); |
| 164 | 164 |
| 165 // check for an overridden version. | 165 // check for an overridden version. |
| 166 PathMap::const_iterator it = path_data->overrides.find(key); | 166 PathMap::const_iterator it = path_data->overrides.find(key); |
| 167 if (it != path_data->overrides.end()) { | 167 if (it != path_data->overrides.end()) { |
| 168 *result = it->second; | 168 *result = it->second; |
|
jar (doing other things)
2012/09/15 02:01:20
This is (I think) the one place they *could* (shou
pastarmovj
2012/09/17 16:30:40
Absolutely. What happens now seems to be that only
| |
| 169 return true; | 169 return true; |
| 170 } | 170 } |
| 171 return false; | 171 return false; |
| 172 } | 172 } |
| 173 | 173 |
| 174 // static | 174 // static |
| 175 void PathService::AddToCache(int key, const FilePath& path) { | 175 void PathService::AddToCache(int key, const FilePath& path) { |
| 176 PathData* path_data = GetPathData(); | 176 PathData* path_data = GetPathData(); |
| 177 base::AutoLock scoped_lock(path_data->lock); | 177 base::AutoLock scoped_lock(path_data->lock); |
| 178 // Save the computed path in our cache. | 178 // Save the computed path in our cache. |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 197 return true; | 197 return true; |
| 198 | 198 |
| 199 if (GetFromOverrides(key, result)) | 199 if (GetFromOverrides(key, result)) |
| 200 return true; | 200 return true; |
| 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; | 207 Provider* provider = path_data->providers; |
|
jar (doing other things)
2012/09/15 02:01:20
This is probably racy, as the contents of path_dat
pastarmovj
2012/09/17 16:30:40
Theoretically you are right but practically the li
jar (doing other things)
2012/09/17 17:06:08
The comment is wrong. The fact that we use a lock
pastarmovj
2012/09/18 14:27:13
Done.
| |
| 208 while (provider) { | 208 while (provider) { |
| 209 if (provider->func(key, &path)) | 209 if (provider->func(key, &path)) |
| 210 break; | 210 break; |
| 211 DCHECK(path.empty()) << "provider should not have modified path"; | 211 DCHECK(path.empty()) << "provider should not have modified path"; |
| 212 provider = provider->next; | 212 provider = provider->next; |
| 213 } | 213 } |
| 214 | 214 |
| 215 if (path.empty()) | 215 if (path.empty()) |
| 216 return false; | 216 return false; |
| 217 | 217 |
| 218 AddToCache(key, path); | 218 AddToCache(key, path); |
| 219 | 219 |
| 220 *result = path; | 220 *result = path; |
| 221 return true; | 221 return true; |
| 222 } | 222 } |
| 223 | 223 |
| 224 // static | |
|
jar (doing other things)
2012/09/15 02:01:20
I personally like this style... but it is a gratui
pastarmovj
2012/09/17 16:30:40
Actually the file is already mixed style (see line
| |
| 224 bool PathService::Override(int key, const FilePath& path) { | 225 bool PathService::Override(int key, const FilePath& path) { |
| 225 // Just call the full function with true for the value of |create|. | 226 // Just call the full function with true for the value of |create|. |
| 226 return OverrideAndCreateIfNeeded(key, path, true); | 227 return OverrideAndCreateIfNeeded(key, path, true); |
| 227 } | 228 } |
| 228 | 229 |
| 230 // static | |
| 229 bool PathService::OverrideAndCreateIfNeeded(int key, | 231 bool PathService::OverrideAndCreateIfNeeded(int key, |
| 230 const FilePath& path, | 232 const FilePath& path, |
| 231 bool create) { | 233 bool create) { |
| 232 PathData* path_data = GetPathData(); | 234 PathData* path_data = GetPathData(); |
| 233 DCHECK(path_data); | 235 DCHECK(path_data); |
| 234 DCHECK_GT(key, base::DIR_CURRENT) << "invalid path key"; | 236 DCHECK_GT(key, base::DIR_CURRENT) << "invalid path key"; |
| 235 | 237 |
| 236 FilePath file_path = path; | 238 FilePath file_path = path; |
| 237 | 239 |
| 238 // For some locations this will fail if called from inside the sandbox there- | 240 // For some locations this will fail if called from inside the sandbox there- |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 251 // relative path. | 253 // relative path. |
| 252 if (!file_util::AbsolutePath(&file_path)) | 254 if (!file_util::AbsolutePath(&file_path)) |
| 253 return false; | 255 return false; |
| 254 | 256 |
| 255 base::AutoLock scoped_lock(path_data->lock); | 257 base::AutoLock scoped_lock(path_data->lock); |
| 256 | 258 |
| 257 // Clear the cache now. Some of its entries could have depended | 259 // 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. | 260 // on the value we are overriding, and are now out of sync with reality. |
| 259 path_data->cache.clear(); | 261 path_data->cache.clear(); |
| 260 | 262 |
| 261 path_data->cache[key] = file_path; | 263 path_data->cache[key] = file_path; |
|
jar (doing other things)
2012/09/15 02:01:20
It is interesting that the directly implent into t
pastarmovj
2012/09/17 16:30:40
I agree. I added a new test to verify that.
| |
| 262 path_data->overrides[key] = file_path; | 264 path_data->overrides[key] = file_path; |
| 263 | 265 |
| 264 return true; | 266 return true; |
| 265 } | 267 } |
| 266 | 268 |
| 269 // static | |
| 270 bool PathService::RemoveOverride(int key) { | |
| 271 PathData* path_data = GetPathData(); | |
| 272 DCHECK(path_data); | |
| 273 | |
| 274 base::AutoLock scoped_lock(path_data->lock); | |
| 275 | |
| 276 if (path_data->overrides.find(key) == path_data->overrides.end()) | |
| 277 return false; | |
| 278 | |
| 279 // Clear the cache now. Some of its entries could have depended on the value | |
| 280 // we are going to remove, and are now out of sync. | |
| 281 path_data->cache.clear(); | |
| 282 | |
| 283 path_data->overrides.erase(key); | |
| 284 | |
| 285 return true; | |
| 286 } | |
| 287 | |
| 288 // static | |
| 267 void PathService::RegisterProvider(ProviderFunc func, int key_start, | 289 void PathService::RegisterProvider(ProviderFunc func, int key_start, |
| 268 int key_end) { | 290 int key_end) { |
| 269 PathData* path_data = GetPathData(); | 291 PathData* path_data = GetPathData(); |
| 270 DCHECK(path_data); | 292 DCHECK(path_data); |
| 271 DCHECK_GT(key_end, key_start); | 293 DCHECK_GT(key_end, key_start); |
| 272 | 294 |
| 273 base::AutoLock scoped_lock(path_data->lock); | 295 base::AutoLock scoped_lock(path_data->lock); |
| 274 | 296 |
| 275 Provider* p; | 297 Provider* p; |
| 276 | 298 |
| 277 #ifndef NDEBUG | 299 #ifndef NDEBUG |
| 278 p = path_data->providers; | 300 p = path_data->providers; |
| 279 while (p) { | 301 while (p) { |
| 280 DCHECK(key_start >= p->key_end || key_end <= p->key_start) << | 302 DCHECK(key_start >= p->key_end || key_end <= p->key_start) << |
| 281 "path provider collision"; | 303 "path provider collision"; |
| 282 p = p->next; | 304 p = p->next; |
| 283 } | 305 } |
| 284 #endif | 306 #endif |
| 285 | 307 |
| 286 p = new Provider; | 308 p = new Provider; |
| 287 p->is_static = false; | 309 p->is_static = false; |
| 288 p->func = func; | 310 p->func = func; |
| 289 p->next = path_data->providers; | 311 p->next = path_data->providers; |
| 290 #ifndef NDEBUG | 312 #ifndef NDEBUG |
| 291 p->key_start = key_start; | 313 p->key_start = key_start; |
| 292 p->key_end = key_end; | 314 p->key_end = key_end; |
| 293 #endif | 315 #endif |
| 294 path_data->providers = p; | 316 path_data->providers = p; |
|
jar (doing other things)
2012/09/15 02:01:20
This push operation is correctly locked, but it wo
pastarmovj
2012/09/17 16:30:40
Done.
| |
| 295 } | 317 } |
| OLD | NEW |