[libcxx-commits] [libcxx] [libc++] std::condition_variable_any overloads accepting std::stop_token don't register for stop callbacks (PR #77099)

via libcxx-commits libcxx-commits at lists.llvm.org
Sat Jan 6 10:47:10 PST 2024


huixie90 wrote:

> Hi @huixie90,
> 
> Thank you for taking the time to reply!
> 
> > It is almost the same except that my patch does not take the internal lock when checks stop requested and only takes the lock before unlock the user lock and wait.
> 
> I think the change to whether or not the internal lock, or the user lock is held is also important to avoid hangs. I think if we only hold the user's lock, there is a window where `request_stop` can be called between us checking `stop_requested` but before entering the wait. e.g. with the changes from #77127 if I update the new test case in `wait_for_token_pred.pass.cpp` and force it to run many times in a loop like this, then the unit tests hang in my environment:
> 
> ```
>   for (int i = 0; i < 50000; ++i)
>   {
>     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;
>   }
> ```
> 
> If I change the `condition_variable` header back to using my changes, the unit tests can run with this tight loop.

why does taking the internal lock help with the window between stop_requested and waiting? The caller of request_stop won’t take the internal lock. So it can still happen in between checking stop_requested and entering the wait. 

https://github.com/llvm/llvm-project/pull/77099


More information about the libcxx-commits mailing list