fix deadlock when deleting models spanning unloaded ADTs
credit : adpsartan and noggit3
This commit is contained in:
T1ti
2024-07-03 00:23:27 +02:00
parent 887b7282e0
commit 6466e6d75a

View File

@@ -111,44 +111,28 @@ namespace Noggit
void world_model_instances_storage::delete_instances_from_tile(TileIndex const& tile) void world_model_instances_storage::delete_instances_from_tile(TileIndex const& tile)
{ {
std::unique_lock<std::mutex> const lock (_mutex); // std::unique_lock<std::mutex> const lock (_mutex);
std::vector<selection_type> instances_to_remove;
for (auto it = _m2s.begin(); it != _m2s.end();) for (auto it = _m2s.begin(); it != _m2s.end(); ++it)
{ {
if (TileIndex(it->second.pos) == tile) if (TileIndex(it->second.pos) == tile)
{ {
if (NOGGIT_CUR_ACTION) instances_to_remove.push_back(&it->second);
NOGGIT_CUR_ACTION->registerObjectRemoved(&it->second);
_world->updateTilesModel(&it->second, model_update::remove);
_instance_count_per_uid.erase(it->first);
it = _m2s.erase(it);
}
else
{
it++;
} }
} }
for (auto it = _wmos.begin(); it != _wmos.end();) for (auto it = _wmos.begin(); it != _wmos.end();++it)
{ {
if (TileIndex(it->second.pos) == tile) if (TileIndex(it->second.pos) == tile)
{ {
if (NOGGIT_CUR_ACTION) instances_to_remove.push_back(&it->second);
NOGGIT_CUR_ACTION->registerObjectRemoved(&it->second);
_world->updateTilesWMO(&it->second, model_update::remove);
_instance_count_per_uid.erase(it->first);
it = _wmos.erase(it);
}
else
{
it++;
} }
} }
delete_instances(instances_to_remove);
} }
void world_model_instances_storage::delete_instances(std::vector<selection_type> const& instances) void world_model_instances_storage::delete_instances(std::vector<selection_type> const& instances)
{ {
std::unique_lock<std::mutex> const lock (_mutex);
for (auto& it : instances) for (auto& it : instances)
{ {
if (it.index() != eEntry_Object) if (it.index() != eEntry_Object)
@@ -156,6 +140,7 @@ namespace Noggit
auto obj = std::get<selected_object_type>(it); auto obj = std::get<selected_object_type>(it);
// should be done in delete_instance
if (NOGGIT_CUR_ACTION) if (NOGGIT_CUR_ACTION)
NOGGIT_CUR_ACTION->registerObjectRemoved(obj); NOGGIT_CUR_ACTION->registerObjectRemoved(obj);
@@ -164,18 +149,14 @@ namespace Noggit
auto instance = static_cast<ModelInstance*>(obj); auto instance = static_cast<ModelInstance*>(obj);
_world->updateTilesModel(instance, model_update::remove); _world->updateTilesModel(instance, model_update::remove);
delete_instance(instance->uid);
_instance_count_per_uid.erase(instance->uid);
_m2s.erase(instance->uid);
} }
else if (obj->which() == eWMO) else if (obj->which() == eWMO)
{ {
auto instance = static_cast<WMOInstance*>(obj); auto instance = static_cast<WMOInstance*>(obj);
_world->updateTilesWMO(instance, model_update::remove); _world->updateTilesWMO(instance, model_update::remove);
delete_instance(instance->uid);
_instance_count_per_uid.erase(instance->uid);
_wmos.erase(instance->uid);
} }
} }
} }