From d734bcc289595c4d05c1b71599ea60113b002503 Mon Sep 17 00:00:00 2001 From: Brian Semrau Date: Wed, 6 Oct 2021 13:16:46 -0400 Subject: [PATCH] [core_bind] Add `Thread::is_alive` --- core/bind/core_bind.cpp | 20 ++++++++++++++------ core/bind/core_bind.h | 3 ++- doc/classes/Thread.xml | 12 ++++++++++-- 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp index 408573f84d3..7daa72939e9 100644 --- a/core/bind/core_bind.cpp +++ b/core/bind/core_bind.cpp @@ -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); @@ -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)); @@ -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; } @@ -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); @@ -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..."); } ///////////////////////////////////// diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h index f9525400a4f..8d63506ab6f 100644 --- a/core/bind/core_bind.h +++ b/core/bind/core_bind.h @@ -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; @@ -702,6 +702,7 @@ public: 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(); diff --git a/doc/classes/Thread.xml b/doc/classes/Thread.xml index 6b588646554..c71115ea4a9 100644 --- a/doc/classes/Thread.xml +++ b/doc/classes/Thread.xml @@ -22,7 +22,14 @@ - 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]. + + + + + + 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]. @@ -39,8 +46,9 @@ - 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.