Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Thread-safe signalling inside Mutex class. #99697

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
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
50 changes: 50 additions & 0 deletions core/core_bind.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1301,6 +1301,56 @@ void Mutex::unlock() {
mutex.unlock();
}

Error Mutex::emit_signalp(const StringName &p_name, const Variant **p_args, int p_argcount) {
MutexLock lock(mutex);
return Object::emit_signalp(p_name, p_args, p_argcount);
}

bool Mutex::has_signal(const StringName &p_name) const {
MutexLock lock(mutex);
return Object::has_signal(p_name);
}

void Mutex::get_signal_list(List<MethodInfo> *p_signals) const {
MutexLock lock(mutex);
Object::get_signal_list(p_signals);
}

void Mutex::get_signal_connection_list(const StringName &p_signal, List<Connection> *p_connections) const {
MutexLock lock(mutex);
Object::get_signal_connection_list(p_signal, p_connections);
}

void Mutex::get_all_signal_connections(List<Connection> *p_connections) const {
MutexLock lock(mutex);
Object::get_all_signal_connections(p_connections);
}

int Mutex::get_persistent_signal_connection_count() const {
MutexLock lock(mutex);
return Object::get_persistent_signal_connection_count();
}

void Mutex::get_signals_connected_to_this(List<Connection> *p_connections) const {
MutexLock lock(mutex);
Object::get_signals_connected_to_this(p_connections);
}

Error Mutex::connect(const StringName &p_signal, const Callable &p_callable, uint32_t p_flags) {
MutexLock lock(mutex);
return Object::connect(p_signal, p_callable, p_flags);
}

void Mutex::disconnect(const StringName &p_signal, const Callable &p_callable) {
MutexLock lock(mutex);
Object::disconnect(p_signal, p_callable);
}

bool Mutex::is_connected(const StringName &p_signal, const Callable &p_callable) const {
MutexLock lock(mutex);
return Object::is_connected(p_signal, p_callable);
}

void Mutex::_bind_methods() {
ClassDB::bind_method(D_METHOD("lock"), &Mutex::lock);
ClassDB::bind_method(D_METHOD("try_lock"), &Mutex::try_lock);
Expand Down
12 changes: 12 additions & 0 deletions core/core_bind.h
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,18 @@ class Mutex : public RefCounted {
void lock();
bool try_lock();
void unlock();

virtual Error emit_signalp(const StringName &p_name, const Variant **p_args, int p_argcount) override;
virtual bool has_signal(const StringName &p_name) const override;
virtual void get_signal_list(List<MethodInfo> *p_signals) const override;
virtual void get_signal_connection_list(const StringName &p_signal, List<Connection> *p_connections) const override;
virtual void get_all_signal_connections(List<Connection> *p_connections) const override;
virtual int get_persistent_signal_connection_count() const override;
virtual void get_signals_connected_to_this(List<Connection> *p_connections) const override;

virtual Error connect(const StringName &p_signal, const Callable &p_callable, uint32_t p_flags = 0) override;
virtual void disconnect(const StringName &p_signal, const Callable &p_callable) override;
virtual bool is_connected(const StringName &p_signal, const Callable &p_callable) const override;
};

class Semaphore : public RefCounted {
Expand Down
24 changes: 12 additions & 12 deletions core/object/object.h
Original file line number Diff line number Diff line change
Expand Up @@ -921,18 +921,18 @@ class Object {
return emit_signalp(p_name, sizeof...(p_args) == 0 ? nullptr : (const Variant **)argptrs, sizeof...(p_args));
}

MTVIRTUAL Error emit_signalp(const StringName &p_name, const Variant **p_args, int p_argcount);
MTVIRTUAL bool has_signal(const StringName &p_name) const;
MTVIRTUAL void get_signal_list(List<MethodInfo> *p_signals) const;
MTVIRTUAL void get_signal_connection_list(const StringName &p_signal, List<Connection> *p_connections) const;
MTVIRTUAL void get_all_signal_connections(List<Connection> *p_connections) const;
MTVIRTUAL int get_persistent_signal_connection_count() const;
MTVIRTUAL void get_signals_connected_to_this(List<Connection> *p_connections) const;

MTVIRTUAL Error connect(const StringName &p_signal, const Callable &p_callable, uint32_t p_flags = 0);
MTVIRTUAL void disconnect(const StringName &p_signal, const Callable &p_callable);
MTVIRTUAL bool is_connected(const StringName &p_signal, const Callable &p_callable) const;
MTVIRTUAL bool has_connections(const StringName &p_signal) const;
virtual Error emit_signalp(const StringName &p_name, const Variant **p_args, int p_argcount);
virtual bool has_signal(const StringName &p_name) const;
virtual void get_signal_list(List<MethodInfo> *p_signals) const;
virtual void get_signal_connection_list(const StringName &p_signal, List<Connection> *p_connections) const;
virtual void get_all_signal_connections(List<Connection> *p_connections) const;
virtual int get_persistent_signal_connection_count() const;
virtual void get_signals_connected_to_this(List<Connection> *p_connections) const;

virtual Error connect(const StringName &p_signal, const Callable &p_callable, uint32_t p_flags = 0);
virtual void disconnect(const StringName &p_signal, const Callable &p_callable);
virtual bool is_connected(const StringName &p_signal, const Callable &p_callable) const;
virtual bool has_connections(const StringName &p_signal) const;

template <typename... VarArgs>
void call_deferred(const StringName &p_name, VarArgs... p_args) {
Expand Down
2 changes: 2 additions & 0 deletions doc/classes/Mutex.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
[b]Warning:[/b] To ensure proper cleanup without crashes or deadlocks, the following conditions must be met:
- When a [Mutex]'s reference count reaches zero and it is therefore destroyed, no threads (including the one on which the destruction will happen) must have it locked.
- When a [Thread]'s reference count reaches zero and it is therefore destroyed, it must not have any mutex locked.

[b]Note:[/b] You can now use `add_user_signal` on mutexes to create thread-safe signals on them.
</description>
<tutorials>
<link title="Using multiple threads">$DOCS_URL/tutorials/performance/using_multiple_threads.html</link>
Expand Down