diff options
author | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2018-12-27 20:05:35 +0000 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2018-12-27 20:05:35 +0000 |
commit | b8dcc65bef33da38b3efe9da4cc9977ba2032677 (patch) | |
tree | 15a861b49be2eee5618f9fb36bc4949549fe2e49 | |
parent | 13d6b2fa8fc63fad59d91d794f0e96dd83f3f669 (diff) | |
parent | 74a412373b66a38b6ce8156f027ce26f89a7462f (diff) |
Merge branch 't/ONSTACK' into refs/top-bases/tschwinge/Roger_Whittaker
-rw-r--r-- | hurd/hurdsig.c | 49 |
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) |