about summary refs log tree commit diff
path: root/sysdeps/nptl
diff options
context:
space:
mode:
authorLucas A. M. Magalhaes <lamm@linux.ibm.com>2020-12-01 18:05:07 -0300
committerTulio Magno Quites Machado Filho <tuliom@linux.ibm.com>2020-12-01 18:26:26 -0300
commit61855081017dff30c577855cda882740356b5d98 (patch)
tree69472c92f3f8b65c240b5987bbeee2760108933b /sysdeps/nptl
parent33fc34521de970153344cfe1bfa9ce6da7a6efea (diff)
downloadglibc-61855081017dff30c577855cda882740356b5d98.tar.gz
glibc-61855081017dff30c577855cda882740356b5d98.tar.xz
glibc-61855081017dff30c577855cda882740356b5d98.zip
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  <adhemerval.zanella@linaro.org>
Diffstat (limited to 'sysdeps/nptl')
-rw-r--r--sysdeps/nptl/futex-internal.h7
1 files changed, 3 insertions, 4 deletions
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 */