}
}
- // The other load could have failed. In this case that error was probably
- // printed to the console, but we need to return something here, so make up a
- // dummy error.
- //
- // There is a race condition. The other load could have failed, but if the
- // other thread is delayed for some reason, this thread could end up
- // reporting the error to the scheduler first (since first error report
- // wins). The user will see this one and the "real" one will be discarded.
- if (!data->parsed_root) {
- *err = Err(origin, "File parse failed.",
- "If you see this, I'm really sorry, but a race condition has caused\n"
- "me to eat your error message. It was crunchy. If the parse error\n"
- "in your imported file isn't obvious, try re-running GN.");
- }
+ // The other load could have failed. It is possible that this thread's error
+ // will be reported to the scheduler before the other thread's (and the first
+ // error reported "wins"). Forward the parse error from the other load for
+ // this thread so that the error message is useful.
+ if (!data->parsed_root)
+ *err = data->parse_error;
return data->parsed_root.get();
}
std::vector<base::FilePath>* result) const {
base::AutoLock lock(lock_);
result->reserve(input_files_.size());
- for (InputFileMap::const_iterator i = input_files_.begin();
- i != input_files_.end(); ++i) {
- if (!i->second->file.physical_name().empty())
- result->push_back(i->second->file.physical_name());
+ for (const auto& file : input_files_) {
+ if (!file.second->file.physical_name().empty())
+ result->push_back(file.second->file.physical_name());
}
}
if (success) {
data->tokens.swap(tokens);
data->parsed_root = root.Pass();
+ } else {
+ data->parse_error = *err;
}
// Unblock waiters on this event.
// separately to get some parallelism. But normally there will only be one
// item in the list, so that's extra overhead and complexity for no gain.
if (success) {
- for (size_t i = 0; i < callbacks.size(); i++)
- callbacks[i].Run(unowned_root);
+ for (const auto& cb : callbacks)
+ cb.Run(unowned_root);
}
return success;
}