|
@@ -186,26 +186,34 @@ void WorkerThreadPool::_thread_function(void *p_user) {
|
|
|
while (true) {
|
|
|
Task *task_to_process = nullptr;
|
|
|
{
|
|
|
+ // Create the lock outside the inner loop so it isn't needlessly unlocked and relocked
|
|
|
+ // when no task was found to process, and the loop is re-entered.
|
|
|
MutexLock lock(thread_data->pool->task_mutex);
|
|
|
|
|
|
- bool exit = thread_data->pool->_handle_runlevel(thread_data, lock);
|
|
|
- if (unlikely(exit)) {
|
|
|
- break;
|
|
|
- }
|
|
|
+ while (true) {
|
|
|
+ bool exit = thread_data->pool->_handle_runlevel(thread_data, lock);
|
|
|
+ if (unlikely(exit)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ thread_data->signaled = false;
|
|
|
|
|
|
- thread_data->signaled = false;
|
|
|
+ if (!thread_data->pool->task_queue.first()) {
|
|
|
+ // There wasn't a task available yet.
|
|
|
+ // Let's wait for the next notification, then recheck.
|
|
|
+ thread_data->cond_var.wait(lock);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
|
|
|
- if (thread_data->pool->task_queue.first()) {
|
|
|
+ // Got a task to process! Remove it from the queue, then break into the task handling section.
|
|
|
task_to_process = thread_data->pool->task_queue.first()->self();
|
|
|
thread_data->pool->task_queue.remove(thread_data->pool->task_queue.first());
|
|
|
- } else {
|
|
|
- thread_data->cond_var.wait(lock);
|
|
|
+ break;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if (task_to_process) {
|
|
|
- thread_data->pool->_process_task(task_to_process);
|
|
|
- }
|
|
|
+ DEV_ASSERT(task_to_process);
|
|
|
+ thread_data->pool->_process_task(task_to_process);
|
|
|
}
|
|
|
}
|
|
|
|