Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 22 additions & 18 deletions core/object/object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,10 @@ struct ObjectSignalLock {
Mutex *mutex2 = nullptr;

ObjectSignalLock(const Object *p_obj1, const Object *p_obj2 = nullptr) {
mutex1 = p_obj1->signal_mutex;
mutex1 = &p_obj1->_control_mutex;

if (p_obj2 != nullptr) {
mutex2 = p_obj2->signal_mutex;
mutex2 = &p_obj2->_control_mutex;

if (mutex2 < mutex1) {
// We must always lock two locks in the same order.
Expand Down Expand Up @@ -224,9 +224,6 @@ void Object::_initialize() {
}

void Object::_postinitialize() {
if (_uses_signal_mutex()) {
signal_mutex = memnew(Mutex);
}
notification(NOTIFICATION_POSTINITIALIZE);
}

Expand Down Expand Up @@ -876,6 +873,21 @@ Variant Object::call_const(const StringName &p_method, const Variant **p_args, i
return ret;
}

bool Object::_instance_binding_reference(bool p_reference) {
bool can_die = true;
if (_instance_bindings) {
MutexLock instance_binding_lock(_control_mutex);
for (uint32_t i = 0; i < _instance_binding_count; i++) {
if (_instance_bindings[i].reference_callback) {
if (!_instance_bindings[i].reference_callback(_instance_bindings[i].token, _instance_bindings[i].binding, p_reference)) {
can_die = false;
}
}
}
}
return can_die;
}

void Object::_gdvirtual_init_method_ptr(uint32_t p_compat_hash, void *&r_fn_ptr, const StringName &p_fn_name, bool p_compat) const {
r_fn_ptr = nullptr;
if (_extension->get_virtual_call_data2 && _extension->call_virtual_with_data) {
Expand Down Expand Up @@ -1665,10 +1677,6 @@ bool Object::_disconnect(const StringName &p_signal, const Callable &p_callable,
return true;
}

bool Object::_uses_signal_mutex() const {
return true;
}

String Object::_get_locale() const {
TranslationServer *ts = TranslationServer::get_singleton();
const StringName domain_name = get_translation_domain();
Expand Down Expand Up @@ -2165,7 +2173,7 @@ void Object::set_instance_binding(void *p_token, void *p_binding, const GDExtens

void *Object::get_instance_binding(void *p_token, const GDExtensionInstanceBindingCallbacks *p_callbacks) {
void *binding = nullptr;
MutexLock instance_binding_lock(_instance_binding_mutex);
MutexLock instance_binding_lock(_control_mutex);
for (uint32_t i = 0; i < _instance_binding_count; i++) {
if (_instance_bindings[i].token == p_token) {
binding = _instance_bindings[i].binding;
Expand Down Expand Up @@ -2201,7 +2209,7 @@ void *Object::get_instance_binding(void *p_token, const GDExtensionInstanceBindi

bool Object::has_instance_binding(void *p_token) {
bool found = false;
MutexLock instance_binding_lock(_instance_binding_mutex);
MutexLock instance_binding_lock(_control_mutex);
for (uint32_t i = 0; i < _instance_binding_count; i++) {
if (_instance_bindings[i].token == p_token) {
found = true;
Expand All @@ -2214,7 +2222,7 @@ bool Object::has_instance_binding(void *p_token) {

void Object::free_instance_binding(void *p_token) {
bool found = false;
MutexLock instance_binding_lock(_instance_binding_mutex);
MutexLock instance_binding_lock(_control_mutex);
for (uint32_t i = 0; i < _instance_binding_count; i++) {
if (!found && _instance_bindings[i].token == p_token) {
if (_instance_bindings[i].free_callback) {
Expand Down Expand Up @@ -2249,7 +2257,7 @@ void Object::clear_internal_extension() {
_gdtype_ptr = &_get_typev();

// Clear the instance bindings.
_instance_binding_mutex.lock();
_control_mutex.lock();
if (_instance_bindings) {
if (_instance_bindings[0].free_callback) {
_instance_bindings[0].free_callback(_instance_bindings[0].token, this, _instance_bindings[0].binding);
Expand All @@ -2259,7 +2267,7 @@ void Object::clear_internal_extension() {
_instance_bindings[0].free_callback = nullptr;
_instance_bindings[0].reference_callback = nullptr;
}
_instance_binding_mutex.unlock();
_control_mutex.unlock();

// Clear the virtual methods.
while (virtual_method_list) {
Expand Down Expand Up @@ -2364,10 +2372,6 @@ Object::~Object() {
}
memfree(_instance_bindings);
}

if (signal_mutex) {
memdelete(signal_mutex);
}
}

bool predelete_handler(Object *p_object) {
Expand Down
22 changes: 4 additions & 18 deletions core/object/object.h
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,9 @@ class Object {
friend bool predelete_handler(Object *);
friend void postinitialize_handler(Object *);

// Used for thread-safe behavior, such as instance bindings and signals.
mutable Mutex _control_mutex;

ObjectGDExtension *_extension = nullptr;
GDExtensionClassInstancePtr _extension_instance = nullptr;

Expand All @@ -419,7 +422,6 @@ class Object {
HashMap<Callable, Slot> slot_map;
bool removable = false;
};
mutable Mutex *signal_mutex = nullptr;
HashMap<StringName, SignalData> signal_map;
List<Connection> connections;
#ifdef DEBUG_ENABLED
Expand Down Expand Up @@ -487,7 +489,6 @@ class Object {

friend class RefCounted;

BinaryMutex _instance_binding_mutex;
struct InstanceBinding {
void *binding = nullptr;
void *token = nullptr;
Expand All @@ -502,20 +503,7 @@ class Object {
protected:
StringName _translation_domain;

_FORCE_INLINE_ bool _instance_binding_reference(bool p_reference) {
bool can_die = true;
if (_instance_bindings) {
MutexLock instance_binding_lock(_instance_binding_mutex);
for (uint32_t i = 0; i < _instance_binding_count; i++) {
if (_instance_bindings[i].reference_callback) {
if (!_instance_bindings[i].reference_callback(_instance_bindings[i].token, _instance_bindings[i].binding, p_reference)) {
can_die = false;
}
}
}
}
return can_die;
}
bool _instance_binding_reference(bool p_reference);

// Used in gdvirtual.gen.h
void _gdvirtual_init_method_ptr(uint32_t p_compat_hash, void *&r_fn_ptr, const StringName &p_fn_name, bool p_compat) const;
Expand Down Expand Up @@ -599,8 +587,6 @@ class Object {
// Prefer using derives_from.
bool _has_ancestry(AncestralClass p_class) const { return _ancestry & (uint32_t)p_class; }

virtual bool _uses_signal_mutex() const;

// Internal helper to get the current locale, taking into account the translation domain.
String _get_locale() const;

Expand Down
2 changes: 0 additions & 2 deletions scene/main/node.h
Original file line number Diff line number Diff line change
Expand Up @@ -423,8 +423,6 @@ class Node : public Object {
}

protected:
virtual bool _uses_signal_mutex() const override { return false; } // Node uses thread guards instead.

virtual void input(const Ref<InputEvent> &p_event);
virtual void shortcut_input(const Ref<InputEvent> &p_key_event);
virtual void unhandled_input(const Ref<InputEvent> &p_event);
Expand Down
Loading