Skip to content

Commit

Permalink
Re-add resource thread-safety measures
Browse files Browse the repository at this point in the history
These deferring measures were added to aid threaded resource loading in being safe.

They were removed as seemingly unneeded, but it seems they are needed so resources involved in threaded loading interact with others only after "sync points".
  • Loading branch information
RandomShaper committed Jul 15, 2024
1 parent 26d1577 commit 62d9ce6
Showing 1 changed file with 16 additions and 1 deletion.
17 changes: 16 additions & 1 deletion core/io/resource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,12 @@
#include <stdio.h>

void Resource::emit_changed() {
emit_signal(CoreStringName(changed));
if (ResourceLoader::is_within_load() && MessageQueue::get_main_singleton() != MessageQueue::get_singleton() && !MessageQueue::get_singleton()->is_flushing()) {
// Let the connection happen on the call queue, later, since signals are not thread-safe.
call_deferred("emit_signal", CoreStringName(changed));
} else {
emit_signal(CoreStringName(changed));
}
}

void Resource::_resource_path_changed() {
Expand Down Expand Up @@ -161,12 +166,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() && MessageQueue::get_main_singleton() != MessageQueue::get_singleton() && !MessageQueue::get_singleton()->is_flushing()) {
// Let the check and connection happen on the call queue, later, since signals are not thread-safe.
callable_mp(this, &Resource::connect_changed).call_deferred(p_callable, p_flags);
return;
}
if (!is_connected(CoreStringName(changed), p_callable) || p_flags & CONNECT_REFERENCE_COUNTED) {
connect(CoreStringName(changed), p_callable, p_flags);
}
}

void Resource::disconnect_changed(const Callable &p_callable) {
if (ResourceLoader::is_within_load() && MessageQueue::get_main_singleton() != MessageQueue::get_singleton() && !MessageQueue::get_singleton()->is_flushing()) {
// Let the check and disconnection happen on the call queue, later, since signals are not thread-safe.
callable_mp(this, &Resource::disconnect_changed).call_deferred(p_callable);
return;
}
if (is_connected(CoreStringName(changed), p_callable)) {
disconnect(CoreStringName(changed), p_callable);
}
Expand Down

0 comments on commit 62d9ce6

Please sign in to comment.