summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2018-12-27 20:05:35 +0000
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2018-12-27 20:05:35 +0000
commitb8dcc65bef33da38b3efe9da4cc9977ba2032677 (patch)
tree15a861b49be2eee5618f9fb36bc4949549fe2e49
parent13d6b2fa8fc63fad59d91d794f0e96dd83f3f669 (diff)
parent74a412373b66a38b6ce8156f027ce26f89a7462f (diff)
Merge branch 't/ONSTACK' into refs/top-bases/tschwinge/Roger_Whittaker
-rw-r--r--hurd/hurdsig.c49
1 files changed, 49 insertions, 0 deletions
diff --git a/hurd/hurdsig.c b/hurd/hurdsig.c
index 7bc4bc97aa..2f16ad5482 100644
--- a/hurd/hurdsig.c
+++ b/hurd/hurdsig.c
@@ -1237,6 +1237,55 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss,
ss = post_signal (ss, signo, detail, untraced, reply);
if (! ss)
return;
+ /* No pending signals left undelivered for this thread.
+ If we were sent signal 0, we need to check for pending
+ signals for all threads. */
+ if (signo == 0)
+ {
+ __spin_unlock (&ss->lock);
+ __mutex_lock (&_hurd_siglock);
+ for (ss = _hurd_sigstates; ss != NULL; ss = ss->next)
+ {
+ __spin_lock (&ss->lock);
+ for (signo = 1; signo < NSIG; ++signo)
+ if (__sigismember (&ss->pending, signo)
+ && (!__sigismember (&ss->blocked, signo)
+ /* We "deliver" immediately pending blocked signals whose
+ action might be to ignore, so that if ignored they are
+ dropped right away. */
+ || ss->actions[signo].sa_handler == SIG_IGN
+ || ss->actions[signo].sa_handler == SIG_DFL))
+ {
+ __mutex_unlock (&_hurd_siglock);
+ goto deliver_pending;
+ }
+ __spin_unlock (&ss->lock);
+ }
+ __mutex_unlock (&_hurd_siglock);
+ }
+ else
+ {
+ /* No more signals pending; SS->lock is still locked.
+ Wake up any sigsuspend call that is blocking SS->thread. */
+ if (ss->suspended != MACH_PORT_NULL)
+ {
+ /* There is a sigsuspend waiting. Tell it to wake up. */
+ error_t err;
+ mach_msg_header_t msg;
+ msg.msgh_bits = MACH_MSGH_BITS (MACH_MSG_TYPE_MAKE_SEND, 0);
+ msg.msgh_remote_port = ss->suspended;
+ msg.msgh_local_port = MACH_PORT_NULL;
+ /* These values do not matter. */
+ msg.msgh_id = 8675309; /* Jenny, Jenny. */
+ ss->suspended = MACH_PORT_NULL;
+ err = __mach_msg (&msg, MACH_SEND_MSG, sizeof msg, 0,
+ MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE,
+ MACH_PORT_NULL);
+ assert_perror (err);
+ }
+ __spin_unlock (&ss->lock);
+ }
+ }
/* The signal was neither fatal nor traced. We still hold SS->lock. */
if (signo != 0 && ss->thread != MACH_PORT_NULL)