* 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.
This commit is contained in:
Christopher Faylor 2004-01-26 22:25:57 +00:00
parent 5e0f482f2c
commit ef33379be8
3 changed files with 34 additions and 9 deletions

View File

@ -1,3 +1,12 @@
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

View File

@ -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;

View File

@ -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