From 816abf54fbbb02923331b69b62333b8a0edb4181 Mon Sep 17 00:00:00 2001 From: Markus Wichmann Date: Thu, 6 Dec 2018 18:30:26 +0100 Subject: [PATCH 3/3] Add workaround for old linux bug. --- src/internal/libc.h | 4 +--- src/signal/sigaction.c | 2 ++ src/thread/sem_timedwait.c | 5 ++++- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/internal/libc.h b/src/internal/libc.h index ac97dc7e..2e6737d9 100644 --- a/src/internal/libc.h +++ b/src/internal/libc.h @@ -18,9 +18,7 @@ struct tls_module { }; struct __libc { - int can_do_threads; - int threaded; - int secure; + unsigned can_do_threads:1, threaded:1, secure:1, handling_sigs:1; volatile int threads_minus_1; size_t *auxv; struct tls_module *tls_head; diff --git a/src/signal/sigaction.c b/src/signal/sigaction.c index af47195e..5f02b99b 100644 --- a/src/signal/sigaction.c +++ b/src/signal/sigaction.c @@ -43,6 +43,8 @@ int __libc_sigaction(int sig, const struct sigaction *restrict sa, struct sigact SIGPT_SET, 0, _NSIG/8); unmask_done = 1; } + if (!(sa->sa_flags & SA_RESTART)) + libc.handling_sigs = 1; } /* Changing the disposition of SIGABRT to anything but * SIG_DFL requires a lock, so that it cannot be changed diff --git a/src/thread/sem_timedwait.c b/src/thread/sem_timedwait.c index 8132eb1b..e76ae9de 100644 --- a/src/thread/sem_timedwait.c +++ b/src/thread/sem_timedwait.c @@ -22,7 +22,10 @@ int sem_timedwait(sem_t *restrict sem, const struct timespec *restrict at) pthread_cleanup_push(cleanup, (void *)(sem->__val+1)); r = __timedwait_cp(sem->__val, -1, CLOCK_REALTIME, at, sem->__val[2]); pthread_cleanup_pop(1); - if (r && r != EINTR) { + /* Linux pre-2.6.22 bug: Sometimes SYS_futex returns with EINTR when it should not. + * Workaround: Retry on EINTR unless someone installed handlers before. + */ + if (r && (r != EINTR || libc.handling_sigs)) { errno = r; return -1; } -- 2.19.1