From 61855081017dff30c577855cda882740356b5d98 Mon Sep 17 00:00:00 2001 From: "Lucas A. M. Magalhaes" Date: Tue, 1 Dec 2020 18:05:07 -0300 Subject: nptl: Fix __futex_clocklock64 return error check [BZ #26964] The earlier implementation of this, __lll_clocklock, calls lll_clockwait that doesn't return the futex syscall error codes. It always tries again if that fails. However in the current implementation, when the futex returns EAGAIN, __futex_clocklock64 will also return EGAIN, even if the futex is taken. This patch fixes the EAGAIN issue and also adds a check for EINTR. As futex syscall can return EINTR if the thread is interrupted by a signal. In this case I'm assuming the function should continue trying to lock as there is no mention to about it on POSIX. Also add a test for both scenarios. Reviewed-by: Adhemerval Zanella --- sysdeps/nptl/futex-internal.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'sysdeps/nptl') diff --git a/sysdeps/nptl/futex-internal.h b/sysdeps/nptl/futex-internal.h index 1640da0ce8..9974477c48 100644 --- a/sysdeps/nptl/futex-internal.h +++ b/sysdeps/nptl/futex-internal.h @@ -420,19 +420,18 @@ static __always_inline int __futex_clocklock64 (int *futex, clockid_t clockid, const struct __timespec64 *abstime, int private) { - int err = 0; - if (__glibc_unlikely (atomic_compare_and_exchange_bool_acq (futex, 1, 0))) { while (atomic_exchange_acq (futex, 2) != 0) { + int err = 0; err = __futex_abstimed_wait64 ((unsigned int *) futex, 2, clockid, abstime, private); if (err == EINVAL || err == ETIMEDOUT || err == EOVERFLOW) - break; + return err; } } - return err; + return 0; } #endif /* futex-internal.h */ -- cgit 1.4.1