Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2003-08-20 09:15:33 +0400
committerChristopher Faylor <me@cgf.cx>2003-08-20 09:15:33 +0400
commit6f6d673cc5aa647a25afb9a5048f5045d7f8a1d8 (patch)
tree45db4e3830111666450a3506e5478b9b1c36eac6 /winsup/cygwin
parent5f31e0f30557788f0f451fd69fbc70a89c271c18 (diff)
* 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.
Diffstat (limited to 'winsup/cygwin')
-rw-r--r--winsup/cygwin/ChangeLog11
-rw-r--r--winsup/cygwin/exceptions.cc9
-rw-r--r--winsup/cygwin/sigproc.cc41
3 files changed, 43 insertions, 18 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 83a902e9c..b4b12a15c 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -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>
* exceptions.cc (pending_signals): Remove unneeded declaration.
diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc
index 537f55e99..034e5605d 100644
--- a/winsup/cygwin/exceptions.cc
+++ b/winsup/cygwin/exceptions.cc
@@ -1220,13 +1220,14 @@ __asm__ volatile ("\n\
.text \n\
_sigreturn: \n\
addl $4,%%esp # Remove argument \n\
- movl %%esp,%%ebp \n\
- addl $36,%%ebp \n\
call _set_process_mask@4 \n\
\n\
cmpl $0,%4 # Did a signal come in? \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\
1: popl %%eax # saved errno \n\
testl %%eax,%%eax # Is it < 0 \n\
@@ -1257,7 +1258,7 @@ _sigdelayed0: \n\
pushl %%ebx \n\
pushl %%eax \n\
pushl %6 # saved errno \n\
- pushl %3 # oldmask \n\
+3: pushl %3 # oldmask \n\
pushl %4 # signal argument \n\
pushl $_sigreturn \n\
\n\
diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc
index f9fed06ec..1b8d96805 100644
--- a/winsup/cygwin/sigproc.cc
+++ b/winsup/cygwin/sigproc.cc
@@ -1116,9 +1116,20 @@ wait_sig (VOID *self)
HANDLE catchem[] = {sigcatch_main, sigcatch_nonmain, sigcatch_nosync};
sigproc_printf ("Ready. dwProcessid %d", myself->dwProcessId);
+ DWORD rc = RC_NOSYNC;
+ bool flush = false;
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);
/* 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
* array looking for any unprocessed signals.
*/
- pending_signals = false;
+ pending_signals = 0;
bool saw_failed_interrupt = false;
for (LONG **todo = todos; todo <= end_todo; todo++)
for (int sig = -__SIGOFFSET; sig < NSIG; sig++)
@@ -1178,8 +1189,8 @@ wait_sig (VOID *self)
(sig != SIGCONT && ISSTATE (myself, PID_STOPPED))))
{
sigproc_printf ("signal %d blocked", sig);
- InterlockedIncrement (*todo + sig);
pending_signals = true; // FIXME: This will cause unnecessary sig_dispatch_pending spins
+ InterlockedIncrement (myself->getsigtodo (sig));
}
else
{
@@ -1188,7 +1199,12 @@ wait_sig (VOID *self)
switch (sig)
{
case __SIGFLUSH:
- /* just forcing the loop */
+ if (rc == RC_MAIN)
+ {
+ flush = true;
+ ReleaseSemaphore (sigcatch_nosync, 1, NULL);
+ goto out1;
+ }
break;
/* Internal signal to turn on stracing. */
@@ -1206,8 +1222,9 @@ wait_sig (VOID *self)
if (!sig_handle (sig))
{
sigproc_printf ("couldn't send signal %d", sig);
- pending_signals = saw_failed_interrupt = true;
ReleaseSemaphore (sigcatch_nosync, 1, NULL);
+ saw_failed_interrupt = true;
+ pending_signals = true;
InterlockedIncrement (myself->getsigtodo (sig));
}
}
@@ -1222,19 +1239,15 @@ wait_sig (VOID *self)
out:
/* Signal completion of signal handling depending on which semaphore
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);
sigproc_printf ("set main thread completion event");
- break;
- case RC_NONMAIN:
- ReleaseSemaphore (sigcomplete_nonmain, 1, NULL);
- break;
- default:
- /* Signal from another process. No need to synchronize. */
- break;
+ flush = false;
}
+ out1:
if (saw_failed_interrupt)
low_priority_sleep (SLEEP_0_STAY_LOW); /* Hopefully, other thread will be waking up soon. */
sigproc_printf ("looping");