Fix #13192: Crash because of objects not properly loading (#13197)

This commit is contained in:
ζeh Matt 2020-10-15 03:54:22 +03:00 committed by GitHub
parent 711dd00cde
commit 92e7b6244b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 25 additions and 10 deletions

View File

@ -344,7 +344,7 @@ private:
return result; return result;
} }
void SetNewLoadedObjectList(std::vector<std::unique_ptr<Object>> newLoadedObjects) void SetNewLoadedObjectList(std::vector<std::unique_ptr<Object>>&& newLoadedObjects)
{ {
if (newLoadedObjects.empty()) if (newLoadedObjects.empty())
{ {
@ -588,26 +588,41 @@ private:
// Read objects // Read objects
std::mutex commonMutex; std::mutex commonMutex;
ParallelFor(requiredObjects, [this, &commonMutex, requiredObjects, &objects, &badObjects, &loadedObjects](size_t i) { ParallelFor(requiredObjects, [this, &commonMutex, requiredObjects, &objects, &badObjects, &loadedObjects](size_t i) {
auto ori = requiredObjects[i]; auto requiredObject = requiredObjects[i];
std::unique_ptr<Object> object; std::unique_ptr<Object> object;
if (ori != nullptr) if (requiredObject != nullptr)
{ {
auto loadedObject = ori->LoadedObject; auto loadedObject = requiredObject->LoadedObject;
if (loadedObject == nullptr) if (loadedObject == nullptr)
{ {
object = _objectRepository.LoadObject(ori); // Object requires to be loaded, if the object successfully loads it will register it
// as a loaded object otherwise placed into the badObjects list.
object = _objectRepository.LoadObject(requiredObject);
std::lock_guard<std::mutex> guard(commonMutex);
if (object == nullptr) if (object == nullptr)
{ {
std::lock_guard<std::mutex> guard(commonMutex); badObjects.push_back(requiredObject->ObjectEntry);
badObjects.push_back(ori->ObjectEntry); ReportObjectLoadProblem(&requiredObject->ObjectEntry);
ReportObjectLoadProblem(&ori->ObjectEntry);
} }
else else
{ {
std::lock_guard<std::mutex> guard(commonMutex);
loadedObjects.push_back(object.get()); loadedObjects.push_back(object.get());
// Connect the ori to the registered object // Connect the ori to the registered object
_objectRepository.RegisterLoadedObject(ori, object.get()); _objectRepository.RegisterLoadedObject(requiredObject, object.get());
}
}
else
{
// The object is already loaded, given that the new list will be used as the next loaded object list,
// we can move the element out safely. This is required as the resulting list must contain all loaded
// objects and not just the newly loaded ones.
std::lock_guard<std::mutex> guard(commonMutex);
auto it = std::find_if(_loadedObjects.begin(), _loadedObjects.end(), [loadedObject](const auto& obj) {
return obj.get() == loadedObject;
});
if (it != _loadedObjects.end())
{
object = std::move(*it);
} }
} }
} }