summaryrefslogtreecommitdiff
path: root/sys/kern
diff options
context:
space:
mode:
authorAlexander Bluhm <bluhm@cvs.openbsd.org>2018-07-11 19:28:17 +0000
committerAlexander Bluhm <bluhm@cvs.openbsd.org>2018-07-11 19:28:17 +0000
commitf2ee85a2da554a320b38ac71bfd0c41f2450d5d3 (patch)
tree3b9a159dd17179afc80cd1d5a051021e72d9b31a /sys/kern
parent10cff0a21c07feb3129bd15f00d3947ca4832977 (diff)
If no thread can immediately handle a signal, which has been sent
to the process, it is made pending at the main thread. There it could hang forever. So also check the main thread for signal delivery. This workaround fixes hung tests in posixtestsuite. The proper solution would be to split pending signals for process and threads. input visa@; OK guenther@
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/kern_sig.c11
1 files changed, 7 insertions, 4 deletions
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
index 823ab102b7b..7a8a7a9ac69 100644
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_sig.c,v 1.221 2018/07/10 04:19:59 guenther Exp $ */
+/* $OpenBSD: kern_sig.c,v 1.222 2018/07/11 19:28:16 bluhm Exp $ */
/* $NetBSD: kern_sig.c,v 1.54 1996/04/22 01:38:32 christos Exp $ */
/*
@@ -1153,14 +1153,17 @@ issignal(struct proc *p)
int s;
for (;;) {
- mask = p->p_siglist & ~p->p_sigmask;
+ mask = SIGPENDING(p);
if (pr->ps_flags & PS_PPWAIT)
mask &= ~stopsigmask;
if (mask == 0) /* no signal to send */
return (0);
signum = ffs((long)mask);
mask = sigmask(signum);
- atomic_clearbits_int(&p->p_siglist, mask);
+ if (p->p_siglist & mask)
+ atomic_clearbits_int(&p->p_siglist, mask);
+ else
+ atomic_clearbits_int(&pr->ps_mainproc->p_siglist, mask);
/*
* We should see pending but ignored signals
@@ -1836,7 +1839,7 @@ userret(struct proc *p)
KERNEL_UNLOCK();
}
- if (SIGPENDING(p)) {
+ if (SIGPENDING(p) != 0) {
KERNEL_LOCK();
while ((signum = CURSIG(p)) != 0)
postsig(p, signum);