* sigproc.cc (wait_sig): Count number of iterations through 'more_signals' loop

and issue a warning if DEBUGGING and excessive.
(WFSO): When debugging and infinite timeout, loop.
This commit is contained in:
Christopher Faylor 2003-08-27 20:42:52 +00:00
parent 0903a4aacf
commit 90f4768b78
2 changed files with 81 additions and 65 deletions

View File

@ -1,3 +1,9 @@
2003-08-27 Christopher Faylor <cgf@redhat.com>
* sigproc.cc (wait_sig): Count number of iterations through
'more_signals' loop and issue a warning if DEBUGGING and excessive.
(WFSO): When debugging and infinite timeout, loop.
2003-08-26 Corinna Vinschen <corinna@vinschen.de> 2003-08-26 Corinna Vinschen <corinna@vinschen.de>
* include/cygwin/stat.h: Allow definition of internal stat structures * include/cygwin/stat.h: Allow definition of internal stat structures

View File

@ -700,7 +700,7 @@ sig_send (_pinfo *p, int sig, DWORD ebp, bool exception)
todo = getlocal_sigtodo (sig); todo = getlocal_sigtodo (sig);
} }
} }
else if (thiscatch = getsem (p, "sigcatch", 0, 0)) else if ((thiscatch = getsem (p, "sigcatch", 0, 0)))
todo = p->getsigtodo (sig); todo = p->getsigtodo (sig);
else else
goto out; // Couldn't get the semaphore. getsem issued goto out; // Couldn't get the semaphore. getsem issued
@ -1137,8 +1137,7 @@ wait_sig (VOID *self)
(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
* this thread should terminate. this thread should terminate. */
*/
if (rc == WAIT_TIMEOUT) if (rc == WAIT_TIMEOUT)
{ {
if (!sig_loop_wait) if (!sig_loop_wait)
@ -1163,76 +1162,86 @@ wait_sig (VOID *self)
todo = todos[1]; todo = todos[1];
/* 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 = false;
bool more_signals = false; unsigned more_signals = 0;
bool saw_failed_interrupt = false; bool saw_failed_interrupt = false;
do do
for (int sig = -__SIGOFFSET, more_signals = false; sig < NSIG; sig++) {
{ more_signals = 0;
LONG x = InterlockedDecrement (todo + sig); for (int sig = -__SIGOFFSET; sig < NSIG; sig++)
if (x < 0) {
InterlockedIncrement (todo + sig); LONG x = InterlockedDecrement (todo + sig);
else if (x >= 0) if (x < 0)
{ InterlockedIncrement (todo + sig);
if (sig > 0 && sig != SIGKILL && sig != SIGSTOP && else if (x >= 0)
(sigismember (&myself->getsigmask (), sig) || {
main_vfork->pid || /* If x > 0, we have to deal with a signal at some later point */
(sig != SIGCONT && ISSTATE (myself, PID_STOPPED)))) if (rc != RC_NOSYNC && x > 0)
{ pending_signals = true; // There should be an armed semaphore, in this case
sigproc_printf ("signal %d blocked", sig);
pending_signals = true; // FIXME: This will cause unnecessary sig_dispatch_pending spins
InterlockedIncrement (myself->getsigtodo (sig));
}
else
{
/* Found a signal to process */
if (rc != RC_NOSYNC)
pending_signals = true; // There should be an armed semaphore, in this case
sigproc_printf ("processing signal %d", sig); if (sig > 0 && sig != SIGKILL && sig != SIGSTOP &&
switch (sig) (sigismember (&myself->getsigmask (), sig) ||
{ main_vfork->pid ||
case __SIGFLUSH: (sig != SIGCONT && ISSTATE (myself, PID_STOPPED))))
if (rc == RC_MAIN) {
{ sigproc_printf ("signal %d blocked", sig);
flush = true; x = InterlockedIncrement (myself->getsigtodo (sig));
ReleaseSemaphore (sigcatch_nosync, 1, NULL); pending_signals = true;
goto out1; }
} else
break; {
sigproc_printf ("processing signal %d", sig);
switch (sig)
{
case __SIGFLUSH:
if (rc == RC_MAIN)
{
flush = true;
ReleaseSemaphore (sigcatch_nosync, 1, NULL);
goto out1;
}
break;
/* Internal signal to turn on stracing. */ /* Internal signal to turn on stracing. */
case __SIGSTRACE: case __SIGSTRACE:
strace.hello (); strace.hello ();
break; break;
case __SIGCOMMUNE: case __SIGCOMMUNE:
talktome (); talktome ();
break; break;
/* A normal UNIX signal */ /* A normal UNIX signal */
default: default:
sigproc_printf ("Got signal %d", sig); sigproc_printf ("Got signal %d", sig);
if (!sig_handle (sig)) if (!sig_handle (sig))
{ {
pending_signals = saw_failed_interrupt = true; saw_failed_interrupt = true;
sigproc_printf ("couldn't send signal %d", sig); sigproc_printf ("couldn't send signal %d", sig);
InterlockedIncrement (myself->getsigtodo (sig)); x = InterlockedIncrement (myself->getsigtodo (sig));
} pending_signals = true;
} }
if (rc == RC_NOSYNC) }
more_signals = x > 0; if (rc == RC_NOSYNC && x > 0)
} more_signals++;
}
if (sig == SIGCHLD) if (sig == SIGCHLD)
proc_subproc (PROC_CLEARWAIT, 0); proc_subproc (PROC_CLEARWAIT, 0);
if (saw_failed_interrupt || rc != RC_NOSYNC)
goto out; /* Need to take special action if an interrupt failed due to main thread not
} getting around to calling handler yet. */
} if (saw_failed_interrupt || rc != RC_NOSYNC)
while (more_signals); goto out;
}
}
#ifdef DEBUGGING
if (more_signals > 100)
system_printf ("hmm. infinite loop? more_signals %u\n", more_signals);
#endif
}
while (more_signals && sig_loop_wait);
out: out:
/* Signal completion of signal handling depending on which semaphore /* Signal completion of signal handling depending on which semaphore
@ -1245,6 +1254,7 @@ wait_sig (VOID *self)
sigproc_printf ("set main thread completion event"); sigproc_printf ("set main thread completion event");
flush = false; flush = false;
} }
out1: out1:
if (saw_failed_interrupt) if (saw_failed_interrupt)
{ {