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 + + * sigproc.cc (wait_sig): Ensure that myself->getsigtodo array is + flushed on a __SIGFLUSH. + +2003-08-20 Pierre Humblet + Christopher Faylor + + * exceptions.cc (_sigreturn): Handle nested signals without growing the + stack. + 2003-08-19 Christopher Faylor * 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");