* sigproc.cc (wait_sig): Ensure that myself->getsigtodo array is flushed on a
__SIGFLUSH. Christopher Faylor <cgf@redhat.com> * exceptions.cc (_sigreturn): Handle nested signals without growing the stack.
This commit is contained in:
parent
5f31e0f305
commit
6f6d673cc5
|
@ -1,3 +1,14 @@
|
|||
2003-08-20 Christopher Faylor <cgf@redhat.com>
|
||||
|
||||
* sigproc.cc (wait_sig): Ensure that myself->getsigtodo array is
|
||||
flushed on a __SIGFLUSH.
|
||||
|
||||
2003-08-20 Pierre Humblet <pierre.humblet@ieee.org>
|
||||
Christopher Faylor <cgf@redhat.com>
|
||||
|
||||
* exceptions.cc (_sigreturn): Handle nested signals without growing the
|
||||
stack.
|
||||
|
||||
2003-08-19 Christopher Faylor <cgf@redhat.com>
|
||||
|
||||
* exceptions.cc (pending_signals): Remove unneeded declaration.
|
||||
|
|
|
@ -1220,13 +1220,14 @@ __asm__ volatile ("\n\
|
|||
.text \n\
|
||||
_sigreturn: \n\
|
||||
addl $4,%%esp # Remove argument \n\
|
||||
movl %%esp,%%ebp \n\
|
||||
addl $36,%%ebp \n\
|
||||
call _set_process_mask@4 \n\
|
||||
\n\
|
||||
cmpl $0,%4 # Did a signal come in? \n\
|
||||
jz 1f # No, if zero \n\
|
||||
call _call_signal_handler_now@0 # yes handle the signal \n\
|
||||
movl %2,%%eax \n\
|
||||
movl %%esp,%%ebp \n\
|
||||
movl %%eax,36(%%ebp) # Restore return address \n\
|
||||
jmp 3f \n\
|
||||
\n\
|
||||
1: popl %%eax # saved errno \n\
|
||||
testl %%eax,%%eax # Is it < 0 \n\
|
||||
|
@ -1257,7 +1258,7 @@ _sigdelayed0: \n\
|
|||
pushl %%ebx \n\
|
||||
pushl %%eax \n\
|
||||
pushl %6 # saved errno \n\
|
||||
pushl %3 # oldmask \n\
|
||||
3: pushl %3 # oldmask \n\
|
||||
pushl %4 # signal argument \n\
|
||||
pushl $_sigreturn \n\
|
||||
\n\
|
||||
|
|
|
@ -1116,9 +1116,20 @@ wait_sig (VOID *self)
|
|||
|
||||
HANDLE catchem[] = {sigcatch_main, sigcatch_nonmain, sigcatch_nosync};
|
||||
sigproc_printf ("Ready. dwProcessid %d", myself->dwProcessId);
|
||||
DWORD rc = RC_NOSYNC;
|
||||
bool flush = false;
|
||||
for (;;)
|
||||
{
|
||||
DWORD rc = WaitForMultipleObjects (3, catchem, FALSE, sig_loop_wait);
|
||||
DWORD i;
|
||||
if (rc == RC_MAIN || rc == RC_NONMAIN)
|
||||
i = RC_NOSYNC;
|
||||
else
|
||||
i = RC_MAIN;
|
||||
rc = WaitForSingleObject (catchem[i], 0);
|
||||
if (rc != WAIT_OBJECT_0)
|
||||
rc = WaitForMultipleObjects (3, catchem, FALSE, sig_loop_wait);
|
||||
else
|
||||
rc = i + WAIT_OBJECT_0;
|
||||
(void) SetThreadPriority (GetCurrentThread (), WAIT_SIG_PRIORITY);
|
||||
|
||||
/* sigproc_terminate sets sig_loop_wait to zero to indicate that
|
||||
|
@ -1159,7 +1170,7 @@ wait_sig (VOID *self)
|
|||
/* A sigcatch semaphore has been signaled. Scan the sigtodo
|
||||
* array looking for any unprocessed signals.
|
||||
*/
|
||||
pending_signals = false;
|
||||
pending_signals = 0;
|
||||
bool saw_failed_interrupt = false;
|
||||
for (LONG **todo = todos; todo <= end_todo; todo++)
|
||||
for (int sig = -__SIGOFFSET; sig < NSIG; sig++)
|
||||
|
@ -1178,8 +1189,8 @@ wait_sig (VOID *self)
|
|||
(sig != SIGCONT && ISSTATE (myself, PID_STOPPED))))
|
||||
{
|
||||
sigproc_printf ("signal %d blocked", sig);
|
||||
InterlockedIncrement (*todo + sig);
|
||||
pending_signals = true; // FIXME: This will cause unnecessary sig_dispatch_pending spins
|
||||
InterlockedIncrement (myself->getsigtodo (sig));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1188,7 +1199,12 @@ wait_sig (VOID *self)
|
|||
switch (sig)
|
||||
{
|
||||
case __SIGFLUSH:
|
||||
/* just forcing the loop */
|
||||
if (rc == RC_MAIN)
|
||||
{
|
||||
flush = true;
|
||||
ReleaseSemaphore (sigcatch_nosync, 1, NULL);
|
||||
goto out1;
|
||||
}
|
||||
break;
|
||||
|
||||
/* Internal signal to turn on stracing. */
|
||||
|
@ -1206,8 +1222,9 @@ wait_sig (VOID *self)
|
|||
if (!sig_handle (sig))
|
||||
{
|
||||
sigproc_printf ("couldn't send signal %d", sig);
|
||||
pending_signals = saw_failed_interrupt = true;
|
||||
ReleaseSemaphore (sigcatch_nosync, 1, NULL);
|
||||
saw_failed_interrupt = true;
|
||||
pending_signals = true;
|
||||
InterlockedIncrement (myself->getsigtodo (sig));
|
||||
}
|
||||
}
|
||||
|
@ -1222,19 +1239,15 @@ wait_sig (VOID *self)
|
|||
out:
|
||||
/* Signal completion of signal handling depending on which semaphore
|
||||
woke up the WaitForMultipleObjects above. */
|
||||
switch (rc)
|
||||
if (rc == RC_NONMAIN) // FIXME: This is broken
|
||||
ReleaseSemaphore (sigcomplete_nonmain, 1, NULL);
|
||||
else if (rc == RC_MAIN || flush)
|
||||
{
|
||||
case RC_MAIN:
|
||||
SetEvent (sigcomplete_main);
|
||||
sigproc_printf ("set main thread completion event");
|
||||
break;
|
||||
case RC_NONMAIN:
|
||||
ReleaseSemaphore (sigcomplete_nonmain, 1, NULL);
|
||||
break;
|
||||
default:
|
||||
/* Signal from another process. No need to synchronize. */
|
||||
break;
|
||||
flush = false;
|
||||
}
|
||||
out1:
|
||||
if (saw_failed_interrupt)
|
||||
low_priority_sleep (SLEEP_0_STAY_LOW); /* Hopefully, other thread will be waking up soon. */
|
||||
sigproc_printf ("looping");
|
||||
|
|
Loading…
Reference in New Issue