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

[3.x] [core_bind] Add Thread::is_alive #53490

Merged
merged 1 commit into from
Oct 12, 2021
Merged
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
20 changes: 14 additions & 6 deletions core/bind/core_bind.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2680,12 +2680,15 @@ void _Thread::_start_func(void *ud) {
}
}

t->running.clear();
ERR_FAIL_MSG("Could not call function '" + t->target_method.operator String() + "' to start thread " + t->get_id() + ": " + reason + ".");
}

t->running.clear();
}

Error _Thread::start(Object *p_instance, const StringName &p_method, const Variant &p_userdata, Priority p_priority) {
ERR_FAIL_COND_V_MSG(active.is_set(), ERR_ALREADY_IN_USE, "Thread already started.");
ERR_FAIL_COND_V_MSG(is_active(), ERR_ALREADY_IN_USE, "Thread already started.");
ERR_FAIL_COND_V(!p_instance, ERR_INVALID_PARAMETER);
ERR_FAIL_COND_V(p_method == StringName(), ERR_INVALID_PARAMETER);
ERR_FAIL_INDEX_V(p_priority, PRIORITY_MAX, ERR_INVALID_PARAMETER);
Expand All @@ -2694,7 +2697,7 @@ Error _Thread::start(Object *p_instance, const StringName &p_method, const Varia
target_method = p_method;
target_instance_id = p_instance->get_instance_id();
userdata = p_userdata;
active.set();
running.set();

Ref<_Thread> *ud = memnew(Ref<_Thread>(this));

Expand All @@ -2710,16 +2713,20 @@ String _Thread::get_id() const {
}

bool _Thread::is_active() const {
return active.is_set();
return thread.is_started();
}

bool _Thread::is_alive() const {
return running.is_set();
}

Variant _Thread::wait_to_finish() {
ERR_FAIL_COND_V_MSG(!active.is_set(), Variant(), "Thread must be active to wait for its completion.");
ERR_FAIL_COND_V_MSG(!is_active(), Variant(), "Thread must have been started to wait for its completion.");
thread.wait_to_finish();
Variant r = ret;
target_method = StringName();
target_instance_id = ObjectID();
userdata = Variant();
active.clear();

return r;
}
Expand All @@ -2728,6 +2735,7 @@ void _Thread::_bind_methods() {
ClassDB::bind_method(D_METHOD("start", "instance", "method", "userdata", "priority"), &_Thread::start, DEFVAL(Variant()), DEFVAL(PRIORITY_NORMAL));
ClassDB::bind_method(D_METHOD("get_id"), &_Thread::get_id);
ClassDB::bind_method(D_METHOD("is_active"), &_Thread::is_active);
ClassDB::bind_method(D_METHOD("is_alive"), &_Thread::is_alive);
ClassDB::bind_method(D_METHOD("wait_to_finish"), &_Thread::wait_to_finish);

BIND_ENUM_CONSTANT(PRIORITY_LOW);
Expand All @@ -2739,7 +2747,7 @@ _Thread::_Thread() {
}

_Thread::~_Thread() {
ERR_FAIL_COND_MSG(active.is_set(), "Reference to a Thread object was lost while the thread is still running...");
ERR_FAIL_COND_MSG(is_active(), "Reference to a Thread object was lost while the thread is still running...");
}

/////////////////////////////////////
Expand Down
3 changes: 2 additions & 1 deletion core/bind/core_bind.h
Original file line number Diff line number Diff line change
Expand Up @@ -683,7 +683,7 @@ class _Thread : public Reference {
protected:
Variant ret;
Variant userdata;
SafeFlag active;
SafeFlag running;
ObjectID target_instance_id;
StringName target_method;
Thread thread;
Expand All @@ -702,6 +702,7 @@ class _Thread : public Reference {
Error start(Object *p_instance, const StringName &p_method, const Variant &p_userdata = Variant(), Priority p_priority = PRIORITY_NORMAL);
String get_id() const;
bool is_active() const;
bool is_alive() const;
Variant wait_to_finish();

_Thread();
Expand Down
12 changes: 10 additions & 2 deletions doc/classes/Thread.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,14 @@
<method name="is_active" qualifiers="const">
<return type="bool" />
<description>
Returns [code]true[/code] if this [Thread] is currently active. An active [Thread] cannot start work on a new method but can be joined with [method wait_to_finish].
Returns [code]true[/code] if this [Thread] has been started. Once started, this will return [code]true[/code] until it is joined using [method wait_to_finish]. For checking if a [Thread] is still executing its task, use [method is_alive].
</description>
</method>
<method name="is_alive" qualifiers="const">
<return type="bool" />
<description>
Returns [code]true[/code] if this [Thread] is currently running. This is useful for determining if [method wait_to_finish] can be called without blocking the calling thread.
To check if a [Thread] is joinable, use [method is_active].
</description>
</method>
<method name="start">
Expand All @@ -39,8 +46,9 @@
<method name="wait_to_finish">
<return type="Variant" />
<description>
Joins the [Thread] and waits for it to finish. Returns what the method called returned.
Joins the [Thread] and waits for it to finish. Returns the output of the method passed to [method start].
Should either be used when you want to retrieve the value returned from the method called by the [Thread] or before freeing the instance that contains the [Thread].
To determine if this can be called without blocking the calling thread, check if [method is_alive] is [code]false[/code].
[b]Note:[/b] After the [Thread] finishes joining it will be disposed. If you want to use it again you will have to create a new instance of it.
</description>
</method>
Expand Down