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