Pārlūkot izejas kodu

Merge pull request #88561 from RandomShaper/res_load_safer

Improve thread safety of resource loading
Rémi Verschelde 1 gadu atpakaļ
vecāks
revīzija
7462b1a0b2
1 mainītis faili ar 16 papildinājumiem un 1 dzēšanām
  1. 16 1
      core/io/resource.cpp

+ 16 - 1
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);
 	}