From 8b0e795aaa445e9167aa07b282c5720b35342c07 Mon Sep 17 00:00:00 2001 From: Adhemerval Zanella Date: Wed, 1 Nov 2017 11:49:05 -0200 Subject: Simplify Linux sig{timed}wait{info} implementations This patch simplifies sig{timed}wait{info} by: - Assuming __NR_rt_sigtimedwait existence on all architectures due minimum kernel version requirement (it pre-dates Linux git inclusion for Linux 2.6.12). - Call __sigtimedwait on both sigwait and sigwaitinfo. - Now that sigwait is based on an internal sigtimedwait call and it is present of both libc.so and libpthread.so we need to add an external private definition of __sigtimedwait for libpthread.so call. Checked on x86_64-linux-gnu. * sysdeps/unix/sysv/linux/Versions (libc) [GLIBC_PRIVATE]: Add __sigtimedwait. * sysdeps/unix/sysv/linux/sigtimedwait.c: Simplify includes and assume __NR_rt_sigtimedwait. * sysdeps/unix/sysv/linux/sigwait.c (__sigwait): Call __sigtimedwait and add LIBC_CANCEL_HANDLED for cancellation marking. * sysdeps/unix/sysv/linux/sigwaitinfo.c (__sigwaitinfo): Likewise. Signed-off-by: Adhemerval Zanella Reviewed-by: Zack Weinberg --- sysdeps/unix/sysv/linux/sigwait.c | 81 ++++----------------------------------- 1 file changed, 8 insertions(+), 73 deletions(-) (limited to 'sysdeps/unix/sysv/linux/sigwait.c') diff --git a/sysdeps/unix/sysv/linux/sigwait.c b/sysdeps/unix/sysv/linux/sigwait.c index 395bd9feb6..e6fb32a610 100644 --- a/sysdeps/unix/sysv/linux/sigwait.c +++ b/sysdeps/unix/sysv/linux/sigwait.c @@ -15,86 +15,21 @@ License along with the GNU C Library; if not, see . */ -#include #include -#define __need_NULL -#include -#include - -#include #include -#include - -#ifdef __NR_rt_sigtimedwait - -/* Return any pending signal or wait for one for the given time. */ -static int -do_sigwait (const sigset_t *set, int *sig) -{ - int ret; - - sigset_t tmpset; - if (set != NULL - && (__builtin_expect (__sigismember (set, SIGCANCEL), 0) - || __builtin_expect (__sigismember (set, SIGSETXID), 0))) - { - /* Create a temporary mask without the bit for SIGCANCEL set. */ - // We are not copying more than we have to. - memcpy (&tmpset, set, _NSIG / 8); - __sigdelset (&tmpset, SIGCANCEL); - __sigdelset (&tmpset, SIGSETXID); - set = &tmpset; - } - - /* XXX The size argument hopefully will have to be changed to the - real size of the user-level sigset_t. */ -#ifdef INTERNAL_SYSCALL - INTERNAL_SYSCALL_DECL (err); - do - ret = INTERNAL_SYSCALL (rt_sigtimedwait, err, 4, set, - NULL, NULL, _NSIG / 8); - while (INTERNAL_SYSCALL_ERROR_P (ret, err) - && INTERNAL_SYSCALL_ERRNO (ret, err) == EINTR); - if (! INTERNAL_SYSCALL_ERROR_P (ret, err)) - { - *sig = ret; - ret = 0; - } - else - ret = INTERNAL_SYSCALL_ERRNO (ret, err); -#else - do - ret = INLINE_SYSCALL (rt_sigtimedwait, 4, set, NULL, NULL, _NSIG / 8); - while (ret == -1 && errno == EINTR); - if (ret != -1) - { - *sig = ret; - ret = 0; - } - else - ret = errno; -#endif - - return ret; -} int __sigwait (const sigset_t *set, int *sig) { - if (SINGLE_THREAD_P) - return do_sigwait (set, sig); - - int oldtype = LIBC_CANCEL_ASYNC (); - - int result = do_sigwait (set, sig); - - LIBC_CANCEL_RESET (oldtype); - - return result; + siginfo_t si; + if (__sigtimedwait (set, &si, 0) < 0) + return -1; + *sig = si.si_signo; + return 0; } libc_hidden_def (__sigwait) weak_alias (__sigwait, sigwait) -#else -# include -#endif strong_alias (__sigwait, __libc_sigwait) + +/* __sigtimedwait handles cancellation. */ +LIBC_CANCEL_HANDLED (); -- cgit 1.4.1