Pārlūkot izejas kodu

Merge pull request #11433 from liamwhite/shutdown-oopsie

polyfill_thread: ensure mutex was locked before signaling stop
liamwhite 2 gadi atpakaļ
vecāks
revīzija
b5f99164f1
1 mainītis faili ar 13 papildinājumiem un 7 dzēšanām
  1. 13 7
      src/common/polyfill_thread.h

+ 13 - 7
src/common/polyfill_thread.h

@@ -19,8 +19,8 @@
 namespace Common {
 
 template <typename Condvar, typename Lock, typename Pred>
-void CondvarWait(Condvar& cv, Lock& lock, std::stop_token token, Pred&& pred) {
-    cv.wait(lock, token, std::move(pred));
+void CondvarWait(Condvar& cv, std::unique_lock<Lock>& lk, std::stop_token token, Pred&& pred) {
+    cv.wait(lk, token, std::move(pred));
 }
 
 template <typename Rep, typename Period>
@@ -332,13 +332,17 @@ private:
 namespace Common {
 
 template <typename Condvar, typename Lock, typename Pred>
-void CondvarWait(Condvar& cv, Lock& lock, std::stop_token token, Pred pred) {
+void CondvarWait(Condvar& cv, std::unique_lock<Lock>& lk, std::stop_token token, Pred pred) {
     if (token.stop_requested()) {
         return;
     }
 
-    std::stop_callback callback(token, [&] { cv.notify_all(); });
-    cv.wait(lock, [&] { return pred() || token.stop_requested(); });
+    std::stop_callback callback(token, [&] {
+        { std::scoped_lock lk2{*lk.mutex()}; }
+        cv.notify_all();
+    });
+
+    cv.wait(lk, [&] { return pred() || token.stop_requested(); });
 }
 
 template <typename Rep, typename Period>
@@ -353,8 +357,10 @@ bool StoppableTimedWait(std::stop_token token, const std::chrono::duration<Rep,
 
     std::stop_callback cb(token, [&] {
         // Wake up the waiting thread.
-        std::unique_lock lk{m};
-        stop_requested = true;
+        {
+            std::scoped_lock lk{m};
+            stop_requested = true;
+        }
         cv.notify_one();
     });