summaryrefslogtreecommitdiffstats
path: root/sys/compat
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2009-10-27 10:42:24 +0000
committerkib <kib@FreeBSD.org>2009-10-27 10:42:24 +0000
commiteb4c68098b66d84de3abc7be00acfdc6d2f8f980 (patch)
tree5f94dc1615964e0cca1ac079c4b76e9157688e6a /sys/compat
parentfeb999713be0c5c7cf9239074dd5d49d5dff1fa0 (diff)
downloadFreeBSD-src-eb4c68098b66d84de3abc7be00acfdc6d2f8f980.zip
FreeBSD-src-eb4c68098b66d84de3abc7be00acfdc6d2f8f980.tar.gz
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
Diffstat (limited to 'sys/compat')
-rw-r--r--sys/compat/freebsd32/freebsd32_misc.c13
1 files changed, 1 insertions, 12 deletions
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 {
OpenPOWER on IntegriCloud