OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 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 | 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 "tools/gn/input_file_manager.h" | 5 #include "tools/gn/input_file_manager.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
11 #include "tools/gn/filesystem_utils.h" | 11 #include "tools/gn/filesystem_utils.h" |
12 #include "tools/gn/parser.h" | 12 #include "tools/gn/parser.h" |
13 #include "tools/gn/scheduler.h" | 13 #include "tools/gn/scheduler.h" |
14 #include "tools/gn/scope_per_file_provider.h" | 14 #include "tools/gn/scope_per_file_provider.h" |
15 #include "tools/gn/tokenizer.h" | 15 #include "tools/gn/tokenizer.h" |
16 #include "tools/gn/trace.h" | 16 #include "tools/gn/trace.h" |
17 | 17 |
18 namespace { | 18 namespace { |
19 | 19 |
20 void InvokeFileLoadCallback(const InputFileManager::FileLoadCallback& cb, | 20 void InvokeFileLoadCallback(const InputFileManager::FileLoadCallback& cb, |
21 const ParseNode* node) { | 21 const ParseNode* node) { |
22 cb.Run(node); | 22 cb.Run(node); |
23 } | 23 } |
24 | 24 |
25 bool DoLoadFile(const LocationRange& origin, | 25 bool DoLoadFile(const LocationRange& origin, |
26 const BuildSettings* build_settings, | 26 const BuildSettings* build_settings, |
27 const SourceFile& name, | 27 const SourceFile& name, |
28 InputFile* file, | 28 InputFile* file, |
29 std::vector<Token>* tokens, | 29 std::vector<Token>* tokens, |
30 scoped_ptr<ParseNode>* root, | 30 std::unique_ptr<ParseNode>* root, |
31 Err* err) { | 31 Err* err) { |
32 // Do all of this stuff outside the lock. We should not give out file | 32 // Do all of this stuff outside the lock. We should not give out file |
33 // pointers until the read is complete. | 33 // pointers until the read is complete. |
34 if (g_scheduler->verbose_logging()) { | 34 if (g_scheduler->verbose_logging()) { |
35 std::string logmsg = name.value(); | 35 std::string logmsg = name.value(); |
36 if (origin.begin().file()) | 36 if (origin.begin().file()) |
37 logmsg += " (referenced from " + origin.begin().Describe(false) + ")"; | 37 logmsg += " (referenced from " + origin.begin().Describe(false) + ")"; |
38 g_scheduler->Log("Loading", logmsg); | 38 g_scheduler->Log("Loading", logmsg); |
39 } | 39 } |
40 | 40 |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
219 | 219 |
220 // The other load could have failed. It is possible that this thread's error | 220 // The other load could have failed. It is possible that this thread's error |
221 // will be reported to the scheduler before the other thread's (and the first | 221 // will be reported to the scheduler before the other thread's (and the first |
222 // error reported "wins"). Forward the parse error from the other load for | 222 // error reported "wins"). Forward the parse error from the other load for |
223 // this thread so that the error message is useful. | 223 // this thread so that the error message is useful. |
224 if (!data->parsed_root) | 224 if (!data->parsed_root) |
225 *err = data->parse_error; | 225 *err = data->parse_error; |
226 return data->parsed_root.get(); | 226 return data->parsed_root.get(); |
227 } | 227 } |
228 | 228 |
229 void InputFileManager::AddDynamicInput(const SourceFile& name, | 229 void InputFileManager::AddDynamicInput( |
230 InputFile** file, | 230 const SourceFile& name, |
231 std::vector<Token>** tokens, | 231 InputFile** file, |
232 scoped_ptr<ParseNode>** parse_root) { | 232 std::vector<Token>** tokens, |
| 233 std::unique_ptr<ParseNode>** parse_root) { |
233 InputFileData* data = new InputFileData(name); | 234 InputFileData* data = new InputFileData(name); |
234 { | 235 { |
235 base::AutoLock lock(lock_); | 236 base::AutoLock lock(lock_); |
236 dynamic_inputs_.push_back(data); | 237 dynamic_inputs_.push_back(data); |
237 } | 238 } |
238 *file = &data->file; | 239 *file = &data->file; |
239 *tokens = &data->tokens; | 240 *tokens = &data->tokens; |
240 *parse_root = &data->parsed_root; | 241 *parse_root = &data->parsed_root; |
241 } | 242 } |
242 | 243 |
(...skipping 20 matching lines...) Expand all Loading... |
263 if (!LoadFile(origin, build_settings, name, file, &err)) | 264 if (!LoadFile(origin, build_settings, name, file, &err)) |
264 g_scheduler->FailWithError(err); | 265 g_scheduler->FailWithError(err); |
265 } | 266 } |
266 | 267 |
267 bool InputFileManager::LoadFile(const LocationRange& origin, | 268 bool InputFileManager::LoadFile(const LocationRange& origin, |
268 const BuildSettings* build_settings, | 269 const BuildSettings* build_settings, |
269 const SourceFile& name, | 270 const SourceFile& name, |
270 InputFile* file, | 271 InputFile* file, |
271 Err* err) { | 272 Err* err) { |
272 std::vector<Token> tokens; | 273 std::vector<Token> tokens; |
273 scoped_ptr<ParseNode> root; | 274 std::unique_ptr<ParseNode> root; |
274 bool success = DoLoadFile(origin, build_settings, name, file, | 275 bool success = DoLoadFile(origin, build_settings, name, file, |
275 &tokens, &root, err); | 276 &tokens, &root, err); |
276 // Can't return early. We have to ensure that the completion event is | 277 // Can't return early. We have to ensure that the completion event is |
277 // signaled in all cases bacause another thread could be blocked on this one. | 278 // signaled in all cases bacause another thread could be blocked on this one. |
278 | 279 |
279 // Save this pointer for running the callbacks below, which happens after the | 280 // Save this pointer for running the callbacks below, which happens after the |
280 // scoped ptr ownership is taken away inside the lock. | 281 // scoped ptr ownership is taken away inside the lock. |
281 ParseNode* unowned_root = root.get(); | 282 ParseNode* unowned_root = root.get(); |
282 | 283 |
283 std::vector<FileLoadCallback> callbacks; | 284 std::vector<FileLoadCallback> callbacks; |
(...skipping 29 matching lines...) Expand all Loading... |
313 | 314 |
314 // Run pending invocations. Theoretically we could schedule each of these | 315 // Run pending invocations. Theoretically we could schedule each of these |
315 // separately to get some parallelism. But normally there will only be one | 316 // separately to get some parallelism. But normally there will only be one |
316 // item in the list, so that's extra overhead and complexity for no gain. | 317 // item in the list, so that's extra overhead and complexity for no gain. |
317 if (success) { | 318 if (success) { |
318 for (const auto& cb : callbacks) | 319 for (const auto& cb : callbacks) |
319 cb.Run(unowned_root); | 320 cb.Run(unowned_root); |
320 } | 321 } |
321 return success; | 322 return success; |
322 } | 323 } |
OLD | NEW |