On Tue, 28 Oct 2025, 08:28 Tomasz Kaminski, <[email protected]> wrote:
> > > 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. > Yes, it happens to work with our implementation when using a recent glibc release with pthread_rwlock_clockrdlock, but we shouldn't rely on that. >> .../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 >> >>
