From f70cea57488f23ba8ac49c47160eb7d03e5ac6e7 Mon Sep 17 00:00:00 2001 From: cgf Date: Thu, 25 Aug 2005 03:12:47 +0000 Subject: [PATCH] * exceptions.cc (handle_sigsuspend): Just sleep forever if called from non-main thread. (sigpacket:process): Simplify logic which determines when and how a signal is masked. Don't trigger sigwait if there is a signal handler. * sigproc.cc (wait_sig): Update comment. Try to process a signal which is in the queue if it isn't queued for the target thread (this is still not right). --- winsup/cygwin/ChangeLog | 10 ++++++++++ winsup/cygwin/exceptions.cc | 37 +++++++++++++++++++++---------------- winsup/cygwin/sigproc.cc | 7 ++++--- 3 files changed, 35 insertions(+), 19 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 361c01c3f1..45c462ab11 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,5 +1,15 @@ 2005-08-24 Christopher Faylor + * exceptions.cc (handle_sigsuspend): Just sleep forever if called from + non-main thread. + (sigpacket:process): Simplify logic which determines when and how a + signal is masked. Don't trigger sigwait if there is a signal handler. + * sigproc.cc (wait_sig): Update comment. Try to process a signal which + is in the queue if it isn't queued for the target thread (this is still + not right). + +2005-08-24 Christopher Faylor + * spawn.cc (perhaps_suffix): Record errno-type error value in third argument. (find_exec): On error, set errno returned from perhaps_suffix. diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc index 9ae77f8d21..e75ee610a3 100644 --- a/winsup/cygwin/exceptions.cc +++ b/winsup/cygwin/exceptions.cc @@ -590,6 +590,8 @@ handle_exceptions (EXCEPTION_RECORD *e0, void *frame, CONTEXT *in0, void *) int __stdcall handle_sigsuspend (sigset_t tempmask) { + if (&_my_tls != _main_tls) + Sleep (INFINITE); sigset_t oldmask = myself->getsigmask (); // Remember for restoration set_signal_mask (tempmask, myself->getsigmask ()); @@ -911,6 +913,7 @@ extern "C" void __stdcall set_process_mask (sigset_t newmask) { set_signal_mask (newmask, myself->getsigmask ()); +sigproc_printf ("mask now %p\n", myself->getsigmask ()); } extern "C" int @@ -1014,9 +1017,12 @@ sigpacket::process () myself->rusage_self.ru_nsignals++; + bool masked; + void *handler = (void *) thissig.sa_handler; + if (si.si_signo == SIGKILL) goto exit_sig; - if ( si.si_signo == SIGSTOP) + if (si.si_signo == SIGSTOP) { sig_clear (SIGCONT); if (!tls) @@ -1024,35 +1030,34 @@ sigpacket::process () goto stop; } - bool masked; - bool special_case; bool insigwait_mask; - insigwait_mask = masked = false; - if (special_case = (/*VFORKPID || */ISSTATE (myself, PID_STOPPED))) - /* nothing to do */; - else if (tls && sigismember (&tls->sigwait_mask, si.si_signo)) - insigwait_mask = true; - else if (!tls && (tls = _cygtls::find_tls (si.si_signo))) - insigwait_mask = true; - else if (!(masked = sigismember (mask, si.si_signo)) && tls) - masked = sigismember (&tls->sigmask, si.si_signo); + if ((masked = ISSTATE (myself, PID_STOPPED))) + insigwait_mask = false; + else if (!tls) + insigwait_mask = !handler && (tls = _cygtls::find_tls (si.si_signo)); + else + insigwait_mask = sigismember (&tls->sigwait_mask, si.si_signo); if (insigwait_mask) goto thread_specific; + if (masked) + /* nothing to do */; + else if (sigismember (mask, si.si_signo)) + masked = true; + else if (tls) + masked = sigismember (&tls->sigmask, si.si_signo); + if (!tls) tls = _main_tls; - if (special_case || masked) + if (masked) { sigproc_printf ("signal %d blocked", si.si_signo); rc = -1; goto done; } - void *handler; - handler = (void *) thissig.sa_handler; - /* Clear pending SIGCONT on stop signals */ if (si.si_signo == SIGTSTP || si.si_signo == SIGTTIN || si.si_signo == SIGTTOU) sig_clear (SIGCONT); diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc index 2bb9d4edaa..382b226f8c 100644 --- a/winsup/cygwin/sigproc.cc +++ b/winsup/cygwin/sigproc.cc @@ -1097,9 +1097,10 @@ wait_sig (VOID *self) else { int sig = pack.si.si_signo; - // FIXME: Not quite right when taking threads into consideration. - // Do we need a per-thread queue? - if (sigq.sigs[sig].si.si_signo) + // FIXME: REALLY not right when taking threads into consideration. + // We need a per-thread queue since each thread can have its own + // list of blocked signals. CGF 2005-08-24 + if (sigq.sigs[sig].si.si_signo && sigq.sigs[sig].tls == pack.tls) sigproc_printf ("sig %d already queued", pack.si.si_signo); else { -- 2.11.0