diff --git a/src/Nazara/Core/TaskScheduler.cpp b/src/Nazara/Core/TaskScheduler.cpp index 0e8fcf0a0..87df7af77 100644 --- a/src/Nazara/Core/TaskScheduler.cpp +++ b/src/Nazara/Core/TaskScheduler.cpp @@ -60,10 +60,7 @@ namespace Nz NAZARA_UNREACHABLE(); } - ~Worker() - { - m_thread.join(); - } + ~Worker() = default; // WaitForExit has to be called before destroying worker void AddTask(TaskScheduler::Task&& task) { @@ -125,7 +122,7 @@ namespace Nz } } - void Shutdown() + void RequestShutdown() { m_running = false; if (!m_notifier.test_and_set()) @@ -139,6 +136,11 @@ namespace Nz return task; } + void WaitForExit() + { + m_thread.join(); + } + void WakeUp() { if (!m_notifier.test_and_set()) @@ -184,10 +186,11 @@ namespace Nz { // Wake up workers and tell them to exit for (Worker& worker : m_data->workers) - worker.Shutdown(); + worker.RequestShutdown(); - // wait for them to have exited - m_data->workers.clear(); + // 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) + for (Worker& worker : m_data->workers) + worker.WaitForExit(); } void TaskScheduler::AddTask(Task&& task)