| 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 |