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

[core_bind] Add Thread::is_alive. Replace is_active with is_started to align with core/os/Thread API. #53455

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

Object *target_instance = t->target_callable.get_object();
if (!target_instance) {
t->running.clear();
ERR_FAIL_MSG(vformat("Could not call function '%s' on previously freed instance to start thread %s.", t->target_callable.get_method(), t->get_id()));
}

Expand Down Expand Up @@ -1813,19 +1814,22 @@ void Thread::_start_func(void *ud) {

t->target_callable.call(arg, argc, t->ret, ce);
if (ce.error != Callable::CallError::CALL_OK) {
t->running.clear();
ERR_FAIL_MSG("Could not call function '" + t->target_callable.get_method().operator String() + "' to start thread " + t->get_id() + ": " + Variant::get_callable_error_text(t->target_callable, arg, argc, ce) + ".");
}

t->running.clear();
}

Error Thread::start(const Callable &p_callable, 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_started(), ERR_ALREADY_IN_USE, "Thread already started.");
ERR_FAIL_COND_V(p_callable.is_null(), ERR_INVALID_PARAMETER);
ERR_FAIL_INDEX_V(p_priority, PRIORITY_MAX, ERR_INVALID_PARAMETER);

ret = Variant();
target_callable = p_callable;
userdata = p_userdata;
active.set();
running.set();

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

Expand All @@ -1840,15 +1844,18 @@ String Thread::get_id() const {
return itos(thread.get_id());
}

bool Thread::is_active() const {
return active.is_set();
bool Thread::is_started() const {
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_started(), Variant(), "Thread must have been started to wait for its completion.");
thread.wait_to_finish();
Variant r = ret;
active.clear();
target_callable = Callable();
userdata = Variant();

Expand All @@ -1858,7 +1865,8 @@ Variant Thread::wait_to_finish() {
void Thread::_bind_methods() {
ClassDB::bind_method(D_METHOD("start", "callable", "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_started"), &Thread::is_started);
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 Down
5 changes: 3 additions & 2 deletions core/core_bind.h
Original file line number Diff line number Diff line change
Expand Up @@ -538,7 +538,7 @@ class Thread : public RefCounted {
protected:
Variant ret;
Variant userdata;
SafeFlag active;
SafeFlag running;
Callable target_callable;
::Thread thread;
static void _bind_methods();
Expand All @@ -554,7 +554,8 @@ class Thread : public RefCounted {

Error start(const Callable &p_callable, const Variant &p_userdata = Variant(), Priority p_priority = PRIORITY_NORMAL);
String get_id() const;
bool is_active() const;
bool is_started() const;
bool is_alive() const;
Variant wait_to_finish();
};

Expand Down
16 changes: 12 additions & 4 deletions doc/classes/Thread.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,17 @@
Returns the current [Thread]'s ID, uniquely identifying it among all threads. If the [Thread] is not running this returns an empty string.
</description>
</method>
<method name="is_active" qualifiers="const">
<method name="is_alive" 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] 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_started].
</description>
</method>
<method name="is_started" qualifiers="const">
<return type="bool" />
<description>
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="start">
Expand All @@ -31,15 +38,16 @@
<argument index="1" name="userdata" type="Variant" default="null" />
<argument index="2" name="priority" type="int" enum="Thread.Priority" default="1" />
<description>
Starts a new [Thread] that calls [code]callable[/code] with [code]userdata[/code] passed as an argument. Even if no userdata is passed, [code]method[/code] must accept one argument and it will be null. The [code]priority[/code] of the [Thread] can be changed by passing a value from the [enum Priority] enum.
Starts a new [Thread] that calls [code]callable[/code] with [code]userdata[/code] passed as an argument. Even if no userdata is passed, [code]callable[/code] must accept one argument and it will be null. The [code]priority[/code] of the [Thread] can be changed by passing a value from the [enum Priority] enum.
Returns [constant OK] on success, or [constant ERR_CANT_CREATE] on failure.
</description>
</method>
<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 [Callable] 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