From 8f9bdebd35ed269d305ccc9c0bd119f95ceaa585 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Mon, 21 Aug 2023 16:13:17 +0900 Subject: [PATCH] renderer task-scheduler: ++thread safety Currently, tasks are expected to be triggered from the main thread. This ensures preventing the popping of a thread from a worker thread. Previously, there was a potential deadlock problem... --- src/lib/tvgTaskScheduler.cpp | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/src/lib/tvgTaskScheduler.cpp b/src/lib/tvgTaskScheduler.cpp index 01946808..7c9b4ea1 100644 --- a/src/lib/tvgTaskScheduler.cpp +++ b/src/lib/tvgTaskScheduler.cpp @@ -106,9 +106,12 @@ struct TaskSchedulerImpl vector threads; vector taskQueues; atomic idx{0}; + thread::id tid; TaskSchedulerImpl(unsigned threadCnt) : threadCnt(threadCnt), taskQueues(threadCnt) { + tid = this_thread::get_id(); + for (unsigned i = 0; i < threadCnt; ++i) { threads.emplace_back([&, i] { run(i); }); } @@ -143,12 +146,23 @@ struct TaskSchedulerImpl { //Async if (threadCnt > 0) { - task->prepare(); - auto i = idx++; - for (unsigned n = 0; n < threadCnt; ++n) { - if (taskQueues[(i + n) % threadCnt].tryPush(task)) return; + auto tid = this_thread::get_id(); + if (tid == this->tid) { + task->prepare(); + auto i = idx++; + for (unsigned n = 0; n < threadCnt; ++n) { + if (taskQueues[(i + n) % threadCnt].tryPush(task)) return; + } + taskQueues[i % threadCnt].push(task); + //Not thread-safety now, it's requested from a worker-thread + } else { + for (unsigned i = 0; i < threadCnt; ++i) { + if (tid == threads[i].get_id()) { + task->prepare(); + (*task)(i + 1); + } + } } - taskQueues[i % threadCnt].push(task); //Sync } else { task->run(0);