Core/TaskScheduler: Fix shutdown data-race
This commit is contained in:
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user