Core/TaskScheduler: Fix shutdown data-race

This commit is contained in:
SirLynix 2024-02-06 13:27:39 +01:00
parent 17b6449472
commit 99952db736
1 changed files with 11 additions and 8 deletions

View File

@ -60,10 +60,7 @@ namespace Nz
NAZARA_UNREACHABLE(); NAZARA_UNREACHABLE();
} }
~Worker() ~Worker() = default; // WaitForExit has to be called before destroying worker
{
m_thread.join();
}
void AddTask(TaskScheduler::Task&& task) void AddTask(TaskScheduler::Task&& task)
{ {
@ -125,7 +122,7 @@ namespace Nz
} }
} }
void Shutdown() void RequestShutdown()
{ {
m_running = false; m_running = false;
if (!m_notifier.test_and_set()) if (!m_notifier.test_and_set())
@ -139,6 +136,11 @@ namespace Nz
return task; return task;
} }
void WaitForExit()
{
m_thread.join();
}
void WakeUp() void WakeUp()
{ {
if (!m_notifier.test_and_set()) if (!m_notifier.test_and_set())
@ -184,10 +186,11 @@ namespace Nz
{ {
// Wake up workers and tell them to exit // Wake up workers and tell them to exit
for (Worker& worker : m_data->workers) for (Worker& worker : m_data->workers)
worker.Shutdown(); worker.RequestShutdown();
// wait for them to have exited // Wait until all threads exited before deleting workers (to avoid data-race where a worker could be freed while another tries to steal their task)
m_data->workers.clear(); for (Worker& worker : m_data->workers)
worker.WaitForExit();
} }
void TaskScheduler::AddTask(Task&& task) void TaskScheduler::AddTask(Task&& task)