From b72b0b14d0da0b506fbddf755cc8c7d0cd813287 Mon Sep 17 00:00:00 2001 From: "Peter S. Mazinger" Date: Fri, 22 Apr 2011 00:33:48 +0200 Subject: rework cancellation for sigwait, sigtimedwait and sigwaitinfo sigtimedwait: - provide __sigtimedwait_nocancel - use __SYSCALL_SIGSET_T_SIZE instead of _NSIG / 8 - do not provide __sigtimedwait - guard a section to avoid failure on archs if SI_TKILL/SI_USER are not defined sigwaitinfo: - simply use sigtimedwait since that handles cancellation already sigwait: - use non-cancellable functions (sigtimedwait, sigsuspend) - get rid of code already done in __sigtimedwait_nocancel Signed-off-by: Peter S. Mazinger Signed-off-by: Bernhard Reutner-Fischer --- libc/signal/sigwait.c | 91 ++++++++++----------------------------------------- 1 file changed, 18 insertions(+), 73 deletions(-) (limited to 'libc/signal') diff --git a/libc/signal/sigwait.c b/libc/signal/sigwait.c index 5e9c4275f..7d47f99de 100644 --- a/libc/signal/sigwait.c +++ b/libc/signal/sigwait.c @@ -21,92 +21,36 @@ #define __need_NULL #include +#include #include +#include -#ifdef __UCLIBC_HAS_THREADS_NATIVE__ -# include +#if defined __NR_rt_sigtimedwait && defined __UCLIBC_HAS_REALTIME__ -# ifdef __NR_rt_sigtimedwait -# include +#include /* Return any pending signal or wait for one for the given time. */ -static int do_sigwait(const sigset_t *set, int *sig) +static int __NC(sigwait)(const sigset_t *set, int *sig) { int ret; -# ifdef SIGCANCEL - sigset_t tmpset; - if (set != NULL - && (__builtin_expect (__sigismember (set, SIGCANCEL), 0) -# ifdef SIGSETXID - || __builtin_expect (__sigismember (set, SIGSETXID), 0) -# endif - )) - { - /* 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); -# ifdef SIGSETXID - __sigdelset(&tmpset, SIGSETXID); -# endif - set = &tmpset; - } -# endif - - /* XXX The size argument hopefully will have to be changed to the - real size of the user-level sigset_t. */ - 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)) - { + /* we might as well use sigtimedwait and do not care about cancellation */ + ret = __NC(sigtimedwait)(set, NULL, NULL); + while (ret == -1 && errno == EINTR); + if (ret != -1) { *sig = ret; ret = 0; - } -else - ret = INTERNAL_SYSCALL_ERRNO (ret, err); + } else + ret = errno; 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; -} -# else /* __NR_rt_sigtimedwait */ -# error We must have rt_sigtimedwait defined!!! -# endif -#else /* __UCLIBC_HAS_THREADS_NATIVE__ */ +#else /* __NR_rt_sigtimedwait */ -# if defined __UCLIBC_HAS_REALTIME__ - -int sigwait (const sigset_t *set, int *sig) -{ - int ret = 1; - if ((ret = __sigwaitinfo(set, NULL)) != -1) { - *sig = ret; - return 0; - } - return 1; -} - -# else /* __UCLIBC_HAS_REALTIME__ */ -# include -# include /* smallint */ /* variant without REALTIME extensions */ +#include /* smallint */ static smallint was_sig; /* obviously not thread-safe */ @@ -115,7 +59,7 @@ static void ignore_signal(int sig) was_sig = sig; } -int sigwait (const sigset_t *set, int *sig) +static int __NC(sigwait)(const sigset_t *set, int *sig) { sigset_t tmp_mask; struct sigaction saved[NSIG]; @@ -149,7 +93,7 @@ int sigwait (const sigset_t *set, int *sig) } /* Now we can wait for signals. */ - sigsuspend (&tmp_mask); + __NC(sigsuspend)(&tmp_mask); restore_handler: save_errno = errno; @@ -165,5 +109,6 @@ int sigwait (const sigset_t *set, int *sig) *sig = was_sig; return was_sig == -1 ? -1 : 0; } -# endif /* __UCLIBC_HAS_REALTIME__ */ -#endif /* __UCLIBC_HAS_THREADS_NATIVE__ */ +#endif /* __NR_rt_sigtimedwait */ + +CANCELLABLE_SYSCALL(int, sigwait, (const sigset_t *set, int *sig), (set, sig)) -- cgit v1.2.3