diff options
author | Christopher Faylor <me@cgf.cx> | 2013-03-31 16:35:44 +0400 |
---|---|---|
committer | Christopher Faylor <me@cgf.cx> | 2013-03-31 16:35:44 +0400 |
commit | 8f8eeb70ba7354749c78bc5013eeb12f4c18fba0 (patch) | |
tree | 5a33777acf2ae03b9f4ef75de12bdccecd1df068 /winsup/cygwin/exceptions.cc | |
parent | 4332090c2d497c08dd1c98df7702f861905b2508 (diff) |
* child_info.h (cygheap_exec_info::sigmask): Declare new field.
* cygheap.cc (init_cygheap::find_tls): Rename threadlist_ix -> ix. Only take
one pass through thread list, looking for eligible threads to signal. Set a
new param indicating that function has found a sigwait* mask.
* cygheap.h (init_cygheap::find_tls): Reflect new parameter.
* dcrt0.cc (parent_sigmask): New variable.
(child_info_spawn::handle_spawn): Save parent's signal mask here.
(dll_crt0_1): Restore parent's signal mask to tls sigmask as appropriate. Call
sig_dispatch_pending to flush signal queue when we can finally do something
with signals.
* exceptions.cc (sigpacket::process): Avoid attempting to handle signals if we
haven't finished initializing. Rely on the fact that find_tls will do mask
checking and don't do it again. Delete ill-named 'dummy' variable.
* sigproc.cc (cygheap_exec_info::alloc): Save calling thread's signal mask in
new sigmask field.
(wait_sig): Try to debug when WFSO fails and DEBUGGING is defined.
* thread.cc (pthread::set_tls_self_pointer): Make this a true automatic method
rather than inexplicably relying on a thread parameter.
(pthread::thread_init_wrapper): Accommodate set_tls_self_pointer change to
non-static. Initialize sigmask before setting tid or suffer signal races.
* ehread.h (pthread::set_tls_self_pointer): Make non-static, delete parameter.
Diffstat (limited to 'winsup/cygwin/exceptions.cc')
-rw-r--r-- | winsup/cygwin/exceptions.cc | 65 |
1 files changed, 37 insertions, 28 deletions
diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc index e41922900..9815be280 100644 --- a/winsup/cygwin/exceptions.cc +++ b/winsup/cygwin/exceptions.cc @@ -1124,12 +1124,19 @@ signal_exit (int sig, siginfo_t *si) int __stdcall sigpacket::process () { - bool continue_now; - struct sigaction dummy = global_sigs[SIGSTOP]; + int rc = 1; + bool issig_wait = false; + bool continue_now = false; + struct sigaction& thissig = global_sigs[si.si_signo]; + void *handler = have_execed ? NULL : (void *) thissig.sa_handler; - if (si.si_signo != SIGCONT) - continue_now = false; - else + if (!cygwin_finished_initializing) + { + rc = -1; + goto really_done; + } + + if (si.si_signo == SIGCONT) { continue_now = ISSTATE (myself, PID_STOPPED); myself->stopsig = 0; @@ -1141,30 +1148,43 @@ sigpacket::process () sig_clear (SIGTTOU); } - int rc = 1; - sigproc_printf ("signal %d processing", si.si_signo); - struct sigaction& thissig = global_sigs[si.si_signo]; myself->rusage_self.ru_nsignals++; _cygtls *tls; - if (sigtls) + if (!sigtls) { - tls = sigtls; - sigproc_printf ("using sigtls %p", sigtls); + tls = cygheap->find_tls (si.si_signo, issig_wait); + sigproc_printf ("using tls %p", tls); } else { - tls = cygheap->find_tls (si.si_signo); - sigproc_printf ("using tls %p", tls); + tls = sigtls; + if (sigismember (&tls->sigwait_mask, si.si_signo)) + issig_wait = true; + else if (!sigismember (&tls->sigmask, si.si_signo)) + issig_wait = false; + else + tls = NULL; + } + + if (!tls || ISSTATE (myself, PID_STOPPED)) + { + sigproc_printf ("signal %d blocked", si.si_signo); + rc = -1; + goto done; } /* Do stuff for gdb */ if ((HANDLE) *tls) tls->signal_debugger (si); - void *handler = have_execed ? NULL : (void *) thissig.sa_handler; + if (issig_wait) + { + tls->sigwait_mask = 0; + goto dosig; + } if (handler == SIG_IGN) { @@ -1180,18 +1200,6 @@ sigpacket::process () goto stop; } - if (sigismember (&tls->sigwait_mask, si.si_signo)) - { - tls->sigwait_mask = 0; - goto dosig; - } - if (sigismember (&tls->sigmask, si.si_signo) || ISSTATE (myself, PID_STOPPED)) - { - sigproc_printf ("signal %d blocked", si.si_signo); - rc = -1; - goto done; - } - /* Clear pending SIGCONT on stop signals */ if (si.si_signo == SIGTSTP || si.si_signo == SIGTTIN || si.si_signo == SIGTTOU) sig_clear (SIGCONT); @@ -1218,7 +1226,7 @@ sigpacket::process () stop: handler = (void *) sig_handle_tty_stop; - thissig = dummy; + thissig = global_sigs[SIGSTOP]; goto dosig; exit_sig: @@ -1248,9 +1256,10 @@ dispatch_sig: done: if (continue_now) { - tls->sig = SIGCONT; + (tls ?: _main_tls)->sig = SIGCONT; SetEvent (tls->signal_arrived); } +really_done: sigproc_printf ("returning %d", rc); return rc; |