Browse Source

Merge pull request #90865 from RandomShaper/wtp_re_fix_yield

WorkerThreadPool: Fix yield-over for not-yet-started tasks
Rémi Verschelde 1 year ago
parent
commit
9bc49a66ba
2 changed files with 12 additions and 2 deletions
  1. 8 1
      core/object/worker_thread_pool.cpp
  2. 4 1
      core/object/worker_thread_pool.h

+ 8 - 1
core/object/worker_thread_pool.cpp

@@ -72,6 +72,9 @@ void WorkerThreadPool::_process_task(Task *p_task) {
 		p_task->pool_thread_index = pool_thread_index;
 		prev_task = curr_thread.current_task;
 		curr_thread.current_task = p_task;
+		if (p_task->pending_notify_yield_over) {
+			curr_thread.yield_is_over = true;
+		}
 		task_mutex.unlock();
 	}
 #endif
@@ -491,7 +494,11 @@ void WorkerThreadPool::notify_yield_over(TaskID p_task_id) {
 		ERR_FAIL_MSG("Invalid Task ID.");
 	}
 	Task *task = *taskp;
-	if (task->completed) {
+	if (task->pool_thread_index == -1) { // Completed or not started yet.
+		if (!task->completed) {
+			// This avoids a race condition where a task is created and yield-over called before it's processed.
+			task->pending_notify_yield_over = true;
+		}
 		task_mutex.unlock();
 		return;
 	}

+ 4 - 1
core/object/worker_thread_pool.h

@@ -81,7 +81,8 @@ private:
 		void *native_func_userdata = nullptr;
 		String description;
 		Semaphore done_semaphore; // For user threads awaiting.
-		bool completed = false;
+		bool completed : 1;
+		bool pending_notify_yield_over : 1;
 		Group *group = nullptr;
 		SelfList<Task> task_elem;
 		uint32_t waiting_pool = 0;
@@ -92,6 +93,8 @@ private:
 
 		void free_template_userdata();
 		Task() :
+				completed(false),
+				pending_notify_yield_over(false),
 				task_elem(this) {}
 	};