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

Side by Side Diff: base/path_service.cc

Issue 2805100: Fix CheckFalseTest.CheckFails on Linux after my change to ui_test. (Closed)
Patch Set: final Created 10 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
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 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 13 matching lines...) Expand all
24 #elif defined(OS_MACOSX) 24 #elif defined(OS_MACOSX)
25 bool PathProviderMac(int key, FilePath* result); 25 bool PathProviderMac(int key, FilePath* result);
26 #elif defined(OS_POSIX) 26 #elif defined(OS_POSIX)
27 bool PathProviderPosix(int key, FilePath* result); 27 bool PathProviderPosix(int key, FilePath* result);
28 #endif 28 #endif
29 } 29 }
30 30
31 namespace { 31 namespace {
32 32
33 typedef base::hash_map<int, FilePath> PathMap; 33 typedef base::hash_map<int, FilePath> PathMap;
34 typedef base::hash_set<int> PathSet;
35 34
36 // We keep a linked list of providers. In a debug build we ensure that no two 35 // We keep a linked list of providers. In a debug build we ensure that no two
37 // providers claim overlapping keys. 36 // providers claim overlapping keys.
38 struct Provider { 37 struct Provider {
39 PathService::ProviderFunc func; 38 PathService::ProviderFunc func;
40 struct Provider* next; 39 struct Provider* next;
41 #ifndef NDEBUG 40 #ifndef NDEBUG
42 int key_start; 41 int key_start;
43 int key_end; 42 int key_end;
44 #endif 43 #endif
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
87 0, 86 0,
88 0, 87 0,
89 #endif 88 #endif
90 true 89 true
91 }; 90 };
92 #endif 91 #endif
93 92
94 93
95 struct PathData { 94 struct PathData {
96 Lock lock; 95 Lock lock;
97 PathMap cache; // Track mappings from path key to path value. 96 PathMap cache; // Cache mappings from path key to path value.
98 PathSet overrides; // Track whether a path has been overridden. 97 PathMap overrides; // Track path overrides.
99 Provider* providers; // Linked list of path service providers. 98 Provider* providers; // Linked list of path service providers.
100 99
101 PathData() { 100 PathData() {
102 #if defined(OS_WIN) 101 #if defined(OS_WIN)
103 providers = &base_provider_win; 102 providers = &base_provider_win;
104 #elif defined(OS_MACOSX) 103 #elif defined(OS_MACOSX)
105 providers = &base_provider_mac; 104 providers = &base_provider_mac;
106 #elif defined(OS_POSIX) 105 #elif defined(OS_POSIX)
107 providers = &base_provider_posix; 106 providers = &base_provider_posix;
108 #endif 107 #endif
(...skipping 25 matching lines...) Expand all
134 // check for a cached version 133 // check for a cached version
135 PathMap::const_iterator it = path_data->cache.find(key); 134 PathMap::const_iterator it = path_data->cache.find(key);
136 if (it != path_data->cache.end()) { 135 if (it != path_data->cache.end()) {
137 *result = it->second; 136 *result = it->second;
138 return true; 137 return true;
139 } 138 }
140 return false; 139 return false;
141 } 140 }
142 141
143 // static 142 // static
143 bool PathService::GetFromOverrides(int key, FilePath* result) {
144 PathData* path_data = GetPathData();
145 AutoLock scoped_lock(path_data->lock);
146
147 // check for an overriden version.
148 PathMap::const_iterator it = path_data->overrides.find(key);
149 if (it != path_data->overrides.end()) {
150 *result = it->second;
151 return true;
152 }
153 return false;
154 }
155
156 // static
144 void PathService::AddToCache(int key, const FilePath& path) { 157 void PathService::AddToCache(int key, const FilePath& path) {
145 PathData* path_data = GetPathData(); 158 PathData* path_data = GetPathData();
146 AutoLock scoped_lock(path_data->lock); 159 AutoLock scoped_lock(path_data->lock);
147 // Save the computed path in our cache. 160 // Save the computed path in our cache.
148 path_data->cache[key] = path; 161 path_data->cache[key] = path;
149 } 162 }
150 163
151 // TODO(brettw): this function does not handle long paths (filename > MAX_PATH) 164 // TODO(brettw): this function does not handle long paths (filename > MAX_PATH)
152 // characters). This isn't supported very well by Windows right now, so it is 165 // characters). This isn't supported very well by Windows right now, so it is
153 // moot, but we should keep this in mind for the future. 166 // moot, but we should keep this in mind for the future.
154 // static 167 // static
155 bool PathService::Get(int key, FilePath* result) { 168 bool PathService::Get(int key, FilePath* result) {
156 PathData* path_data = GetPathData(); 169 PathData* path_data = GetPathData();
157 DCHECK(path_data); 170 DCHECK(path_data);
158 DCHECK(result); 171 DCHECK(result);
159 DCHECK(key >= base::DIR_CURRENT); 172 DCHECK(key >= base::DIR_CURRENT);
160 173
161 // special case the current directory because it can never be cached 174 // special case the current directory because it can never be cached
162 if (key == base::DIR_CURRENT) 175 if (key == base::DIR_CURRENT)
163 return file_util::GetCurrentDirectory(result); 176 return file_util::GetCurrentDirectory(result);
164 177
165 if (GetFromCache(key, result)) 178 if (GetFromCache(key, result))
166 return true; 179 return true;
167 180
181 if (GetFromOverrides(key, result))
182 return true;
183
168 FilePath path; 184 FilePath path;
169 185
170 // search providers for the requested path 186 // search providers for the requested path
171 // NOTE: it should be safe to iterate here without the lock 187 // NOTE: it should be safe to iterate here without the lock
172 // since RegisterProvider always prepends. 188 // since RegisterProvider always prepends.
173 Provider* provider = path_data->providers; 189 Provider* provider = path_data->providers;
174 while (provider) { 190 while (provider) {
175 if (provider->func(key, &path)) 191 if (provider->func(key, &path))
176 break; 192 break;
177 DCHECK(path.empty()) << "provider should not have modified path"; 193 DCHECK(path.empty()) << "provider should not have modified path";
(...skipping 14 matching lines...) Expand all
192 bool PathService::Get(int key, std::wstring* result) { 208 bool PathService::Get(int key, std::wstring* result) {
193 // Deprecated compatibility function. 209 // Deprecated compatibility function.
194 FilePath path; 210 FilePath path;
195 if (!Get(key, &path)) 211 if (!Get(key, &path))
196 return false; 212 return false;
197 *result = path.ToWStringHack(); 213 *result = path.ToWStringHack();
198 return true; 214 return true;
199 } 215 }
200 #endif 216 #endif
201 217
202 bool PathService::IsOverridden(int key) {
203 PathData* path_data = GetPathData();
204 DCHECK(path_data);
205
206 AutoLock scoped_lock(path_data->lock);
207 return path_data->overrides.find(key) != path_data->overrides.end();
208 }
209
210 bool PathService::Override(int key, const FilePath& path) { 218 bool PathService::Override(int key, const FilePath& path) {
211 PathData* path_data = GetPathData(); 219 PathData* path_data = GetPathData();
212 DCHECK(path_data); 220 DCHECK(path_data);
213 DCHECK(key > base::DIR_CURRENT) << "invalid path key"; 221 DCHECK(key > base::DIR_CURRENT) << "invalid path key";
214 222
215 FilePath file_path = path; 223 FilePath file_path = path;
216 224
217 // Make sure the directory exists. We need to do this before we translate 225 // Make sure the directory exists. We need to do this before we translate
218 // this to the absolute path because on POSIX, AbsolutePath fails if called 226 // this to the absolute path because on POSIX, AbsolutePath fails if called
219 // on a non-existant path. 227 // on a non-existant path.
220 if (!file_util::PathExists(file_path) && 228 if (!file_util::PathExists(file_path) &&
221 !file_util::CreateDirectory(file_path)) 229 !file_util::CreateDirectory(file_path))
222 return false; 230 return false;
223 231
224 // We need to have an absolute path, as extensions and plugins don't like 232 // We need to have an absolute path, as extensions and plugins don't like
225 // relative paths, and will glady crash the browser in CHECK()s if they get a 233 // relative paths, and will glady crash the browser in CHECK()s if they get a
226 // relative path. 234 // relative path.
227 if (!file_util::AbsolutePath(&file_path)) 235 if (!file_util::AbsolutePath(&file_path))
228 return false; 236 return false;
229 237
230 AutoLock scoped_lock(path_data->lock); 238 AutoLock scoped_lock(path_data->lock);
239
240 // Clear the cache now. Some of its entries could have depended
241 // on the value we are overriding, and are now out of sync with reality.
242 path_data->cache.clear();
243
231 path_data->cache[key] = file_path; 244 path_data->cache[key] = file_path;
232 path_data->overrides.insert(key); 245 path_data->overrides[key] = file_path;
246
233 return true; 247 return true;
234 } 248 }
235 249
236 void PathService::RegisterProvider(ProviderFunc func, int key_start, 250 void PathService::RegisterProvider(ProviderFunc func, int key_start,
237 int key_end) { 251 int key_end) {
238 PathData* path_data = GetPathData(); 252 PathData* path_data = GetPathData();
239 DCHECK(path_data); 253 DCHECK(path_data);
240 DCHECK(key_end > key_start); 254 DCHECK(key_end > key_start);
241 255
242 AutoLock scoped_lock(path_data->lock); 256 AutoLock scoped_lock(path_data->lock);
(...skipping 12 matching lines...) Expand all
255 p = new Provider; 269 p = new Provider;
256 p->is_static = false; 270 p->is_static = false;
257 p->func = func; 271 p->func = func;
258 p->next = path_data->providers; 272 p->next = path_data->providers;
259 #ifndef NDEBUG 273 #ifndef NDEBUG
260 p->key_start = key_start; 274 p->key_start = key_start;
261 p->key_end = key_end; 275 p->key_end = key_end;
262 #endif 276 #endif
263 path_data->providers = p; 277 path_data->providers = p;
264 } 278 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698