* exceptions.cc (_cygtls::handle_SIGCONT): Reinstate previous behavior but make

sure that yield() isn't called when signal stack is locked.
This commit is contained in:
Christopher Faylor 2013-06-07 17:09:56 +00:00
parent 0f38043d8b
commit da6461a4d5
2 changed files with 29 additions and 10 deletions

View File

@ -1,3 +1,8 @@
2013-06-07 Christopher Faylor <me.cygwin2013@cgf.cx>
* exceptions.cc (_cygtls::handle_SIGCONT): Reinstate previous behavior
but make sure that yield() isn't called when signal stack is locked.
2013-06-07 Christopher Faylor <me.cygwin2013@cgf.cx> 2013-06-07 Christopher Faylor <me.cygwin2013@cgf.cx>
* exceptions.cc (exception::handle): Add comment explaining si_addr * exceptions.cc (exception::handle): Add comment explaining si_addr

View File

@ -1256,16 +1256,30 @@ _cygtls::handle_SIGCONT ()
{ {
myself->stopsig = 0; myself->stopsig = 0;
myself->process_state &= ~PID_STOPPED; myself->process_state &= ~PID_STOPPED;
/* Carefully tell sig_handle_tty_stop to wake up. */ int state = 0;
lock (); /* Carefully tell sig_handle_tty_stop to wake up.
sig = SIGCONT; Make sure that any pending signal is handled before trying to
SetEvent (signal_arrived); send a new one. Then make sure that SIGCONT has been recognized
/* Make sure yield doesn't run under lock condition to avoid before exiting the loop. */
starvation of sig_handle_tty_stop. */ while (state < 2)
unlock (); {
/* Wait until sig_handle_tty_stop woke up. */ lock ();
while (sig) bool do_yield = !!sig;
yield (); if (do_yield)
/* signal still being processed */;
else if (state)
state++; /* state == 2: signal no longer being processed */
else
{
sig = SIGCONT;
SetEvent (signal_arrived);
state++; /* state == 1: alert sig_handle_tty_stop */
do_yield = true; /* wake up other thread */
}
unlock ();
if (do_yield)
yield ();
}
/* Tell wait_sig to handle any queued signals now that we're alive /* Tell wait_sig to handle any queued signals now that we're alive
again. */ again. */
sig_dispatch_pending (false); sig_dispatch_pending (false);