[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