From 4090c458de8e2825528e4bad2e70cfa9b851cdc1 Mon Sep 17 00:00:00 2001 From: Mikael Simberg Date: Thu, 18 Jan 2024 14:48:32 +0100 Subject: [PATCH] Fix waiting in sync_wait Remove shortcut to check if lock can be avoided as it can lead to the shared state being freed before the notifying thread has released the lock. The following can happen with the shortcut: - thread 2 takes lock to notify condition variable - thread 2 sets set_called to true - thread 1 sees set_called == true - thread 1 skips the wait and returns from sync_wait, releasing the shared state - thread 2 releases the lock (with a write), which was stored in the shared state By keeping always taking the lock we guarantee that the notifying thread will always release the lock before the waiting thread returns from the wait. --- .../include/pika/execution/algorithms/sync_wait.hpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/libs/pika/execution/include/pika/execution/algorithms/sync_wait.hpp b/libs/pika/execution/include/pika/execution/algorithms/sync_wait.hpp index ca6b8198e..e87970404 100644 --- a/libs/pika/execution/include/pika/execution/algorithms/sync_wait.hpp +++ b/libs/pika/execution/include/pika/execution/algorithms/sync_wait.hpp @@ -140,11 +140,8 @@ namespace pika::sync_wait_detail { void wait() { - if (!set_called) - { - std::unique_lock l(mtx); - cond_var.wait(l, [&] { return set_called.load(); }); - } + std::unique_lock l(mtx); + cond_var.wait(l, [&] { return set_called.load(); }); } auto get_value()