diff options
author | Christopher Faylor <me@cgf.cx> | 2004-01-26 22:28:58 +0000 |
---|---|---|
committer | Christopher Faylor <me@cgf.cx> | 2004-01-26 22:28:58 +0000 |
commit | d0a255f2fa0dbd91daa057fb0e2e603628a58e5b (patch) | |
tree | 5021dd4be6c036c009da06ae3f5812b8c47458e5 | |
parent | 8da01b1bce918073c1f700e1a52c2c5138853aca (diff) | |
download | newlib-github/cr-0x9e.zip newlib-github/cr-0x9e.tar.gz newlib-github/cr-0x9e.tar.bz2 |
* exceptions.cc (sig_handle_tty_stop): Avoid races by waiting for bothgithub/cr-0x9ecr-0x9e
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.
-rw-r--r-- | winsup/cygwin/ChangeLog | 9 | ||||
-rw-r--r-- | winsup/cygwin/exceptions.cc | 28 | ||||
-rwxr-xr-x | winsup/cygwin/gendef | 6 |
3 files changed, 34 insertions, 9 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index a2d0278..54b7cb0 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,5 +1,14 @@ 2004-01-26 Christopher Faylor <cgf@redhat.com> + * 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. + +2004-01-26 Christopher Faylor <cgf@redhat.com> + * cygtls.cc (_threadinfo::init_thread): Add more local reent stdio initialization. * dcrt0.cc (initial_env): Can it really be true that XP doesn't allow diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc index 9889d4d..49b04c7 100644 --- a/winsup/cygwin/exceptions.cc +++ b/winsup/cygwin/exceptions.cc @@ -610,8 +610,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; } } @@ -891,9 +902,12 @@ set_signal_mask (sigset_t newmask, sigset_t oldmask) int __stdcall sig_handle (int sig, sigset_t mask, int pid, _threadinfo *tls) { - if (sig == SIGCONT) + DWORD continue_now; + if (sig != 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 */ @@ -901,8 +915,6 @@ sig_handle (int sig, sigset_t mask, int pid, _threadinfo *tls) sig_clear (SIGTSTP); sig_clear (SIGTTIN); sig_clear (SIGTTOU); - if (stopped) - SetEvent (sigCONT); } int rc = 1; @@ -952,6 +964,8 @@ sig_handle (int sig, sigset_t mask, int pid, _threadinfo *tls) || sig == SIGURG) { sigproc_printf ("default signal %d ignored", sig); + if (continue_now) + SetEvent (signal_arrived); goto done; } @@ -985,6 +999,8 @@ dosig: rc = setup_handler (sig, handler, thissig, tls ?: _main_tls); done: + if (continue_now) + SetEvent (sigCONT); sigproc_printf ("returning %d", rc); return rc; diff --git a/winsup/cygwin/gendef b/winsup/cygwin/gendef index df810cb..7e3a4ae 100755 --- a/winsup/cygwin/gendef +++ b/winsup/cygwin/gendef @@ -127,15 +127,15 @@ _sigreturn: addl \$4,%esp # Remove argument call _set_process_mask\@4 - movl %fs:4,%eax + movl %fs:4,%ebx - cmpl \$0,$tls::sig(%eax) # Did a signal come in? + cmpl \$0,$tls::sig(%ebx) # Did a signal come in? jnz 3f # Yes, if non-zero 1: popl %edx # saved errno testl %edx,%edx # Is it < 0 jl 2f # yup. ignore it - movl $tls::errno_addr(%eax),%eax + movl $tls::errno_addr(%ebx),%eax movl %edx,(%eax) 2: popl %eax popl %ebx |