Hi, Since the recent futex(2) changes the posixtestsuite regress does not finish within the given time frame. Depending on some races tests hang, e.g. this one:
/usr/local/libexec/posixtestsuite/conformance/interfaces/pthread_atfork/3-3.test It spans a worker thread that allows to handle SIGUSR1 or SIGUSR2. Two signal sending threads are created that kill the process with SIGUSR1 or SIGUSR2 repectively. The main thread and the signal sending threads block these signals. The signal handler in the worker thread uses semaphores to acknowledge signals and then the sending threads kill again. It may happen that the worker thread is in the signal handler and also blocks the signals. Then all threads block them and ptsignal() sends it to the main thread. In the test program the main thread blocks them forever and the process gets stuck. According to POSIX any thread should process the signal when it unblocks. http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_04_01 If there are no threads in a call to a sigwait() function selecting that signal, and if all threads within the process block delivery of the signal, the signal shall remain pending on the process until a thread calls a sigwait() function selecting that signal, a thread unblocks delivery of the signal, or the action associated with the signal is set to ignore the signal. For this purpose NetBSD has l_sigpend for the thread and p_sigpend for the process. As prsignal() sends the signal to ps_mainproc if it cannot be delivered immediately, we could also consider the main proc when we check for pending signals. This fixes my use case without beeing to invasive. ok? bluhm Index: kern/kern_sig.c =================================================================== RCS file: /data/mirror/openbsd/cvs/src/sys/kern/kern_sig.c,v retrieving revision 1.220 diff -u -p -r1.220 kern_sig.c --- kern/kern_sig.c 28 Apr 2018 03:13:04 -0000 1.220 +++ kern/kern_sig.c 22 Jun 2018 19:28:54 -0000 @@ -1155,14 +1155,18 @@ issignal(struct proc *p) int s; for (;;) { - mask = p->p_siglist & ~p->p_sigmask; + mask = p->p_siglist | pr->ps_mainproc->p_siglist; + mask &= ~p->p_sigmask; 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 Index: sys/signalvar.h =================================================================== RCS file: /data/mirror/openbsd/cvs/src/sys/sys/signalvar.h,v retrieving revision 1.30 diff -u -p -r1.30 signalvar.h --- sys/signalvar.h 24 Mar 2018 04:13:59 -0000 1.30 +++ sys/signalvar.h 22 Jun 2018 19:28:54 -0000 @@ -68,7 +68,9 @@ struct sigacts { /* * Check if process p has an unmasked signal pending. */ -#define SIGPENDING(p) (((p)->p_siglist & ~(p)->p_sigmask) != 0) +#define SIGPENDING(p) \ + ((((p)->p_siglist | (p)->p_p->ps_mainproc->p_siglist) & \ + ~(p)->p_sigmask) != 0) /* * Determine signal that should be delivered to process p, the current @@ -76,9 +78,11 @@ struct sigacts { * action, the process stops in issignal(). */ #define CURSIG(p) \ - (((p)->p_siglist == 0 || \ + ((((p)->p_siglist == 0 && \ + (p)->p_p->ps_mainproc->p_siglist == 0) || \ (((p)->p_p->ps_flags & PS_TRACED) == 0 && \ - ((p)->p_siglist & ~(p)->p_sigmask) == 0)) ? \ + (((p)->p_siglist | (p)->p_p->ps_mainproc->p_siglist) & \ + ~(p)->p_sigmask) == 0)) ? \ 0 : issignal(p)) /*
