Reference safety for Worker after callbacks

Joining a WorkRequest now ensures that either the after callback has
already been executed, or will never be executed.

Fixes #1438
This commit is contained in:
John Firebaugh
2015-05-06 13:19:00 -07:00
parent 6c31d928e1
commit 5b4015ccba
6 changed files with 96 additions and 10 deletions

View File

@@ -27,10 +27,17 @@ WorkRequest Worker::send(Fn work, Fn after) {
std::packaged_task<void ()> task(work);
std::future<void> future = task.get_future();
threads[current]->invokeWithResult(&Worker::Impl::doWork, std::move(after), task);
std::shared_ptr<std::atomic<bool>> joined = std::make_shared<std::atomic<bool>>();
*joined = false;
threads[current]->invokeWithResult(&Worker::Impl::doWork, [joined, after] {
if (!*joined) {
after();
}
}, task);
current = (current + 1) % threads.size();
return WorkRequest(std::move(future));
return WorkRequest(std::move(future), joined);
}
}