From 4d02a5b18a0c2702bfca949bc60187f53d6f39d2 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Thu, 6 Jun 1996 20:49:22 +0000 Subject: Thu Jun 6 16:12:39 1996 Roland McGrath * hurd/hurdsig.c (_hurd_internal_post_signal): For SIGNO==0 pending check, deliver a pending blocked signal if its action might be to ignore. * sysdeps/mach/hurd/sigaction.c: If new action is SIG_IGN or SIG_DFL and SIG is pending, wake up signal thread to check us. * hurd/hurdsig.c (_hurd_internal_post_signal): Don't mark a signal pending while blocked or stopped when the action is to ignore it. * hurd/hurdsig.c (_hurd_internal_post_signal: resume): Only set SS_SUSPENDED when the thread is really suspended. * elf/rtld.c (dl_main): Don't dereference _dl_rtld_map.l_next if null. --- hurd/hurdsig.c | 40 ++++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-) (limited to 'hurd/hurdsig.c') diff --git a/hurd/hurdsig.c b/hurd/hurdsig.c index 6abad33021..f2bc08993d 100644 --- a/hurd/hurdsig.c +++ b/hurd/hurdsig.c @@ -516,8 +516,9 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss, (vm_address_t) threads, nthreads * sizeof *threads); _hurd_stopped = 0; - /* The thread that will run the handler is already suspended. */ - ss_suspended = 1; + if (act == handle) + /* The thread that will run the handler is already suspended. */ + ss_suspended = 1; } if (signo == 0) @@ -673,19 +674,11 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss, } /* Handle receipt of a blocked signal, or any signal while stopped. */ - if (__sigismember (&ss->blocked, signo) || + if (act != ignore && /* Signals ignored now are forgotten now. */ + __sigismember (&ss->blocked, signo) || (signo != SIGKILL && _hurd_stopped)) { mark_pending (); - /* If there was a call to resume above in SIGCONT processing - and we've left a thread suspended, now's the time to - set it going. */ - if (ss_suspended) - { - err = __thread_resume (ss->thread); - assert_perror (err); - ss_suspended = 0; - } act = ignore; } @@ -708,7 +701,15 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss, break; case ignore: - /* Nobody cares about this signal. */ + /* Nobody cares about this signal. If there was a call to resume + above in SIGCONT processing and we've left a thread suspended, + now's the time to set it going. */ + if (ss_suspended) + { + err = __thread_resume (ss->thread); + assert_perror (err); + ss_suspended = 0; + } break; sigbomb: @@ -904,10 +905,10 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss, if (signals_pending ()) { - pending: for (signo = 1; signo < NSIG; ++signo) if (__sigismember (&pending, signo)) { + deliver: __sigdelset (&ss->pending, signo); *detail = ss->pending_data[signo]; __spin_unlock (&ss->lock); @@ -925,8 +926,15 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss, for (ss = _hurd_sigstates; ss != NULL; ss = ss->next) { __spin_lock (&ss->lock); - if (signals_pending ()) - goto pending; + 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) + goto deliver_pending; __spin_unlock (&ss->lock); } __mutex_unlock (&_hurd_siglock); -- cgit 1.4.1