From 856564759b8308cc4d8b7c7ad0765545454d8683 Mon Sep 17 00:00:00 2001 From: squidbus <175574877+squidbus@users.noreply.github.com> Date: Thu, 28 Nov 2024 19:27:29 -0800 Subject: [PATCH] semaphore: Use separate signaled flag to prevent races --- src/core/libraries/kernel/threads/semaphore.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/core/libraries/kernel/threads/semaphore.cpp b/src/core/libraries/kernel/threads/semaphore.cpp index 177dc4a8c..db14c298c 100644 --- a/src/core/libraries/kernel/threads/semaphore.cpp +++ b/src/core/libraries/kernel/threads/semaphore.cpp @@ -72,6 +72,7 @@ public: } it = wait_list.erase(it); token_count -= waiter->need_count; + waiter->was_signaled = true; waiter->cv.notify_one(); } @@ -106,6 +107,7 @@ public: std::condition_variable cv; u32 priority; s32 need_count; + bool was_signaled{}; bool was_deleted{}; bool was_cancled{}; @@ -137,16 +139,17 @@ public: } // Wait until timeout runs out, recording how much remaining time there was. const auto start = std::chrono::high_resolution_clock::now(); - const auto status = cv.wait_for(lk, std::chrono::microseconds(*timeout)); + const auto signaled = cv.wait_for(lk, std::chrono::microseconds(*timeout), + [this] { return was_signaled; }); const auto end = std::chrono::high_resolution_clock::now(); const auto time = std::chrono::duration_cast(end - start).count(); - if (status == std::cv_status::timeout) { - *timeout = 0; - } else { + if (signaled) { *timeout -= time; + } else { + *timeout = 0; } - return GetResult(status == std::cv_status::timeout); + return GetResult(!signaled); } };