Skip to content

Commit c0a31d2

Browse files
ThreadPool: allow task rescheduling by returning the NOT_STARTED status from the Run() method
1 parent 337019e commit c0a31d2

File tree

2 files changed

+11
-7
lines changed

2 files changed

+11
-7
lines changed

Common/interface/ThreadPool.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,9 @@ DILIGENT_BEGIN_INTERFACE(IAsyncTask, IObject)
7878
///
7979
/// Before returning from the function, the task implementation must
8080
/// set the task status to either ASYNC_TASK_STATUS_CANCELLED or
81-
/// ASYNC_TASK_STATUS_COMPLETE.
81+
/// ASYNC_TASK_STATUS_COMPLETE to indicate that the task is finished,
82+
/// or to ASYNC_TASK_STATUS_NOT_STARTED to request the task to be
83+
/// rescheduled.
8284
VIRTUAL void METHOD(Run)(THIS_
8385
Uint32 ThreadId) PURE;
8486

Common/src/ThreadPool.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -125,21 +125,22 @@ class ThreadPoolImpl final : public ObjectBase<IThreadPool>
125125
}
126126
}
127127

128+
bool TaskFinished = false;
128129
if (PrerequisitesMet)
129130
{
130131
TaskInfo.pTask->SetStatus(ASYNC_TASK_STATUS_RUNNING);
131132
TaskInfo.pTask->Run(ThreadId);
132-
DEV_CHECK_ERR((TaskInfo.pTask->GetStatus() == ASYNC_TASK_STATUS_COMPLETE ||
133-
TaskInfo.pTask->GetStatus() == ASYNC_TASK_STATUS_CANCELLED),
134-
"Finished tasks must be in COMPLETE or CANCELLED state");
133+
TaskFinished = TaskInfo.pTask->IsFinished();
134+
DEV_CHECK_ERR((TaskFinished || TaskInfo.pTask->GetStatus() == ASYNC_TASK_STATUS_NOT_STARTED),
135+
"Finished tasks must be in COMPLETE, CANCELLED or NOT_STARTED state");
135136
}
136137

137138
{
138139
std::unique_lock<std::mutex> lock{m_TasksQueueMtx};
139140

140141
const auto NumRunningTasks = m_NumRunningTasks.fetch_add(-1) - 1;
141142

142-
if (PrerequisitesMet)
143+
if (TaskFinished)
143144
{
144145
if (m_TasksQueue.empty() && NumRunningTasks == 0)
145146
{
@@ -148,14 +149,15 @@ class ThreadPoolImpl final : public ObjectBase<IThreadPool>
148149
}
149150
else
150151
{
151-
// If prerequisites are not met, re-enqueue the task with the minimum prerequisite priority
152+
// If prerequisites are not met or the task requested to be re-run,
153+
// re-enqueue the task with the minimum prerequisite priority
152154
if (TaskInfo.pTask->GetPriority() > MinPrereqPriority)
153155
TaskInfo.pTask->SetPriority(MinPrereqPriority);
154156
m_TasksQueue.emplace(TaskInfo.pTask->GetPriority(), std::move(TaskInfo));
155157
}
156158
}
157159

158-
if (!PrerequisitesMet)
160+
if (!TaskFinished)
159161
{
160162
m_NextTaskCond.notify_one();
161163
}

0 commit comments

Comments
 (0)