Skip to content

Commit

Permalink
Fix potential hang on exit due to deadlocks.
Browse files Browse the repository at this point in the history
  • Loading branch information
Relintai committed Feb 8, 2025
1 parent c85768a commit 12214cb
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 0 deletions.
35 changes: 35 additions & 0 deletions modules/terraman/library/terrain_library_merger_pcm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,11 @@ void TerrainLibraryMergerPCM::_material_cache_get_key(Ref<TerrainChunk> chunk) {
continue;
}

if (unlikely(_engine_quitting)) {
_material_cache_mutex.unlock();
return;
}

Ref<TerrainSurfaceMerger> nms = ms->duplicate();
nms->set_library(Ref<TerrainLibraryMergerPCM>(this));
nms->set_id(s);
Expand All @@ -186,6 +191,11 @@ void TerrainLibraryMergerPCM::_material_cache_get_key(Ref<TerrainChunk> chunk) {
continue;
}

if (unlikely(_engine_quitting)) {
_material_cache_mutex.unlock();
return;
}

Ref<Material> nm = m->duplicate();

cache->material_add(nm);
Expand Down Expand Up @@ -359,6 +369,11 @@ void TerrainLibraryMergerPCM::_liquid_material_cache_get_key(Ref<TerrainChunk> c
continue;
}

if (unlikely(_engine_quitting)) {
_liquid_material_cache_mutex.unlock();
return;
}

Ref<TerrainSurfaceMerger> nms = ms->duplicate();
nms->set_library(Ref<TerrainLibraryMergerPCM>(this));
nms->set_id(s);
Expand All @@ -373,6 +388,11 @@ void TerrainLibraryMergerPCM::_liquid_material_cache_get_key(Ref<TerrainChunk> c
continue;
}

if (unlikely(_engine_quitting)) {
_liquid_material_cache_mutex.unlock();
return;
}

Ref<Material> nm = m->duplicate();

cache->material_add(nm);
Expand Down Expand Up @@ -560,6 +580,11 @@ void TerrainLibraryMergerPCM::_prop_material_cache_get_key(Ref<TerrainChunk> chu
continue;
}

if (unlikely(_engine_quitting)) {
_prop_material_cache_mutex.unlock();
return;
}

Ref<Material> nm = m->duplicate();

cache->material_add(nm);
Expand Down Expand Up @@ -972,6 +997,8 @@ void TerrainLibraryMergerPCM::_setup_material_albedo(const int material_index, c
}

TerrainLibraryMergerPCM::TerrainLibraryMergerPCM() {
_engine_quitting = false;

_packer.instance();

_packer->set_texture_flags(Texture::FLAG_MIPMAPS | Texture::FLAG_FILTER);
Expand Down Expand Up @@ -1046,6 +1073,14 @@ bool TerrainLibraryMergerPCM::process_prop_textures(Ref<PropData> prop) {
}
#endif

void TerrainLibraryMergerPCM::_notification(int p_what) {
switch (p_what) {
case MainLoop::NOTIFICATION_QUITTING: {
_engine_quitting = true;
} break;
}
}

void TerrainLibraryMergerPCM::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_texture_flags"), &TerrainLibraryMergerPCM::get_texture_flags);
ClassDB::bind_method(D_METHOD("set_texture_flags", "flags"), &TerrainLibraryMergerPCM::set_texture_flags);
Expand Down
7 changes: 7 additions & 0 deletions modules/terraman/library/terrain_library_merger_pcm.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ class TerrainLibraryMergerPCM : public TerrainLibrary {
bool process_prop_textures(Ref<PropData> prop);
#endif

virtual void _notification(int p_what);
static void _bind_methods();

RBMap<int, Ref<TerrainMaterialCachePCM>> _material_cache;
Expand All @@ -143,6 +144,12 @@ class TerrainLibraryMergerPCM : public TerrainLibrary {
Mutex _material_cache_mutex;
Mutex _liquid_material_cache_mutex;
Mutex _prop_material_cache_mutex;

// To fix potential deadlock on quit
// (Materials can't be duplicated after the engine started deinitializing itself)
// The notification that sets this should be immediate, the engine will start deinitialization later
// so materials that already started duplicating should be fine
bool _engine_quitting;
};

#endif
6 changes: 6 additions & 0 deletions modules/terraman/world/terrain_world.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include "core/containers/hash_set.h"

#include "core/object/message_queue.h"
#include "core/os/main_loop.h"
#include "terrain_chunk.h"
#include "terrain_structure.h"

Expand Down Expand Up @@ -1429,6 +1430,11 @@ void TerrainWorld::_notification(int p_what) {
}
break;
}
case MainLoop::NOTIFICATION_QUITTING: {
if (_library.is_valid()) {
_library->notification(MainLoop::NOTIFICATION_QUITTING);
}
} break;
}
}

Expand Down

0 comments on commit 12214cb

Please sign in to comment.