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
>>
>>

Reply via email to