summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorRémi Verschelde <rverschelde@gmail.com>2024-02-29 13:53:58 +0100
committerRémi Verschelde <rverschelde@gmail.com>2024-02-29 13:53:58 +0100
commit7462b1a0b2b3facc33e80f2ff925957b8aad0037 (patch)
treefd2e5bb1fec0f6a64c823858f8d173cdd599ab4d /core
parent5c38b9bcf4c7ee3a9030b7a31c1f26d75fd53e72 (diff)
parent84b85d894c47cf5d680992fcae1d9af48eee0d3f (diff)
downloadredot-engine-7462b1a0b2b3facc33e80f2ff925957b8aad0037.tar.gz
Merge pull request #88561 from RandomShaper/res_load_safer
Improve thread safety of resource loading
Diffstat (limited to 'core')
-rw-r--r--core/io/resource.cpp17
1 files changed, 16 insertions, 1 deletions
diff --git a/core/io/resource.cpp b/core/io/resource.cpp
index daa57be76f..7e8d0b43cd 100644
--- a/core/io/resource.cpp
+++ b/core/io/resource.cpp
@@ -41,7 +41,12 @@
#include <stdio.h>
void Resource::emit_changed() {
- emit_signal(CoreStringNames::get_singleton()->changed);
+ if (ResourceLoader::is_within_load() && !Thread::is_main_thread()) {
+ // Let the connection happen on the main thread, later, since signals are not thread-safe.
+ call_deferred("emit_signal", CoreStringNames::get_singleton()->changed);
+ } else {
+ emit_signal(CoreStringNames::get_singleton()->changed);
+ }
}
void Resource::_resource_path_changed() {
@@ -152,12 +157,22 @@ bool Resource::editor_can_reload_from_file() {
}
void Resource::connect_changed(const Callable &p_callable, uint32_t p_flags) {
+ if (ResourceLoader::is_within_load() && !Thread::is_main_thread()) {
+ // Let the check and connection happen on the main thread, later, since signals are not thread-safe.
+ callable_mp(this, &Resource::connect_changed).call_deferred(p_callable, p_flags);
+ return;
+ }
if (!is_connected(CoreStringNames::get_singleton()->changed, p_callable) || p_flags & CONNECT_REFERENCE_COUNTED) {
connect(CoreStringNames::get_singleton()->changed, p_callable, p_flags);
}
}
void Resource::disconnect_changed(const Callable &p_callable) {
+ if (ResourceLoader::is_within_load() && !Thread::is_main_thread()) {
+ // Let the check and disconnection happen on the main thread, later, since signals are not thread-safe.
+ callable_mp(this, &Resource::disconnect_changed).call_deferred(p_callable);
+ return;
+ }
if (is_connected(CoreStringNames::get_singleton()->changed, p_callable)) {
disconnect(CoreStringNames::get_singleton()->changed, p_callable);
}