aboutsummaryrefslogtreecommitdiff
path: root/sys/kern
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2017-05-12 15:34:59 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2017-05-12 15:34:59 +0000
commit396a0d4455e4d5438eb1d309a118aa85a1f8e647 (patch)
tree447487a2f4a3d7dada77f554e4807a24a1f27a87 /sys/kern
parent342b8b88ba0766330012185207b57cfded73abc9 (diff)
downloadsrc-396a0d4455e4d5438eb1d309a118aa85a1f8e647.tar.gz
src-396a0d4455e4d5438eb1d309a118aa85a1f8e647.zip
Do not wake up sleeping thread in reschedule_signals() if the signal
is blocked. The spurious wakeup might result in spurious EINTR. The reschedule_signals() function is called when the calling thread has the signal mask changed. For each newly blocked signal, we try to find a thread which might have the signal not blocked. If no such thread exists, sigtd() returns random thread, which must not be waken up. I decided that re-checking, as suggested by PR submitter, is more reasonable change than to change sigtd() interface, due to other uses of sigtd(). signotify() already performs this check. Submitted by: Duane <parakleta@darkreality.org> PR: 219228 Sponsored by: The FreeBSD Foundation MFC after: 1 week
Notes
Notes: svn path=/head/; revision=318243
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/kern_sig.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
index 5dfba379e19d..d2596985090e 100644
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -2646,7 +2646,9 @@ reschedule_signals(struct proc *p, sigset_t block, int flags)
signotify(td);
if (!(flags & SIGPROCMASK_PS_LOCKED))
mtx_lock(&ps->ps_mtx);
- if (p->p_flag & P_TRACED || SIGISMEMBER(ps->ps_sigcatch, sig))
+ if (p->p_flag & P_TRACED ||
+ (SIGISMEMBER(ps->ps_sigcatch, sig) &&
+ !SIGISMEMBER(td->td_sigmask, sig)))
tdsigwakeup(td, sig, SIG_CATCH,
(SIGISMEMBER(ps->ps_sigintr, sig) ? EINTR :
ERESTART));