[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 11:02:35 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.
Ah I think the callback is taking the internal lock.
https://github.com/llvm/llvm-project/pull/77099
More information about the libcxx-commits
mailing list