From eb4c68098b66d84de3abc7be00acfdc6d2f8f980 Mon Sep 17 00:00:00 2001 From: kib Date: Tue, 27 Oct 2009 10:42:24 +0000 Subject: In kern_sigsuspend(), better manipulate thread signal mask using kern_sigprocmask() to properly notify other possible candidate threads for signal delivery. Since sigsuspend() shall only return to usermode after a signal was delivered, do cursig/postsig loop immediately after waiting for signal, repeating the wait if wakeup was spurious due to race with other thread fetching signal from the process queue before us. Add thread_suspend_check() call to allow the thread to be stopped or killed while in loop. Modify last argument of kern_sigprocmask() from boolean to flags, allowing the function to be called with locked proc. Convertion of the callers that supplied 1 to the old argument will be done in the next commit, and due to SIGPROCMASK_OLD value equial to 1, code is formally correct in between. Reviewed by: davidxu Tested by: pho MFC after: 1 month --- sys/compat/freebsd32/freebsd32_misc.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) (limited to 'sys/compat') diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c index 71b22aa..9f6b16d 100644 --- a/sys/compat/freebsd32/freebsd32_misc.c +++ b/sys/compat/freebsd32/freebsd32_misc.c @@ -2579,21 +2579,10 @@ int ofreebsd32_sigsuspend(struct thread *td, struct ofreebsd32_sigsuspend_args *uap) { - struct proc *p = td->td_proc; sigset_t mask; - PROC_LOCK(p); - td->td_oldsigmask = td->td_sigmask; - td->td_pflags |= TDP_OLDMASK; OSIG2SIG(uap->mask, mask); - SIG_CANTMASK(mask); - SIGSETLO(td->td_sigmask, mask); - signotify(td); - while (msleep(&p->p_sigacts, &p->p_mtx, PPAUSE|PCATCH, "opause", 0) == 0) - /* void */; - PROC_UNLOCK(p); - /* always return EINTR rather than ERESTART... */ - return (EINTR); + return (kern_sigsuspend(td, mask)); } struct sigstack32 { -- cgit v1.1