Skip to content

Commit 061eab1

Browse files
committed
Add clear_task_if_completed function to WorkerThreadPools
Adds clear_task_if_completed function to worker threadpools Currently every task must be waited on (wait_for_task_completion) for their resources to be removed from memory (#84888). This is addressed in the docs however said solution may not always be intuitive or ideal as the function known as "wait_for_task_completion" is used even in cases where no waiting is necessary as it does the double duty of waiting, and also clearing memory. While it makes sense that if you wait for a task, and it finishes, it should be cleared from memory, it is not always intuitive that you HAVE to wait for a task that you know is completed (via is_task_completed) to prevent a memory leak. This can currently be circumvented by using an if statement (if is_task_completed: wait_for_task_completion) however said usage is ugly and also unintuitive. This commit adds a function which checks if the task is completed, and then returns true and clears resources if so. Essentially doing the same job as wait_for_task_completion if already completed, HOWEVER not binding the main thread (or the thread it is called from) in the case the task isn't. This allows for resource clearing without accidentally pausing the entire thread if not completed, in the case of a non essential functions such as saving (which can be allowed to operate in the background without pausing the entire game/main thread)
1 parent 5efd124 commit 061eab1

File tree

3 files changed

+27
-1
lines changed

3 files changed

+27
-1
lines changed

core/object/worker_thread_pool.cpp

+18-1
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,23 @@ bool WorkerThreadPool::is_task_completed(TaskID p_task_id) const {
361361
return (*taskp)->completed;
362362
}
363363

364+
bool WorkerThreadPool::clear_task_if_completed(TaskID p_task_id) {
365+
MutexLock task_lock(task_mutex);
366+
Task **taskp = tasks.getptr(p_task_id);
367+
if (!taskp) {
368+
ERR_FAIL_V_MSG(false, "Invalid Task ID"); // Invalid task
369+
}
370+
Task *task = *taskp;
371+
if (task->completed) {
372+
if (task->waiting_pool == 0 && task->waiting_user == 0) {
373+
tasks.erase(p_task_id);
374+
task_allocator.free(task);
375+
}
376+
return true;
377+
}
378+
return false;
379+
}
380+
364381
Error WorkerThreadPool::wait_for_task_completion(TaskID p_task_id) {
365382
task_mutex.lock();
366383
Task **taskp = tasks.getptr(p_task_id);
@@ -824,8 +841,8 @@ void WorkerThreadPool::finish() {
824841
void WorkerThreadPool::_bind_methods() {
825842
ClassDB::bind_method(D_METHOD("add_task", "action", "high_priority", "description"), &WorkerThreadPool::add_task, DEFVAL(false), DEFVAL(String()));
826843
ClassDB::bind_method(D_METHOD("is_task_completed", "task_id"), &WorkerThreadPool::is_task_completed);
844+
ClassDB::bind_method(D_METHOD("clear_task_if_completed", "task_id"), &WorkerThreadPool::clear_task_if_completed);
827845
ClassDB::bind_method(D_METHOD("wait_for_task_completion", "task_id"), &WorkerThreadPool::wait_for_task_completion);
828-
829846
ClassDB::bind_method(D_METHOD("add_group_task", "action", "elements", "tasks_needed", "high_priority", "description"), &WorkerThreadPool::add_group_task, DEFVAL(-1), DEFVAL(false), DEFVAL(String()));
830847
ClassDB::bind_method(D_METHOD("is_group_task_completed", "group_id"), &WorkerThreadPool::is_group_task_completed);
831848
ClassDB::bind_method(D_METHOD("get_group_processed_element_count", "group_id"), &WorkerThreadPool::get_group_processed_element_count);

core/object/worker_thread_pool.h

+1
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,7 @@ class WorkerThreadPool : public Object {
238238
TaskID add_task(const Callable &p_action, bool p_high_priority = false, const String &p_description = String());
239239

240240
bool is_task_completed(TaskID p_task_id) const;
241+
bool clear_task_if_completed(TaskID p_task_id);
241242
Error wait_for_task_completion(TaskID p_task_id);
242243

243244
void yield();

doc/classes/WorkerThreadPool.xml

+8
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,14 @@
7272
[b]Warning:[/b] Every task must be waited for completion using [method wait_for_task_completion] or [method wait_for_group_task_completion] at some point so that any allocated resources inside the task can be cleaned up.
7373
</description>
7474
</method>
75+
<method name="clear_task_if_completed">
76+
<return type="bool" />
77+
<param index="0" name="task_id" type="int" />
78+
<description>
79+
Returns [code]true[/code] if the task with the given ID is completed, and then removes it from memory (if completed).
80+
[b]Note:[/b] You should only call this method between adding the task and awaiting its completion.
81+
</description>
82+
</method>
7583
<method name="get_group_processed_element_count" qualifiers="const">
7684
<return type="int" />
7785
<param index="0" name="group_id" type="int" />

0 commit comments

Comments
 (0)