* signal.cc (sigpending): Move.

* sigproc.cc (sigpending): To here.
(getlocal_sigtodo): Return process-local signal array.
(sigpending): Accommodate new process-local signal array.
(sig_send): Ditto.
(sig_set_pending): Ditto.
(wait_sig): Ditto.
This commit is contained in:
Christopher Faylor 2003-08-19 05:47:44 +00:00
parent 05cb7b17cb
commit 06bb489932
3 changed files with 107 additions and 66 deletions

View File

@ -1,3 +1,13 @@
2003-08-19 Christopher Faylor <cgf@redhat.com>
* signal.cc (sigpending): Move.
* sigproc.cc (sigpending): To here.
(getlocal_sigtodo): Return process-local signal array.
(sigpending): Accommodate new process-local signal array.
(sig_send): Ditto.
(sig_set_pending): Ditto.
(wait_sig): Ditto.
2003-08-19 Christopher Faylor <cgf@redhat.com> 2003-08-19 Christopher Faylor <cgf@redhat.com>
Throughout, eliminate argument to sig_dispatch_pending. Throughout, eliminate argument to sig_dispatch_pending.

View File

@ -407,17 +407,6 @@ sigfillset (sigset_t *set)
return 0; return 0;
} }
extern "C" int
sigpending (sigset_t *set)
{
unsigned bit;
*set = 0;
for (int sig = 1; sig < NSIG; sig++)
if (*myself->getsigtodo (sig) && myself->getsigmask () & (bit = SIGTOMASK (sig)))
*set |= bit;
return 0;
}
extern "C" int extern "C" int
sigsuspend (const sigset_t *set) sigsuspend (const sigset_t *set)
{ {

View File

@ -48,6 +48,12 @@ details. */
#define NZOMBIES 256 #define NZOMBIES 256
LONG local_sigtodo[TOTSIGS];
inline LONG* getlocal_sigtodo (int sig)
{
return local_sigtodo + __SIGOFFSET + sig;
}
/* /*
* Global variables * Global variables
*/ */
@ -508,9 +514,22 @@ void __stdcall
sig_clear (int sig) sig_clear (int sig)
{ {
(void) InterlockedExchange (myself->getsigtodo (sig), 0L); (void) InterlockedExchange (myself->getsigtodo (sig), 0L);
(void) InterlockedExchange (getlocal_sigtodo (sig), 0L);
return; return;
} }
extern "C" int
sigpending (sigset_t *set)
{
unsigned bit;
*set = 0;
for (int sig = 1; sig < NSIG; sig++)
if ((*getlocal_sigtodo (sig) || *myself->getsigtodo (sig))
&& (myself->getsigmask () & (bit = SIGTOMASK (sig))))
*set |= bit;
return 0;
}
/* Force the wait_sig thread to wake up and scan the sigtodo array. /* Force the wait_sig thread to wake up and scan the sigtodo array.
*/ */
extern "C" int __stdcall extern "C" int __stdcall
@ -659,6 +678,7 @@ sig_send (_pinfo *p, int sig, DWORD ebp, bool exception)
sigproc_printf ("pid %d, signal %d, its_me %d", p->pid, sig, its_me); sigproc_printf ("pid %d, signal %d, its_me %d", p->pid, sig, its_me);
LONG *todo;
if (its_me) if (its_me)
{ {
if (!wait_for_completion) if (!wait_for_completion)
@ -674,8 +694,11 @@ sig_send (_pinfo *p, int sig, DWORD ebp, bool exception)
thiscomplete = sigcomplete_main; thiscomplete = sigcomplete_main;
thisframe.set (mainthread, ebp, exception); thisframe.set (mainthread, ebp, exception);
} }
todo = getlocal_sigtodo (sig);
} }
else if (!(thiscatch = getsem (p, "sigcatch", 0, 0))) else if (thiscatch = getsem (p, "sigcatch", 0, 0))
todo = p->getsigtodo (sig);
else
goto out; // Couldn't get the semaphore. getsem issued goto out; // Couldn't get the semaphore. getsem issued
// an error, if appropriate. // an error, if appropriate.
@ -688,7 +711,7 @@ sig_send (_pinfo *p, int sig, DWORD ebp, bool exception)
/* Increment the sigtodo array to signify which signal to assert. /* Increment the sigtodo array to signify which signal to assert.
*/ */
(void) InterlockedIncrement (p->getsigtodo (sig)); (void) InterlockedIncrement (todo);
/* Notify the process that a signal has arrived. /* Notify the process that a signal has arrived.
*/ */
@ -740,6 +763,7 @@ sig_send (_pinfo *p, int sig, DWORD ebp, bool exception)
SetLastError (0); SetLastError (0);
rc = WaitForSingleObject (thiscomplete, WSSC); rc = WaitForSingleObject (thiscomplete, WSSC);
#if 0 // STILL NEEDED?
/* Check for strangeness due to this thread being redirected by the /* Check for strangeness due to this thread being redirected by the
signal handler. Sometimes a WAIT_TIMEOUT will occur when the signal handler. Sometimes a WAIT_TIMEOUT will occur when the
thread hasn't really timed out. So, check again. thread hasn't really timed out. So, check again.
@ -747,6 +771,7 @@ sig_send (_pinfo *p, int sig, DWORD ebp, bool exception)
if (rc != WAIT_OBJECT_0 && if (rc != WAIT_OBJECT_0 &&
WaitForSingleObject (thiscomplete, 0) == WAIT_OBJECT_0) WaitForSingleObject (thiscomplete, 0) == WAIT_OBJECT_0)
rc = WAIT_OBJECT_0; rc = WAIT_OBJECT_0;
#endif
} }
#if 0 #if 0
@ -775,7 +800,7 @@ out:
void __stdcall void __stdcall
sig_set_pending (int sig) sig_set_pending (int sig)
{ {
(void) InterlockedIncrement (myself->getsigtodo (sig)); (void) InterlockedIncrement (getlocal_sigtodo (sig));
return; return;
} }
@ -1028,6 +1053,7 @@ talktome ()
static DWORD WINAPI static DWORD WINAPI
wait_sig (VOID *self) wait_sig (VOID *self)
{ {
LONG *todos[] = {getlocal_sigtodo (0), myself->getsigtodo (0)};
/* Initialization */ /* Initialization */
(void) SetThreadPriority (GetCurrentThread (), WAIT_SIG_PRIORITY); (void) SetThreadPriority (GetCurrentThread (), WAIT_SIG_PRIORITY);
@ -1111,69 +1137,85 @@ wait_sig (VOID *self)
} }
rc -= WAIT_OBJECT_0; rc -= WAIT_OBJECT_0;
sigproc_printf ("awake"); sigproc_printf ("awake, rc %d", rc);
LONG **start_todo, **end_todo;
switch (rc)
{
case 0:
start_todo = todos;
end_todo = todos;
break;
case 1:
start_todo = todos + 1;
end_todo = todos + 1;
default:
start_todo = todos;
end_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 = -1; pending_signals = -1;
bool saw_pending_signals = false; bool saw_pending_signals = false;
bool saw_sigchld = false; bool saw_sigchld = false;
for (int sig = -__SIGOFFSET; sig < NSIG; sig++) for (LONG **todo = start_todo; todo <= end_todo; todo++)
{ for (int sig = -__SIGOFFSET; sig < NSIG; sig++)
LONG x = InterlockedDecrement (myself->getsigtodo (sig)); {
if (x < 0) LONG x = InterlockedDecrement (*todo + sig);
InterlockedIncrement (myself->getsigtodo (sig)); if (x < 0)
else if (x >= 0) InterlockedIncrement (*todo + sig);
{ else if (x >= 0)
if (x > 0) {
pending_signals = 1; if (x > 0)
pending_signals = 1;
if (sig == SIGCHLD) if (sig == SIGCHLD)
saw_sigchld = true; saw_sigchld = true;
if (sig > 0 && sig != SIGKILL && sig != SIGSTOP && if (sig > 0 && sig != SIGKILL && sig != SIGSTOP &&
(sigismember (&myself->getsigmask (), sig) || (sigismember (&myself->getsigmask (), sig) ||
main_vfork->pid || main_vfork->pid ||
(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 (myself->getsigtodo (sig)); InterlockedIncrement (*todo + sig);
} }
else else
{ {
/* Found a signal to process */ /* Found a signal to process */
sigproc_printf ("processing signal %d", sig); sigproc_printf ("processing signal %d", sig);
switch (sig) switch (sig)
{ {
case __SIGFLUSH: case __SIGFLUSH:
/* just forcing the loop */ /* just forcing the loop */
break; 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))
{ {
sigproc_printf ("couldn't send signal %d", sig); sigproc_printf ("couldn't send signal %d", sig);
low_priority_sleep (SLEEP_0_STAY_LOW); /* Hopefully, other process will be waking up soon. */ low_priority_sleep (SLEEP_0_STAY_LOW); /* Hopefully, other process will be waking up soon. */
saw_pending_signals = true; saw_pending_signals = true;
ReleaseSemaphore (sigcatch_nosync, 1, NULL); ReleaseSemaphore (sigcatch_nosync, 1, NULL);
InterlockedIncrement (myself->getsigtodo (sig)); InterlockedIncrement (*todo + sig);
} }
break; break;
} }
} }
} }
} }
if (saw_pending_signals) if (saw_pending_signals)
pending_signals = 1; pending_signals = 1;