[PATCH] libstdc++: Fix deadlock in shared_timed_mutex test [PR122401]
Tomasz Kaminski
tkaminsk@redhat.com
Tue Oct 28 08:25:28 GMT 2025
On Mon, Oct 27, 2025 at 10:29 PM Jonathan Wakely <jwakely@redhat.com> 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
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://gcc.gnu.org/pipermail/libstdc++/attachments/20251028/912e91b6/attachment-0001.htm>
More information about the Libstdc++
mailing list