On Mon, Oct 27, 2025 at 10:29 PM Jonathan Wakely <[email protected]> wrote:
> The test_shared_relative function deadlocks on older Glibc versions that > don't have pthread_rwlock_clockrdlock, because (as already mentioned > earlier in the test file) pthread_rwlock_timedrdlock returns EDEADLK if > the thread that already holds a write lock attempts to acquire read > lock, causing std::shared_timed_mutex to loop forever. > > The fix is to do the invalid try_lock_shared_for call on a different > thread. > > Also add missing -pthread for PR122401. > > libstdc++-v3/ChangeLog: > > PR libstdc++/122401 > * testsuite/30_threads/shared_timed_mutex/try_lock_until/116586.cc: > Do not call try_lock_shared_for from the thread that already > holds the exclusive lock. Add -pthread for et pthread. > --- > > Tested x86_64-linux (Glibc 2.41) and aarch64-linux (Glibc 2.28). > LGTM. This is problem in test, as https://eel.is/c++draft/thread.sharedmutex.class#3.2, says that attempting to lock already locked, which try_lock is doing, is UB. > > .../shared_timed_mutex/try_lock_until/116586.cc | 12 +++++++++++- > 1 file changed, 11 insertions(+), 1 deletion(-) > > diff --git > a/libstdc++-v3/testsuite/30_threads/shared_timed_mutex/try_lock_until/116586.cc > b/libstdc++-v3/testsuite/30_threads/shared_timed_mutex/try_lock_until/116586.cc > index cebbb3a258d9..aae85487a692 100644 > --- > a/libstdc++-v3/testsuite/30_threads/shared_timed_mutex/try_lock_until/116586.cc > +++ > b/libstdc++-v3/testsuite/30_threads/shared_timed_mutex/try_lock_until/116586.cc > @@ -1,4 +1,7 @@ > // { dg-do run { target c++14 } } > +// { dg-additional-options "-pthread" { target pthread } } > +// { dg-require-gthreads "" } > +// { dg-require-effective-target hosted } > > #include <shared_mutex> > #include <chrono> > @@ -66,7 +69,14 @@ test_shared_relative(chrono::nanoseconds offset) > stm.unlock_shared(); > // Should complete immediately > VERIFY(stm.try_lock_for(chrono::seconds{10})); > - VERIFY(!stm.try_lock_shared_for(d)); > + { > + // NPTL will give us EDEADLK if pthread_rwlock_timedrdlock() is > called on > + // the same thread that already holds the exclusive (write) lock, so > let's > + // arrange for a different thread to try to acquire the shared lock. > + auto t = std::async(std::launch::async, [&stm, d]() { > + VERIFY(!stm.try_lock_shared_for(d)); > + }); > + } > } > > int main() > -- > 2.51.0 > >
