diff options
author | Christopher Faylor <me@cgf.cx> | 2013-06-07 17:09:56 +0000 |
---|---|---|
committer | Christopher Faylor <me@cgf.cx> | 2013-06-07 17:09:56 +0000 |
commit | da6461a4d5e9df13e5f14b4b078914eac1b80735 (patch) | |
tree | f680b014794df283a324c9947836c3941ab88089 | |
parent | 0f38043d8bda7c157f916a3e77cb4f84d17355bd (diff) | |
download | cygnal-da6461a4d5e9df13e5f14b4b078914eac1b80735.tar.gz cygnal-da6461a4d5e9df13e5f14b4b078914eac1b80735.tar.bz2 cygnal-da6461a4d5e9df13e5f14b4b078914eac1b80735.zip |
* exceptions.cc (_cygtls::handle_SIGCONT): Reinstate previous behavior but make
sure that yield() isn't called when signal stack is locked.
-rw-r--r-- | winsup/cygwin/ChangeLog | 5 | ||||
-rw-r--r-- | winsup/cygwin/exceptions.cc | 34 |
2 files changed, 29 insertions, 10 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 60b05ddc9..56ca1027e 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,5 +1,10 @@ 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> + * exceptions.cc (exception::handle): Add comment explaining si_addr behavior. diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc index c1b313910..2fd75c65a 100644 --- a/winsup/cygwin/exceptions.cc +++ b/winsup/cygwin/exceptions.cc @@ -1256,16 +1256,30 @@ _cygtls::handle_SIGCONT () { myself->stopsig = 0; myself->process_state &= ~PID_STOPPED; - /* Carefully tell sig_handle_tty_stop to wake up. */ - lock (); - sig = SIGCONT; - SetEvent (signal_arrived); - /* Make sure yield doesn't run under lock condition to avoid - starvation of sig_handle_tty_stop. */ - unlock (); - /* Wait until sig_handle_tty_stop woke up. */ - while (sig) - yield (); + 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); |