Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2004-01-27 01:25:57 +0300
committerChristopher Faylor <me@cgf.cx>2004-01-27 01:25:57 +0300
commitef33379be8be59c475cdb280e2e2f414fe1c2a8e (patch)
treed716598d339fa88162dc9aca2d60192cb7d1dd27 /winsup/cygwin/exceptions.cc
parent5e0f482f2cac33d5ce758e4dc0f665a4e195f4e1 (diff)
* exceptions.cc (sig_handle_tty_stop): Avoid races by waiting for both
signal_arrived and for sigCONT. (sigpacket::process): Enforce sending of both signal_arrived and sigCONT, where appropriate. * gendef (sigreturn): Save tls pointer in ebx so that it can jump into sigdelayed and use the same register.
Diffstat (limited to 'winsup/cygwin/exceptions.cc')
-rw-r--r--winsup/cygwin/exceptions.cc28
1 files changed, 22 insertions, 6 deletions
diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc
index db70fa51d..11088fcfd 100644
--- a/winsup/cygwin/exceptions.cc
+++ b/winsup/cygwin/exceptions.cc
@@ -644,8 +644,19 @@ sig_handle_tty_stop (int sig)
}
sigproc_printf ("process %d stopped by signal %d, myself->ppid_handle %p",
myself->pid, sig, myself->ppid_handle);
- if (WaitForSingleObject (sigCONT, INFINITE) != WAIT_OBJECT_0)
- api_fatal ("WaitSingleObject failed, %E");
+ HANDLE w4[2];
+ w4[0] = sigCONT;
+ w4[1] = signal_arrived;
+ switch (WaitForMultipleObjects (2, w4, TRUE, INFINITE))
+ {
+ case WAIT_OBJECT_0:
+ case WAIT_OBJECT_0 + 1:
+ reset_signal_arrived ();
+ break;
+ default:
+ api_fatal ("WaitSingleObject failed, %E");
+ break;
+ }
return;
}
}
@@ -925,9 +936,12 @@ set_signal_mask (sigset_t newmask, sigset_t oldmask)
int __stdcall
sigpacket::process ()
{
- if (si.si_signo == SIGCONT)
+ DWORD continue_now;
+ if (si.si_signo != SIGCONT)
+ continue_now = false;
+ else
{
- DWORD stopped = myself->process_state & PID_STOPPED;
+ continue_now = myself->process_state & PID_STOPPED;
myself->stopsig = 0;
myself->process_state &= ~PID_STOPPED;
/* Clear pending stop signals */
@@ -935,8 +949,6 @@ sigpacket::process ()
sig_clear (SIGTSTP);
sig_clear (SIGTTIN);
sig_clear (SIGTTOU);
- if (stopped)
- SetEvent (sigCONT);
}
int rc = 1;
@@ -1001,6 +1013,8 @@ sigpacket::process ()
|| si.si_signo == SIGURG)
{
sigproc_printf ("default signal %d ignored", si.si_signo);
+ if (continue_now)
+ SetEvent (signal_arrived);
goto done;
}
@@ -1037,6 +1051,8 @@ dosig1:
rc = setup_handler (si.si_signo, handler, thissig, tls);
done:
+ if (continue_now)
+ SetEvent (sigCONT);
sigproc_printf ("returning %d", rc);
return rc;