[libcxx-commits] [libcxx] [libc++] fix condition_variable_any hangs on stop_request (PR #77127)
Louis Dionne via libcxx-commits
libcxx-commits at lists.llvm.org
Fri Jan 12 09:22:33 PST 2024
================
@@ -155,6 +155,54 @@ void test() {
assert(lock.owns_lock());
}
+ // #76807 Hangs in std::condition_variable_any when used with std::stop_token
+ {
+ class MyThread {
+ public:
+ MyThread() {
+ thread_ = support::make_test_jthread([this](std::stop_token st) {
+ while (!st.stop_requested()) {
+ std::unique_lock lock{m_};
+ cv_.wait_for(lock, st, 1h, [] { return false; });
+ }
+ });
+ }
+
+ private:
+ std::mutex m_;
+ std::condition_variable_any cv_;
+ std::jthread thread_;
+ };
+
+ [[maybe_unused]] MyThread my_thread;
+ }
+
+ // request_stop potentially in-between check and wait
+ {
+ std::stop_source ss;
+ std::condition_variable_any cv;
+ Mutex mutex;
+ Lock lock{mutex};
+
+ std::atomic_bool pred_started = false;
+ std::atomic_bool request_stop_called = false;
+ auto thread = support::make_test_thread([&]() {
+ pred_started.wait(false);
+ ss.request_stop();
+ request_stop_called.store(true);
+ });
+
+ std::same_as<bool> auto r = cv.wait_for(lock, ss.get_token(), 1h, [&]() {
+ pred_started.store(true);
+ request_stop_called.wait(false);
+ return false;
+ });
+ assert(!r);
----------------
ldionne wrote:
Does this test fail if we don't get the desired interleaving within 1h?
One way to make this work could be to measure the time it took for you to run the test, and actually give yourself e.g. 45 minutes of allowed time. If you notice that you're still waiting after 45 minutes, you can fail the test -- that way you know you'll never exit via the timeout in the condition variable.
https://github.com/llvm/llvm-project/pull/77127
More information about the libcxx-commits
mailing list