diff options
author | Christopher Faylor <me@cgf.cx> | 2003-08-19 09:47:44 +0400 |
---|---|---|
committer | Christopher Faylor <me@cgf.cx> | 2003-08-19 09:47:44 +0400 |
commit | 06bb489932be04b35133b908d4cd58f161c8d027 (patch) | |
tree | 2ad8586368fcaf8574ce8ead4b3f0f0e28da4d33 /winsup | |
parent | 05cb7b17cb29a2ac4dd3b1f1bc49073ccc81e89b (diff) |
* 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.
Diffstat (limited to 'winsup')
-rw-r--r-- | winsup/cygwin/ChangeLog | 10 | ||||
-rw-r--r-- | winsup/cygwin/signal.cc | 11 | ||||
-rw-r--r-- | winsup/cygwin/sigproc.cc | 162 |
3 files changed, 112 insertions, 71 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 85f9f7043..b586613fa 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,5 +1,15 @@ 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> + Throughout, eliminate argument to sig_dispatch_pending. * exceptions.cc (setup_handler): Move non-interruptible condition handling (back) to wait_sig (as suggested by Pierre Humblet). diff --git a/winsup/cygwin/signal.cc b/winsup/cygwin/signal.cc index 09dcbca51..baad718b9 100644 --- a/winsup/cygwin/signal.cc +++ b/winsup/cygwin/signal.cc @@ -408,17 +408,6 @@ sigfillset (sigset_t *set) } 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 sigsuspend (const sigset_t *set) { return handle_sigsuspend (*set); diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc index ae9c3302a..4ac1d8e4e 100644 --- a/winsup/cygwin/sigproc.cc +++ b/winsup/cygwin/sigproc.cc @@ -48,6 +48,12 @@ details. */ #define NZOMBIES 256 +LONG local_sigtodo[TOTSIGS]; +inline LONG* getlocal_sigtodo (int sig) +{ + return local_sigtodo + __SIGOFFSET + sig; +} + /* * Global variables */ @@ -508,9 +514,22 @@ void __stdcall sig_clear (int sig) { (void) InterlockedExchange (myself->getsigtodo (sig), 0L); + (void) InterlockedExchange (getlocal_sigtodo (sig), 0L); 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. */ 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); + LONG *todo; if (its_me) { if (!wait_for_completion) @@ -674,8 +694,11 @@ sig_send (_pinfo *p, int sig, DWORD ebp, bool exception) thiscomplete = sigcomplete_main; 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 // 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. */ - (void) InterlockedIncrement (p->getsigtodo (sig)); + (void) InterlockedIncrement (todo); /* Notify the process that a signal has arrived. */ @@ -740,6 +763,7 @@ sig_send (_pinfo *p, int sig, DWORD ebp, bool exception) SetLastError (0); rc = WaitForSingleObject (thiscomplete, WSSC); +#if 0 // STILL NEEDED? /* Check for strangeness due to this thread being redirected by the signal handler. Sometimes a WAIT_TIMEOUT will occur when the 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 && WaitForSingleObject (thiscomplete, 0) == WAIT_OBJECT_0) rc = WAIT_OBJECT_0; +#endif } #if 0 @@ -775,7 +800,7 @@ out: void __stdcall sig_set_pending (int sig) { - (void) InterlockedIncrement (myself->getsigtodo (sig)); + (void) InterlockedIncrement (getlocal_sigtodo (sig)); return; } @@ -1028,6 +1053,7 @@ talktome () static DWORD WINAPI wait_sig (VOID *self) { + LONG *todos[] = {getlocal_sigtodo (0), myself->getsigtodo (0)}; /* Initialization */ (void) SetThreadPriority (GetCurrentThread (), WAIT_SIG_PRIORITY); @@ -1111,69 +1137,85 @@ wait_sig (VOID *self) } 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 * array looking for any unprocessed signals. */ pending_signals = -1; bool saw_pending_signals = false; bool saw_sigchld = false; - for (int sig = -__SIGOFFSET; sig < NSIG; sig++) - { - LONG x = InterlockedDecrement (myself->getsigtodo (sig)); - if (x < 0) - InterlockedIncrement (myself->getsigtodo (sig)); - else if (x >= 0) - { - if (x > 0) - pending_signals = 1; - - if (sig == SIGCHLD) - saw_sigchld = true; - - if (sig > 0 && sig != SIGKILL && sig != SIGSTOP && - (sigismember (&myself->getsigmask (), sig) || - main_vfork->pid || - (sig != SIGCONT && ISSTATE (myself, PID_STOPPED)))) - { - sigproc_printf ("signal %d blocked", sig); - InterlockedIncrement (myself->getsigtodo (sig)); - } - else - { - /* Found a signal to process */ - sigproc_printf ("processing signal %d", sig); - switch (sig) - { - case __SIGFLUSH: - /* just forcing the loop */ - break; - - /* Internal signal to turn on stracing. */ - case __SIGSTRACE: - strace.hello (); - break; - - case __SIGCOMMUNE: - talktome (); - break; - - /* A normal UNIX signal */ - default: - sigproc_printf ("Got signal %d", sig); - if (!sig_handle (sig)) - { - sigproc_printf ("couldn't send signal %d", sig); - low_priority_sleep (SLEEP_0_STAY_LOW); /* Hopefully, other process will be waking up soon. */ - saw_pending_signals = true; - ReleaseSemaphore (sigcatch_nosync, 1, NULL); - InterlockedIncrement (myself->getsigtodo (sig)); - } - break; - } - } - } - } + for (LONG **todo = start_todo; todo <= end_todo; todo++) + for (int sig = -__SIGOFFSET; sig < NSIG; sig++) + { + LONG x = InterlockedDecrement (*todo + sig); + if (x < 0) + InterlockedIncrement (*todo + sig); + else if (x >= 0) + { + if (x > 0) + pending_signals = 1; + + if (sig == SIGCHLD) + saw_sigchld = true; + + if (sig > 0 && sig != SIGKILL && sig != SIGSTOP && + (sigismember (&myself->getsigmask (), sig) || + main_vfork->pid || + (sig != SIGCONT && ISSTATE (myself, PID_STOPPED)))) + { + sigproc_printf ("signal %d blocked", sig); + InterlockedIncrement (*todo + sig); + } + else + { + /* Found a signal to process */ + sigproc_printf ("processing signal %d", sig); + switch (sig) + { + case __SIGFLUSH: + /* just forcing the loop */ + break; + + /* Internal signal to turn on stracing. */ + case __SIGSTRACE: + strace.hello (); + break; + + case __SIGCOMMUNE: + talktome (); + break; + + /* A normal UNIX signal */ + default: + sigproc_printf ("Got signal %d", sig); + if (!sig_handle (sig)) + { + sigproc_printf ("couldn't send signal %d", sig); + low_priority_sleep (SLEEP_0_STAY_LOW); /* Hopefully, other process will be waking up soon. */ + saw_pending_signals = true; + ReleaseSemaphore (sigcatch_nosync, 1, NULL); + InterlockedIncrement (*todo + sig); + } + break; + } + } + } + } if (saw_pending_signals) pending_signals = 1; |