* 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:
Christopher Faylor 2003-08-20 05:15:33 +00:00
parent 5f31e0f305
commit 6f6d673cc5
3 changed files with 43 additions and 18 deletions

View File

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

View File

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

View File

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