summaryrefslogtreecommitdiffstats
path: root/winsup/cygwin/exceptions.cc
diff options
context:
space:
mode:
Diffstat (limited to 'winsup/cygwin/exceptions.cc')
-rw-r--r--winsup/cygwin/exceptions.cc54
1 files changed, 22 insertions, 32 deletions
diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc
index 2fd75c65a..ac13478c3 100644
--- a/winsup/cygwin/exceptions.cc
+++ b/winsup/cygwin/exceptions.cc
@@ -1252,38 +1252,28 @@ signal_exit (int sig, siginfo_t *si)
void
_cygtls::handle_SIGCONT ()
{
- if (ISSTATE (myself, PID_STOPPED))
- {
- myself->stopsig = 0;
- myself->process_state &= ~PID_STOPPED;
- int state = 0;
- /* Carefully tell sig_handle_tty_stop to wake up.
- Make sure that any pending signal is handled before trying to
- send a new one. Then make sure that SIGCONT has been recognized
- before exiting the loop. */
- while (state < 2)
- {
- lock ();
- bool do_yield = !!sig;
- 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
- again. */
- sig_dispatch_pending (false);
- }
+ if (NOTSTATE (myself, PID_STOPPED))
+ return;
+
+ myself->stopsig = 0;
+ myself->process_state &= ~PID_STOPPED;
+ /* Carefully tell sig_handle_tty_stop to wake up.
+ Make sure that any pending signal is handled before trying to
+ send a new one. Then make sure that SIGCONT has been recognized
+ before exiting the loop. */
+ bool sigsent = false;
+ while (1)
+ if (sig) /* Assume that it's ok to just test sig outside of a
+ lock since setup_handler does it this way. */
+ yield (); /* Attempt to schedule another thread. */
+ else if (sigsent)
+ break; /* SIGCONT has been recognized by other thread */
+ else
+ {
+ sig = SIGCONT;
+ SetEvent (signal_arrived); /* alert sig_handle_tty_stop */
+ sigsent = true;
+ }
/* Clear pending stop signals */
sig_clear (SIGSTOP);
sig_clear (SIGTSTP);