diff --git a/emper/Runtime.cpp b/emper/Runtime.cpp index e4b189749222f0913beda1faf4059a5c1e805074..ef67ae27031788018398dd3ac850d6543b5c9d31 100644 --- a/emper/Runtime.cpp +++ b/emper/Runtime.cpp @@ -67,6 +67,7 @@ using emper::io::IoContext; Runtime::Runtime(workerid_t workerCount, RuntimeStrategyFactory& strategyFactory, unsigned int seed) : workerCount(workerCount), workerLatch(workerCount), + workerThreadExitLatch(workerCount), strategy(strategyFactory.constructRuntimeStrategy(*this)), scheduler(strategy->getScheduler()), dispatcher(strategy->getDispatcher()), @@ -229,6 +230,12 @@ auto Runtime::workerLoop(Worker* worker) -> void* { // Threads return here if Context::switchToOriginalStack() is called. + // Ensure that all worker threads exit "at the same" time. Otherwise + // it would be possible that one thread is work-stealing, + // potentially accessing a work stealing queue of an worker thread + // that already exited, causing an invalid access. + workerThreadExitLatch.count_down_and_wait(); + return nullptr; } diff --git a/emper/Runtime.hpp b/emper/Runtime.hpp index 24a8c52adc5126119cba00adf683a926f12e862e..621eda413c7a46cd1121d1845b6e25646b873ecf 100644 --- a/emper/Runtime.hpp +++ b/emper/Runtime.hpp @@ -51,6 +51,7 @@ class Runtime : public Logger<LogSubsystem::RUNTI> { std::vector<std::function<void(workerid_t)>> newWorkerHooks; Latch workerLatch; + Latch workerThreadExitLatch; RuntimeStrategy* const strategy; Scheduler& scheduler;